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 }