`
magixyu
  • 浏览: 79755 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

IMS测试中ENUM模拟软件

    博客分类:
  • Perl
阅读更多
ENUM 遵循 DNS 协议。ENUM是IETF的电话号码映射工作组定义的一个协议——RFC2916,RFC2916的题目为“E.164号码和域名系统”。它定义了将E.164号码转换为域名形式放在DNS服务器数据库中的方法,每个由E.164号码转化而成的域名可以对应一系列的统一资源辨识URI,从而使国际统一的E.164电话号码成为可以在互联网中使用的网络地址资源。

根据ENUM格式的定义,将电话号码变成了DNS中的域名形式。每个E.164号码形成的域名可以对应多条网络资源记录,称为统一资源标志URI,它是采用另一个IETF建议RFC2915定义的格式,称为“名称权威指针”(NAPTR)。

在IMS测试中,需要用到ENUM服务器,一般用bind来替代,需要配置各种号码。下面是一个模拟器,可以很方便的完成一些简单功能,而避开用真正的ENUM

#!/usr/bin/perl

use strict;
use IO::Socket::INET;
use POSIX 'WNOHANG';
use Getopt::Long;

use constant PORT   => 53;
use constant SUFFIX => '.e164.arpa';
use constant REALM  => 'qd.lucentlab.com';
use constant USAGE  => <<USE;

    This is a ENUM simulator, only supports 2 response messages now
    1. Query success with one record
    2. Query failed with "No such Name"
    Usage:
        $0 --port port --prefix prefix --suffix suffix --realm realm[--debug]

    port     Default port is 53
    prefix   Reponse message type 1 for DNs with this prefix
             Other DN will response with type 2
    suffix   The suffix of query message, Default is '.e164.arpa'
    realm    The SIPURI domain/realm, default is 'qd.lucent.com'
    debug    Show more debug message
    
    Example:
        $0 --prefix 1543 --debug
        $0 --prefix 1543 --suffix '.e164.cn'
        
    Contact: Tristan Yu (tyu@)
        
USE

my ($port, $prefix, $suffix, $realm, $debug, $help);
my $file;

err_exit(USAGE, 255) unless GetOptions( 
            'port=s'   => \$port, 'prefix=s' => \$prefix, 'suffix=s' => \$suffix,
            'realm=s'  => \$realm, 'debug'    => \$debug, 'help'     => \$help, 
            'file=s'   => \$file      );

if ($help) {
    print USAGE;
    exit 0;
}

if ( $file ) {
    eval(require $file) || die "$file format is wrong, check the program help";
}
$port   ||= PORT;
$suffix ||= SUFFIX;
$realm  ||= REALM;

err_exit("\tPort should be digits", 1) unless $port =~ /^\d+$/;
err_exit("\tMust have a prefix", 1) if ($prefix eq "");

if ($debug) {
    print "Configuration data:\n";
    print "Port: $port, Prefix: $prefix, Suffix: $suffix, Realm: $realm, Debug: $debug\n";
}

# MAIN STARTS HERE #

$| = 1;
$/ = '\012\015';

my $ok_prefix = $prefix;
my $count  = 0;

$SIG{INT}  = sub { print "Totally processed $count ENUM queries\n"; exit 0 };
$SIG{ALRM} = sub { print "X\n";};
$SIG{CHLD} = sub { while ( waitpid(-1, WNOHANG)>0 ) {}};

#Do not change any value below in the while loop
#Variables for ENUM message header

my $corrid = 1; # 16-bit field, used to correlate queries and responses. 
my $qr     = 1; # 1-bit field, that identifies the message as a response. 
my $opcode = 0; # 4bits field to indicate the operation. 0 means QUERY, Standard query
my $aa     = 1; # 1-bit field, Authoritative Answer, 1 means "Not authoritative."
my $tc     = 0; # 1-bit field, Truncation, 0 means Not truncated.
my $rd     = 1; # 1-bit field, Recursion Desired
my $ra     = 1; # 1-bit field, Recursion Available
my $ad     = 0; # 1-bit field, Authenticated data 
my $cd     = 0;
my $z      = 0; # Must be 0 for NOW (RFC1035)
my $rcode  = 0; # 4-bit field, Response Code, is set by the NS to identify the status of the query

# 16-bit field that defines the number of entries in the question section
my $ques = 1; 
# 16-bit field that defines the number of resource records in the answer section. 
my $answ = 1; 
# 16-bit field that defines the number of name server resource records in the authority section
my $auth = 1; 
# 16-bit field that defines the number of resource records in the additional records section.
my $addt = 0; 

my $byte1  = (($qr?0x80:0)|($opcode << 3)|($aa?0x04:0)|($tc?0x02:0)|($rd?0x01:0));
# Response with resualt
my $byte2  = (($ra?0x80:0)|($ad?0x20:0)|($cd?0x10:0)|($rcode));
# Response with "No Such Name"
my $byte2_f  = (($ra?0x80:0)|($ad?0x20:0)|($cd?0x10:0)|(0x3));

my $header_fix_ok = pack("C2 n4", $byte1, $byte2, $ques, $answ, $auth, $addt);
my $header_fix_nf = pack("C2 n4", $byte1, $byte2_f, $ques, 0, $auth, $addt);

#Variables for ENUM message answer
my $dname = 0xC000; #Indicator this is a pointer
my $type  = 35; # NAPTR, Naming Authority Pointer.
my $class = 1;  # IN, Internet.
my $ttl   = 0;
my $order = 100;
my $pref  = 100;
# "u" flag means that the next step is not a DNS lookup but that the output 
# of the Regexp field is an URI that adheres to the 'absoluteURI' product
my $flag  = "u"; 
my $serv  = 'E2U+sip';

#Variables for ENUM message authorize
my $aname = 0xC000; #Indicator this is a pointer
my $atype = 2;      #A NS record for the domain name
my $attl  = 3600 * 24; # 24 hours
my $ns    = dns_normalize($realm);

my $auth_pre_data = pack("n2 L n", $atype, $class, $attl, length($ns)) . $ns;

use constant HEADER_LENGTH   => length pack 'n C2 n4', (0)x7;
use constant QUESTION_LENGTH => length pack 'n2', (0)x2;

# Setup Socket
my $enum_server = IO::Socket::INET->new(
        #LocalAddr => '135.252.29.135',
        LocalPort => $port,
        Proto     => 'udp',
        ) or die "Could not open UPD port 53 $!";
binmode $enum_server;

print "UDP ENUM server is running ...\n";
while (1) {
    my $data_buf;
    next unless my $peer_addr = $enum_server->recv($data_buf, 1024);
    defined ( my $enum_s = fork())
        or do { print "\nFork an ENUM processor failed\n", next;};
        
    if ($enum_s == 0) {
        if ($debug) {
            my ($portno, $ipaddr) = sockaddr_in($peer_addr);
            print "Host " . inet_ntoa($ipaddr) . ":" . $portno ;
        }
        alarm(1);
        my $corrid = unpack('n', $data_buf);
        
        my ($qname, $offset) = parse_question(\$data_buf, HEADER_LENGTH);
        print "\nQuery for $qname [$corrid]\n" if $debug;
        #Generate query with query name
        my $query_data = dns_normalize($qname) . pack("n2", $type, $class);
        
        my $e164_num   = to_e164($qname);
        print "E164 is $e164_num\n" if $debug;
        my $dname_ptr  = HEADER_LENGTH;
        my $aname_ptr  = $dname_ptr + 2 * length($e164_num);
        
        my $header_data = "";
        my $answer_data = "";
        
        if ($e164_num =~ /^$ok_prefix/) {
            print "Query successfully response \n" if $debug;
            #Generate header with the corrilation identity
            $header_data = pack("n", $corrid) . $header_fix_ok;
            
            #Generate the DNS regular expression
            my $regex = '!^.*$!sip:+' . $e164_num . '@' . $realm . '!';
            my $relen = length($regex); # The length of the regex
            my $rdata = pack("n2 C a C a7 C a$relen C",
                            $order, $pref, length($flag), $flag, length($serv), $serv, $relen, $regex, 0) ;
            $answer_data = pack("n", ($dname|$dname_ptr))
                        . pack("n2 L n", $type, $class, $ttl, length($rdata)) . $rdata;
        } else {
            print "Query No such Name response \n" if $debug;
            #Response with No such Name
            $answer_data = ""; 
            $header_data = pack("n", $corrid) . $header_fix_nf;
        }

        my $auth_data = pack("n", ($aname|$aname_ptr)) . $auth_pre_data;
        
        $enum_server->send($header_data.$query_data.$answer_data.$auth_data);
        
        alarm(0);

        print "Done for $qname\n" if $debug;
        print "." if not $debug;
        exit 0;
    }
    
    $count++;
    print "\b" x 80 if ( not $debug and ($count % 80 == 0));
}

sub dns_normalize {
    my ($i) = @_;
    my @ele = split /\./, $i;
    my $message = "";
    foreach my $e (@ele) {
        $message .= pack("C a*", length($e), $e);
    }
    $message .= pack("C", 0);
    return $message;
}

# Function to parse e164 number

sub to_e164 {
    my ($var) = @_;
    $var =~ s/$suffix//g;
    $var =~ s/\.$//o;
    my $e164_num = join("", reverse(split /\./, $var));
    return $e164_num;
}

# Function to parse the incoming message

sub parse_question {
    my ($packet, $offset) = @_;
    my $packetlen = length($$packet);
    my $name = '';

    while ( $offset < $packetlen ) {
        unless ( my $length = unpack("\@$offset C", $$packet) ) {
            $name =~ s/\.$//o;
            return ($name, ++$offset);
        } else {
            my $element = substr($$packet, ++$offset, $length);
            $name .= $element.'.';
            $offset += $length;
        }
    }
    return undef;
}

sub err_exit {
    my ($err_msg ,$err_no) = @_;
    print $err_msg, "\n";
    exit $err_no;
}

分享到:
评论
3 楼 magixyu 2013-11-14  
对影三人 写道
博主 您好
    我,试着将代码编译了一下,perlapp程序报错:can,t find string terminator "use"anywhere before EOF at ENUM.pl line 11.
'ENUM.pl'had compilation errors
期待您的指教


去掉USE前面的空格
2 楼 对影三人 2013-05-12  
博主 您好
    我,试着将代码编译了一下,perlapp程序报错:can,t find string terminator "use"anywhere before EOF at ENUM.pl line 11.
'ENUM.pl'had compilation errors
期待您的指教
1 楼 对影三人 2013-05-10  
博主您好
     由于毕设课题设计到ENUM,欲借ENUM模拟器一用,只是本人对代码实在头痛,不知能否给予打包好的软件一用?

相关推荐

    中国移动IMS业务测试要求

    兼容性测试涉及不同终端类型、操作系统、浏览器等,确保IMS接入设备能在各种环境中正常工作。 10. **网络管理与计费** 测试设备是否支持网络管理和计费功能,如信令跟踪、计费信息收集、性能监控等。 11. **福建...

    中国联通IMS测试规范

    联通IMS技术试验测试规范 第十二分册:IMS与WCDMA可视电话互通》.doc

    中移动CM-IMS多媒体电话及补充业务测试规范.pdf

    本内容涉及中国移动CM-IMS多媒体电话及其补充业务的测试规范。CM-IMS指的是“中国移动基于IP多媒体子系统(IP Multimedia Subsystem,IMS)”,是一个基于3GPP标准的多媒体通信架构,它允许运营商提供包括语音、视频...

    中国移动CM-IMS试点测试规范_Gm接口

    知识点:IMS系统中的术语、定义和缩略语是IMS试点测试的基础,了解这些概念是IMS试点测试的先决条件。 4. 设备环境及说明:该规范文件对IMS系统的设备环境和说明进行了详细的介绍,旨在确保IMS系统的设备环境和说明...

    IMS客户端技术标准及软件特性分析

    IMS客户端技术标准及软件特性分析 IMS(IP多媒体子系统)是基于SIP(会话初始化协议)构建的系统,旨在提供一个标准化的框架,支持多媒体服务。IETF(互联网工程任务组)、3GPP(第三代合作伙伴计划)、OMA(开放...

    VoIP NGN IMS 3G 标准 规范 测试技术 资料集合

    资料集合中的文档"VoIP NGN IMS 3G 标准 规范 测试技术 资料集合.doc"可能会包含以下内容: 1. VoIP技术的基本原理和协议栈,如SIP(Session Initiation Protocol)、RTP(Real-time Transport Protocol)和UDP/TCP...

    DNS,ENUM原理介绍

    简单介绍了DNS和ENUM的原理及在IMS网络中的使用

    中国移动IMS设备测试规范(V2[1].0)

    本测试规范用于对IMS设备进行测试,包括设备功能、接口规程、网络管理、操作维护等方面的要求,目的是保证包括CSCF、BGCF、MGCF/IM MGW、MRFC、MRFP、SLF、HSS、AS、CCF、IM-SSF在内的各IMS设备符合标准,为设备引进...

    IMS注册及CALL SIP信令分析

    同时,CALL SIP信令是IMS系统中的一种重要信令,用于控制IMS呼叫的建立、维持和释放。 一、IMS注册 IMS注册是IMS系统中的一种基本步骤,涉及到用户设备的注册、认证和授权。注册过程包括以下几个步骤: 1. DS通知...

    IMS200客户端软件(中文版)

    IMS200客户端软件(中文版),用于海康威视录像机的视频控制、采集及处理。功能强大,操作简单

    自己整理的IMS中文资料

    IMS(IP Multimedia Subsystem,IP多媒体子系统)是电信领域中的一个关键概念,它是一种基于IP网络的架构,旨在提供融合的通信服务,包括语音、数据、视频等多种媒体类型。IMS系统的设计目标是使运营商能够在其现有...

    中国联通IMS技术试验测试规范 第五分册:Mw接口

    IMS 技术试验测试规范第五分册:Mw 接口 IMS(IP Multimedia Subsystem)是一种基于IP的多媒体子系统,旨在提供多种多媒体应用服务。中国联通作为一家大型电信运营商,需要制定相关的试验测试规范来确保IMS技术的...

    ims_wiki ims综述

    3. **水平控制层**:IMS架构中的控制层是横向的,它将接入网络与服务层隔离,使得服务层不必关心具体的接入技术。虽然理论上这可以降低复杂性和成本,但在实际部署过程中并不总是如此简单。 #### 四、IMS面临的挑战...

    uctimsclient1.0.14.tar.gz

    在本文中,我们将深入探讨UCTIMS客户端在IMS系统中的作用、1.0.14版本可能包含的改进以及如何进行测试。 首先,IMS是一种基于IP的架构,旨在为固定和移动用户提供多媒体通信服务,如语音、视频通话、即时消息等。...

    uctimsclient

    2. **OPEN IMS CORE**:这是一个开源项目,为开发和测试IMS网络提供了软件平台。它包含了IMS体系结构中的关键组件,如归属用户服务器(HSS)、会话初始化协议(SIP)服务器、认证授权服务器等,为开发者和研究者提供...

    中国移动CM-IMS试点测试规范_IPPBX设备分册v1.6.0_1211.pdf

    - 术语IPPBX、IMS、IP、SIP、H.263、H.264等标识了测试规范中所涉及的技术和协议。 - VLAN、SBC(会话边界控制器)、CENTREX、MRBT等词汇表明了测试涉及的网络组件和特定功能。 - RFC3261、3GPP、ITU-T等代表了文档...

Global site tag (gtag.js) - Google Analytics