# HG changeset patch # User Mychaela Falconia # Date 1662338011 28800 # Node ID 77d980126efd5fad27cb2514f8dc0dfcb1c9888f # Parent 64b9f0f90726063c71632cef8444703b2083ebe7 libsip started with primary parsing function diff -r 64b9f0f90726 -r 77d980126efd libsip/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsip/Makefile Sun Sep 04 16:33:31 2022 -0800 @@ -0,0 +1,13 @@ +CC= gcc +CFLAGS= -O2 +OBJS= primary_parse.o +LIB= libsip.a + +all: ${LIB} + +${LIB}: ${OBJS} + ar rcu $@ ${OBJS} + ranlib $@ + +clean: + rm -f *.[oa] errs diff -r 64b9f0f90726 -r 77d980126efd libsip/parse.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsip/parse.h Sun Sep 04 16:33:31 2022 -0800 @@ -0,0 +1,33 @@ +/* + * Here we define the structure we are going to use for receiving + * and parsing SIP UDP packets. + */ + +#define MAX_SIP_RX_PACKET 3072 +#define MAX_HEADER_FIELDS 64 + +struct sip_parse_hdr { + char *field_name; + char *field_value; +}; + +struct sip_pkt_rx { + /* recvfrom on UDP socket, input to parser */ + char pkt_buffer[MAX_SIP_RX_PACKET]; + unsigned pkt_length; + /* filled by parser */ + int parse_msgtype; + char *req_method; + char *req_uri; + unsigned status_code; + char *status_str; + /* header fields */ + struct sip_parse_hdr hdr_fields[MAX_HEADER_FIELDS]; + unsigned num_hdr_fields; + /* optional message body */ + char *msg_body; + unsigned msg_body_len; +}; + +#define SIP_MSG_TYPE_REQ 1 +#define SIP_MSG_TYPE_RESP 2 diff -r 64b9f0f90726 -r 77d980126efd libsip/primary_parse.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsip/primary_parse.c Sun Sep 04 16:33:31 2022 -0800 @@ -0,0 +1,151 @@ +/* + * In this module we are going to implement the first stage of + * parsing for incoming SIP UDP packets, using struct sip_pkt_rx + * defined in parse.h. + */ + +#include +#include +#include +#include +#include "parse.h" + +static +find_crlf(ptr, msg_end, endp, nextp) + char *ptr, *msg_end, **endp, **nextp; +{ + for (;;) { + if (ptr >= msg_end) + return(0); + switch (*ptr) { + case '\0': + return(0); + case '\n': + *endp = ptr; + *nextp = ptr + 1; + return(1); + case '\r': + *endp = ptr; + ptr++; + if (ptr >= msg_end) + return(0); + if (*ptr != '\n') + return(0); + *nextp = ptr + 1; + return(1); + } + ptr++; + } +} + +static +try_status_line(msg) + struct sip_pkt_rx *msg; +{ + if (strncmp(msg->pkt_buffer, "SIP/2.0 ", 8)) + return(0); + if (!isdigit(msg->pkt_buffer[8])) + return(0); + if (!isdigit(msg->pkt_buffer[9])) + return(0); + if (!isdigit(msg->pkt_buffer[10])) + return(0); + if (msg->pkt_buffer[11] != ' ') + return(0); + msg->status_code = atoi(msg->pkt_buffer + 8); + msg->status_str = msg->pkt_buffer + 8; + return(1); +} + +static +try_request_line(msg) + struct sip_pkt_rx *msg; +{ + char *cp; + + cp = msg->pkt_buffer; + if (!isupper(*cp)) + return(0); + while (isalnum(*cp)) + cp++; + if (*cp != ' ') + return(0); + msg->req_method = msg->pkt_buffer; + *cp++ = '\0'; + msg->req_uri = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp != ' ') + return(0); + *cp++ = '\0'; + if (strcmp(cp, "SIP/2.0")) + return(0); + else + return(1); +} + +parse_incoming_sip_msg(msg) + struct sip_pkt_rx *msg; +{ + char *msg_end = msg->pkt_buffer + msg->pkt_length; + char *cp, *endp, *nextp; + unsigned hdr_cnt; + int rc; + + /* begin by isolating the Request-Line or Status-Line */ + rc = find_crlf(msg->pkt_buffer, msg_end, &endp, &nextp); + if (!rc) + return(-1); + *endp = '\0'; + if (try_status_line(msg)) + msg->parse_msgtype = SIP_MSG_TYPE_RESP; + else if (try_request_line(msg)) + msg->parse_msgtype = SIP_MSG_TYPE_REQ; + else + return(-1); + /* now preparse header fields */ + cp = nextp; + for (hdr_cnt = 0; ; ) { + rc = find_crlf(cp, msg_end, &endp, &nextp); + if (!rc) + return(-1); + if (endp == cp) /* final CRLF? */ + break; + if (!isalpha(*cp)) + return(-1); + if (hdr_cnt >= MAX_HEADER_FIELDS) + return(-2); + msg->hdr_fields[hdr_cnt].field_name = cp; + while (cp < endp && (isalnum(*cp) || *cp == '-')) + cp++; + if (cp >= endp) + return(-1); + if (*cp == ':') + *cp++ = '\0'; + else if (isspace(*cp)) { + *cp++ = '\0'; + while (cp < endp && isspace(*cp)) + cp++; + if (cp >= endp) + return(-1); + if (*cp++ != ':') + return(-1); + } else + return(-1); + while (cp < endp && isspace(*cp)) + cp++; + msg->hdr_fields[hdr_cnt++].field_value = cp; + cp = nextp; + while (cp < msg_end && (*cp == ' ' || *cp == '\t')) { + rc = find_crlf(cp, msg_end, &endp, &nextp); + if (!rc) + return(-1); + cp = nextp; + } + *endp = '\0'; + } + msg->num_hdr_fields = hdr_cnt; + msg->msg_body = nextp; + msg->msg_body_len = msg_end - nextp; + return(0); +}