FreeCalypso > hg > sipout-test-utils
comparison libsip/primary_parse.c @ 0:35c0d9f03c0a
beginning with sipout-test-voice,
a copy of sip-manual-out from themwi-system-sw
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 03 Mar 2024 23:20:19 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:35c0d9f03c0a |
---|---|
1 /* | |
2 * In this module we are going to implement the first stage of | |
3 * parsing for incoming SIP UDP packets, using struct sip_pkt_rx | |
4 * defined in parse.h. | |
5 */ | |
6 | |
7 #include <ctype.h> | |
8 #include <string.h> | |
9 #include <strings.h> | |
10 #include <stdlib.h> | |
11 #include "parse.h" | |
12 | |
13 static | |
14 find_crlf(ptr, msg_end, endp, nextp) | |
15 char *ptr, *msg_end, **endp, **nextp; | |
16 { | |
17 for (;;) { | |
18 if (ptr >= msg_end) | |
19 return(0); | |
20 switch (*ptr) { | |
21 case '\0': | |
22 return(0); | |
23 case '\n': | |
24 *endp = ptr; | |
25 *nextp = ptr + 1; | |
26 return(1); | |
27 case '\r': | |
28 *endp = ptr; | |
29 ptr++; | |
30 if (ptr >= msg_end) | |
31 return(0); | |
32 if (*ptr != '\n') | |
33 return(0); | |
34 *nextp = ptr + 1; | |
35 return(1); | |
36 } | |
37 ptr++; | |
38 } | |
39 } | |
40 | |
41 static | |
42 try_status_line(msg) | |
43 struct sip_pkt_rx *msg; | |
44 { | |
45 if (strncasecmp(msg->pkt_buffer, "SIP/2.0 ", 8)) | |
46 return(0); | |
47 if (!isdigit(msg->pkt_buffer[8])) | |
48 return(0); | |
49 if (!isdigit(msg->pkt_buffer[9])) | |
50 return(0); | |
51 if (!isdigit(msg->pkt_buffer[10])) | |
52 return(0); | |
53 if (msg->pkt_buffer[11] != ' ') | |
54 return(0); | |
55 msg->status_code = atoi(msg->pkt_buffer + 8); | |
56 msg->status_str = msg->pkt_buffer + 8; | |
57 return(1); | |
58 } | |
59 | |
60 static | |
61 try_request_line(msg) | |
62 struct sip_pkt_rx *msg; | |
63 { | |
64 char *cp; | |
65 | |
66 cp = msg->pkt_buffer; | |
67 if (!isupper(*cp)) | |
68 return(0); | |
69 while (isalnum(*cp)) | |
70 cp++; | |
71 if (*cp != ' ') | |
72 return(0); | |
73 msg->req_method = msg->pkt_buffer; | |
74 *cp++ = '\0'; | |
75 msg->req_uri = cp; | |
76 while (*cp && !isspace(*cp)) | |
77 cp++; | |
78 if (*cp != ' ') | |
79 return(0); | |
80 *cp++ = '\0'; | |
81 if (strcasecmp(cp, "SIP/2.0")) | |
82 return(0); | |
83 else | |
84 return(1); | |
85 } | |
86 | |
87 static void | |
88 trim_trailing_spaces(sp) | |
89 char *sp; | |
90 { | |
91 char *ep; | |
92 | |
93 ep = index(sp, '\0'); | |
94 while (ep > sp && isspace(ep[-1])) | |
95 ep--; | |
96 *ep = '\0'; | |
97 } | |
98 | |
99 parse_incoming_sip_msg(msg) | |
100 struct sip_pkt_rx *msg; | |
101 { | |
102 char *msg_end = msg->pkt_buffer + msg->pkt_length; | |
103 char *cp, *endp, *nextp, *sp; | |
104 unsigned hdr_cnt; | |
105 int rc; | |
106 | |
107 /* begin by isolating the Request-Line or Status-Line */ | |
108 rc = find_crlf(msg->pkt_buffer, msg_end, &endp, &nextp); | |
109 if (!rc) | |
110 return(-1); | |
111 *endp = '\0'; | |
112 if (try_status_line(msg)) | |
113 msg->parse_msgtype = SIP_MSG_TYPE_RESP; | |
114 else if (try_request_line(msg)) | |
115 msg->parse_msgtype = SIP_MSG_TYPE_REQ; | |
116 else | |
117 return(-1); | |
118 /* now preparse header fields */ | |
119 cp = nextp; | |
120 for (hdr_cnt = 0; ; ) { | |
121 rc = find_crlf(cp, msg_end, &endp, &nextp); | |
122 if (!rc) | |
123 return(-1); | |
124 if (endp == cp) /* final CRLF? */ | |
125 break; | |
126 if (!isalpha(*cp)) | |
127 return(-1); | |
128 if (hdr_cnt >= MAX_HEADER_FIELDS) | |
129 return(-2); | |
130 msg->hdr_fields[hdr_cnt].field_name = cp; | |
131 while (cp < endp && (isalnum(*cp) || *cp == '-')) | |
132 cp++; | |
133 if (cp >= endp) | |
134 return(-1); | |
135 if (*cp == ':') | |
136 *cp++ = '\0'; | |
137 else if (isspace(*cp)) { | |
138 *cp++ = '\0'; | |
139 while (cp < endp && isspace(*cp)) | |
140 cp++; | |
141 if (cp >= endp) | |
142 return(-1); | |
143 if (*cp++ != ':') | |
144 return(-1); | |
145 } else | |
146 return(-1); | |
147 sp = cp; | |
148 cp = nextp; | |
149 while (cp < msg_end && (*cp == ' ' || *cp == '\t')) { | |
150 rc = find_crlf(cp, msg_end, &endp, &nextp); | |
151 if (!rc) | |
152 return(-1); | |
153 cp = nextp; | |
154 } | |
155 *endp = '\0'; | |
156 while (isspace(*sp)) | |
157 sp++; | |
158 trim_trailing_spaces(sp); | |
159 msg->hdr_fields[hdr_cnt++].field_value = sp; | |
160 } | |
161 msg->num_hdr_fields = hdr_cnt; | |
162 msg->msg_body = nextp; | |
163 msg->msg_body_len = msg_end - nextp; | |
164 return(0); | |
165 } |