Разобрать SIP-пакет в C - PullRequest
       43

Разобрать SIP-пакет в C

5 голосов
/ 23 февраля 2011

Я пытаюсь проанализировать SIP-пакет и получить из него некоторую информацию.Чтобы быть более конкретным, пакет выглядит следующим образом

REGISTER sip:open-ims.test SIP/2.0
Via: SIP/2.0/UDP 192.168.1.64:5060;rport;branch=z9hG4bK1489975971
From: <sip:alice@open-ims.test>;tag=1627897650
To: <sip:alice@open-ims.test>
Call-ID: 1097412971
CSeq: 1 REGISTER
Contact: <sip:alice@192.168.1.64:5060;line=5fc3b39f127158d>;+sip.instance="<urn:uuid:46f525fe-3f60-11e0-bec1-d965d1488cfa>"
Authorization: Digest username="alice@open-ims.test", 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

Теперь из этого пакета мне нужно извлечь следующее:

  • Значение после «From:» (в этомcase <sip:alice@open-ims.test>)
  • Значение после «Contact:» (в данном случае <sip:alice@192.168.1.64)
  • Значение после «username» (в данном случае alice@open-ims.test)

Мой код до сих пор такой:

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 помочь мне с моей проблемой?

Заранее спасибо

Ответы [ 6 ]

4 голосов
/ 24 февраля 2011

Я думаю, что-то подобное может работать

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); 
3 голосов
/ 23 февраля 2011

Повторяя комментарий, предоставленный Rup , я бы тоже порекомендовал использовать библиотеку, так как все тяжелые работы были сделаны для вас, и вы можете потратить больше времени на то, чтобы сосредоточиться на том, что вы пытаясь выполнить с разобранной информацией.

Библиотека GNU oSIP может быть хорошим местом для начала.

Из электронной документации :

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

Начальная функция реализована в osip - это SIP-парсер. Нет много сказать об этом: он способен парсинг и переформатирование SIP-запросов и ответы.

Детали инструментов разбора доступны перечислены ниже:

1 SIP запрос / ответ
2 SIP uri
3 конкретных заголовка
4 Via
5 CSeq
6 Call-ID
7 До, От, Маршрут, Запись-Маршрут ...
8 Связанные с аутентификацией заголовки
9 Заголовки, связанные с контентом
10 Примите связанные заголовки
11 ...
12 Общий заголовок
13 Анализатор вложений (должен поддерживать mime)
14 SDP-анализатор

1 голос
/ 01 января 2012

Используйте парсер, если возможно. Синтаксис SIP имеет настолько сложную грамматику, что многие парсеры ABNF не могут обрабатывать RFC 3261 ABNF. Если вы все еще думаете, что писать его самостоятельно - это хорошая идея, вам следует ознакомиться с RFC 4475, тестами SIP на пытки, потому что вы должны использовать их, если это будет взаимодействовать с другими системами, и потому что это покажет вам, почему это так трудно получить право.

1 голос
/ 23 февраля 2011

Прочитайте каждую строку и найдите каждую из ваших подстрок («От:», «Контакт:», «Имя пользователя»), используя strstr().

Когда вы встретите строку, содержащую одно из ваших ключевых слов, разделите ее на strtok() и извлеките нужную часть.

Я не знаю, нужна ли вам полноценная SIP-библиотека для извлечения этих трех вещей, но если вам может понадобиться проанализировать больше пакетов в будущем, это может быть неплохой идеей.

0 голосов
/ 23 февраля 2011

strtok не обязательно каждый раз использовать один и тот же набор разделителей. Вы можете использовать двоеточие, когда ожидаете метку поля, и не указывать его, когда ожидаете правую часть.

0 голосов
/ 23 февраля 2011

Для использования strtok с "<>;" я бы ожидал, что ваш пакет будет разбит на что-то вроде следующего (новые строки удалены)

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

rport

branch=z9hG4bK1489975971From:

sip:alice@open-ims.test 

Ни один из них не будет соответствовать

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

Вам нужно либо изменить свой синтаксический анализатор, либо выполнить поиск по строке, возвращенной strtok для "From:".

...