FreeCalypso > hg > themwi-system-sw
comparison libsip/primary_parse.c @ 40:77d980126efd
libsip started with primary parsing function
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 04 Sep 2022 16:33:31 -0800 |
parents | |
children | 30572642e853 |
comparison
equal
deleted
inserted
replaced
39:64b9f0f90726 | 40:77d980126efd |
---|---|
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 (strncmp(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 (strcmp(cp, "SIP/2.0")) | |
82 return(0); | |
83 else | |
84 return(1); | |
85 } | |
86 | |
87 parse_incoming_sip_msg(msg) | |
88 struct sip_pkt_rx *msg; | |
89 { | |
90 char *msg_end = msg->pkt_buffer + msg->pkt_length; | |
91 char *cp, *endp, *nextp; | |
92 unsigned hdr_cnt; | |
93 int rc; | |
94 | |
95 /* begin by isolating the Request-Line or Status-Line */ | |
96 rc = find_crlf(msg->pkt_buffer, msg_end, &endp, &nextp); | |
97 if (!rc) | |
98 return(-1); | |
99 *endp = '\0'; | |
100 if (try_status_line(msg)) | |
101 msg->parse_msgtype = SIP_MSG_TYPE_RESP; | |
102 else if (try_request_line(msg)) | |
103 msg->parse_msgtype = SIP_MSG_TYPE_REQ; | |
104 else | |
105 return(-1); | |
106 /* now preparse header fields */ | |
107 cp = nextp; | |
108 for (hdr_cnt = 0; ; ) { | |
109 rc = find_crlf(cp, msg_end, &endp, &nextp); | |
110 if (!rc) | |
111 return(-1); | |
112 if (endp == cp) /* final CRLF? */ | |
113 break; | |
114 if (!isalpha(*cp)) | |
115 return(-1); | |
116 if (hdr_cnt >= MAX_HEADER_FIELDS) | |
117 return(-2); | |
118 msg->hdr_fields[hdr_cnt].field_name = cp; | |
119 while (cp < endp && (isalnum(*cp) || *cp == '-')) | |
120 cp++; | |
121 if (cp >= endp) | |
122 return(-1); | |
123 if (*cp == ':') | |
124 *cp++ = '\0'; | |
125 else if (isspace(*cp)) { | |
126 *cp++ = '\0'; | |
127 while (cp < endp && isspace(*cp)) | |
128 cp++; | |
129 if (cp >= endp) | |
130 return(-1); | |
131 if (*cp++ != ':') | |
132 return(-1); | |
133 } else | |
134 return(-1); | |
135 while (cp < endp && isspace(*cp)) | |
136 cp++; | |
137 msg->hdr_fields[hdr_cnt++].field_value = cp; | |
138 cp = nextp; | |
139 while (cp < msg_end && (*cp == ' ' || *cp == '\t')) { | |
140 rc = find_crlf(cp, msg_end, &endp, &nextp); | |
141 if (!rc) | |
142 return(-1); | |
143 cp = nextp; | |
144 } | |
145 *endp = '\0'; | |
146 } | |
147 msg->num_hdr_fields = hdr_cnt; | |
148 msg->msg_body = nextp; | |
149 msg->msg_body_len = msg_end - nextp; | |
150 return(0); | |
151 } |