Reputation: 18127
A SIP (Session Initiation Protocol) packet's format is something along the lines of:
INVITE sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.100.86:5060;rport;branch=z9hG4bKPj3f79189a-581d-4f58-a4dd-bc64e050421c
Max-Forwards: 70
From: <sip:192.168.100.86>;tag=60f4c35a-6cdb-4b19-b580-f3d3ad5c1abf
To: <sip:[email protected]>
Contact: <sip:192.168.101.86:5060;ob>
Call-ID: 247ee45e-957a-481a-b97b-82f2429a999d
CSeq: 17491 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Session-Expires: 1800
Min-SE: 90
User-Agent: PJSUA v2.3 Linux-3.2.0.4/x86_64/glibc-2.13
Content-Type: application/sdp
Content-Length: 479
I need to decode this packet and extract some of its fields, like From
, To
, Call-ID
, etc. The packet is in ASCII format and each filed is encoded in a separate line. Also, the order of fields is not determined and they may be in any order. What's the best method to extract the value of the desired fields from such packet? I need to be able to set and get each field separately. The simplest idea that comes to my mind is to read the packet line by line and check if each line starts with any of my desired values. I really appreciate any advice on showing me an efficient way to do this.
Upvotes: 2
Views: 1988
Reputation: 670
One of the better approaches has been to use the Lex / Yaml. No matter how much similarities there are in each of the SIP headers, each one has a specific pattern. And one of the ways to capture the parsing logic should be break down into the most common base types defined in the ABNF for the SIP. Then build on them for each header and gradually build it cover more fancier headers that keeps coming out every few days from the IETF.
I have found the approach to be really extendable and SIP stacks do use the similar approach for the parsing. BTW i would second Adrians approach if you are only intrested in a few common headers.
Upvotes: 1
Reputation: 2182
Personally, I'd do this by hand. It's utterly deterministic. There will never be a colon in the field name, so you just look for it on each line, chop, and populate a map. I'd try not to code for specific fields like "Via". Just write something generic that could also read email headers without code changes. You could try to find a library but it would bring baggage you don't need. It's small enough to write by hand. Watch out for security issues like interminable lines.
Upvotes: 3