2011-02-23 30 views
5

Estoy tratando de analizar un paquete SIP y obtener algo de información de él. Para ser más específicos, el paquete se parece a estopaquete Parse SIP en 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 

Ahora, a partir de ese paquete que necesito para extraer lo siguiente:

Mi código hasta ahora es este

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); 
     } 
    } 

Dónde carga útil contiene el paquete como se describió anteriormente.

Sin embargo, cuando ejecuto mi programa, se producirá un error de segmentación. Lo extraño es que si uso en strtok los caracteres "<> ;:" y en strcmp el valor "sip", el mensaje se analizará correctamente y mantendrá el valor guardado. Pero necesito analizar los tres valores superiores.

¿Una biblioteca de sorbos podría ayudarme más con mi problema?

Gracias de antemano

+3

En general, cuando necesita analizar o construir texto estructurado como este, es una buena idea usar una biblioteca porque siempre hay casos de esquina en la codificación que tendría que manejar, y alguien más ha hecho ese trabajo por usted . Asumiendo, es decir, puede encontrar algo simple y lo suficientemente liviano para vincularse con lo que está haciendo. – Rup

Respuesta

4

creo que algo como esto podría funcionar

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

Para uso con strtok "<>;", yo esperaría que su paquete se divida en algo así como las nuevas líneas siguientes (eliminados)

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

rport 

branch=z9hG4bK1489975971From: 

sip:[email protected] 

Ninguna de estas partido

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

Debería modificar su analizador o buscar a través de la cadena devuelta por strtok para "De:".

3

Haciendo eco del comentario proporcionado por Rup, yo también recomendaría usar una biblioteca ya que todo el trabajo pesado se ha realizado para usted y puede dedicar más tiempo a concentrarse en lo que está intentando lograr con la información analizada.

El GNU oSIP library puede ser un buen lugar para comenzar.

Desde el online documentation:

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

La característica inicial implementado en Osip es un analizador SIP. No hay mucho que decir sobre : es capaz de analizar y reformar solicitudes SIP y respuestas.

Los detalles de las herramientas de análisis sintáctico disponibles se enumeran a continuación:

1 petición SIP/respuesta
2 de URI SIP
3 cabeceras específicas
4 Via
5 CSeq
6 Call-ID
7 a, desde, ruta, ruta de registro ...
8 encabezados relacionados con la autenticación
9 encabezados relacionados con el contenido
10 Aceptar encabezados relacionados
11 ...
12 de cabecera genérica
13 Documento anexo analizador (debe apoyar el mimo)
14 SDP analizador

1

Lea cada línea y la búsqueda de cada una de las subseries ('De:', 'Contacto:', 'nombre de usuario') usando strstr().

Cuando encuentre una línea que contenga una de sus palabras clave, divídala con strtok() y extraiga la pieza que necesita en consecuencia.

No sé si necesitas una lib de SIP completa para extraer estas tres cosas, pero si es posible que necesites analizar más paquetes en el futuro, puede que no sea una mala idea.

+0

Gracias @ wtfm8. Pero el problema es que no puedo leer cada línea porque es una gran cadena. Estoy de acuerdo en que agregar un sip lib no sería lo mejor para una tarea tan ligera. – kamperone

0

strtok no tiene que usar el mismo conjunto de delimitadores cada vez. Puede usar dos puntos cuando espera una etiqueta de campo y dejarla apagada cuando espera el lado derecho.

1

Utilizar un analizador si le sea posible. La sintaxis SIP tiene una gramática tan compleja que muchos analizadores ABNF no pueden manejar el RFC 3261 ABNF. Si todavía estás pensando en escribirlo tú mismo es una buena idea, debes familiarizarte con RFC 4475, las pruebas de tortura de SIP porque debes usarlas si esto va a interactuar con otros sistemas, y porque te mostrará por qué es tan difícil de hacer bien