2011-02-23 65 views
5

我想解析一个SIP数据包并从中获取一些信息。具体而言,该数据包看起来像这样解析SIP数据包C

REGISTER sip:open-ims.test SIP/2.0 
Via: SIP/2.0/UDP 192.168.1.64:5060;rport;branch=z9hG4bK1489975971 
From: <sip:[email protected]>;tag=1627897650 
To: <sip:[email protected]> 
Call-ID: 1097412971 
CSeq: 1 REGISTER 
Contact: <sip:[email protected]:5060;line=5fc3b39f127158d>;+sip.instance="<urn:uuid:46f525fe-3f60-11e0-bec1-d965d1488cfa>" 
Authorization: Digest username="[email protected]", realm="open-ims.test", nonce=" ", uri="sip:open-ims.test", response=" " 
Max-Forwards: 70 
User-Agent: UCT IMS Client 
Expires: 600000 
Supported: path 
Supported: gruu 
Content-Length: 0 

现在,从包我需要提取以下内容:

“联系”

到目前为止我的代码是这个

char * tch; 
     char * saved;      
     tch = strtok (payload,"<>;"); 
     while (tch != NULL) 
     { 
     int savenext = 0;    
     if (!strcmp(tch, "From: "))  
     {        
      savenext = 1;     
     }        

     tch = strtok (NULL, "<>;"); 
     if (savenext == 1)    
     {        
      saved = tch;     
     }        
     } 
     printf ("### SIP Contact: %s ###\n", saved); 
     } 
    } 

凡有效载荷包含与上述数据包。

但是,当我运行我的程序时,将导致分段错误。奇怪的是,如果我在strtok中使用字符“<> ;:”,并且在strcmp中的值为“sip”,则消息将成功解析,并且会保存保存的值。但是我需要解析所有三个上面的值。

sip图书馆会帮助我解决我的问题吗?

在此先感谢

+3

一般而言,当您需要解析或构建像这样的结构化文本时,使用库是一个不错的主意,因为编码中总是存在需要处理的角落案例 - 而其他人已经为您完成了这项工作。假设,就是说,你可以找到足够简单和轻量级的东西来链接你正在做的事情。 – Rup 2011-02-23 15:46:33

回答

4

我觉得这样的事情可以工作

char * tch; 
     char * saved;      
     tch = strtok (payload,"<>;\n\""); 
     while (tch != NULL) 
     { 
      int savenext = 0;    
      if (strncmp(tch, "From",4)==0) 
      {         
      tch = strtok (NULL, "<>;\n\""); 
      saved = tch;     
      printf (" SIP From: %s \n", saved); 
      } 
      else if (strncmp(tch, "Contact",7)==0) 
      {         
      tch = strtok (NULL, "<>;\n\""); 
      saved = tch;     
      printf (" SIP Cont: %s \n", saved); 
      } 
      if (strncmp(tch, "Authorization",13)==0) 
      {          
      tch = strtok (NULL, "<>;\n\""); 
      saved = tch;     
      printf (" SIP User: %s \n", saved); 
0

对于“<>;” strtok的使用,我希望你的包拆分成类似如下(换行删除)

REGISTER sip:open-ims.test SIP/2.0Via: SIP/2.0/UDP 192.168.1.64:5060 

rport 

branch=z9hG4bK1489975971From: 

sip:[email protected] 

这些都不意志比赛

if (!strcmp(tch, "From: "))  

你会要么需要修改解析器或通过的strtok为返回的字符串搜索“从”。

3

回应​​提供的意见,我也会建议使用一个库,因为所有繁重的工作都是为您完成的,您可以花更多的时间专注于您正在尝试使用解析后的信息完成的任务。

GNU oSIP library可能是一个很好的开始。

online documentation

SIP parser: 
    ========== 

在 约瑟夫实现的初始特征是SIP解析器。关于它没有太多的说法:它能够解析和重新格式化SIP请求 和答案。

的解析工具的细节 可用列举如下:

1 SIP请求/应答
2 SIP URI
3特定的头
4通过
5的Cseq
6的Call-ID
7,发件人,路由,记录路由...
8认证相关的头
9内容相关的头
10接受相关的头
11 ...
12通用头
13 Attachement解析器(应支持MIME)
14 SDP解析器

1

阅读每一条线,然后搜索每个子串( 'From:','Contact:','username')使用strstr()

当你遇到一个包含关键字的一个线,与strtok()拆分,并提取您需要相应的作品。

我不知道,如果你需要一个全面的SIP lib中提取这三样东西,但如果你可能需要更多的分析在未来的分组中,它可能不是一个坏主意。

+0

Thanks @ wtfm8。但事情是我无法读取每一行,因为它都是一个大字符串。我同意添加一个sip库对于这样一个轻量级的任务并不是最好的。 – kamperone 2011-02-23 17:39:35

0

strtok不必每次都使用同一组的分隔符。当你期待一个字段标签时,你可以使用冒号,当你期待右手边时,可以不使用冒号。

1

如果你所能使用的解析器。 SIP语法的语法非常复杂,以至于许多ABNF分析器无法处理RFC 3261 ABNF。如果你还在想自己写的这是一个好主意,你应该熟悉RFC 4475中,SIP折磨测试,因为如果这是要与其他系统交互时,您应该使用它们,因为它会告诉你它为什么这么很难得到正确的。