2011-02-23 63 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折磨測試,因爲如果這是要與其他系統交互時,您應該使用它們,因爲它會告訴你它爲什麼這麼很難得到正確的。