FreeCalypso > hg > themwi-system-sw
diff utils/sip-rx-test.c @ 42:891ebfb55e6b
sip-rx-test program written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 04 Sep 2022 17:55:40 -0800 |
parents | |
children | 5995660dcbac |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/sip-rx-test.c Sun Sep 04 17:55:40 2022 -0800 @@ -0,0 +1,128 @@ +/* + * This test program is the next level above sip-udp-dump: it binds + * to UDP port 5060, waits for a packet to come in, and when a SIP + * packet does arrive (call one of the numbers from BulkVS while this + * test program is running, to make BulkVS send SIP INVITE), it does + * two things with the captured packet: + * + * 1) The captured packet is written raw into one file named on the + * command line; + * + * 2) The packet is parsed with parse_incoming_sip_msg(), and the + * parsed structure is written out into the other file named on + * the command line. + * + * This program is intended to serve as a unit test for the parsing + * function. + */ + +#include <sys/types.h> +#include <sys/file.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include "../libsip/parse.h" + +static int sock; +static struct sockaddr_in sin; +static struct sip_pkt_rx pkt; + +static void +save_raw_packet(filename) + char *filename; +{ + int fd; + + fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (fd < 0) { + perror(filename); + exit(1); + } + write(fd, pkt.pkt_buffer, pkt.pkt_length); + close(fd); +} + +static void +write_parse_output(filename) + char *filename; +{ + FILE *of; + unsigned n; + + of = fopen(filename, "w"); + if (!of) { + perror(filename); + exit(1); + } + switch (pkt.parse_msgtype) { + case SIP_MSG_TYPE_REQ: + fprintf(of, "Message is a request\n"); + fprintf(of, "Method: %s\n", pkt.req_method); + fprintf(of, "Request-URI: %s\n", pkt.req_uri); + break; + case SIP_MSG_TYPE_RESP: + fprintf(of, "Message is a response\n"); + fprintf(of, "Status code: %u\n", pkt.status_code); + fprintf(of, "Status string: %s\n", pkt.status_str); + break; + default: + fprintf(of, "Parsed returned unknown message type %d\n", + pkt.parse_msgtype); + } + fprintf(of, "Number of header fields: %u\n", pkt.num_hdr_fields); + for (n = 0; n < pkt.num_hdr_fields; n++) { + fprintf(of, "Header field %u:\n", n); + fprintf(of, " Field name: %s\n", + pkt.hdr_fields[n].field_name); + fprintf(of, " Field value: %s\n", + pkt.hdr_fields[n].field_value); + } + fprintf(of, "Message body length: %u\n", pkt.msg_body_len); + fclose(of); +} + +main(argc, argv) + char **argv; +{ + int rc; + socklen_t addrlen; + + if (argc != 3) { + fprintf(stderr, "usage: %s raw-file parsed-file\n", argv[0]); + exit(1); + } + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + perror("socket"); + exit(1); + } + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(5060); + rc = bind(sock, (struct sockaddr *) &sin, sizeof sin); + if (rc < 0) + perror("bind"); + addrlen = sizeof sin; + rc = recvfrom(sock, pkt.pkt_buffer, MAX_SIP_RX_PACKET, 0, + (struct sockaddr *) &sin, &addrlen); + if (rc < 0) { + perror("recvfrom"); + exit(1); + } + pkt.pkt_length = rc; + printf("Rx from %s:%u, %u bytes\n", inet_ntoa(sin.sin_addr), + ntohs(sin.sin_port), pkt.pkt_length); + save_raw_packet(argv[1]); + rc = parse_incoming_sip_msg(&pkt); + if (rc < 0) { + printf("Parse error: %d\n", rc); + exit(0); + } + write_parse_output(argv[2]); + exit(0); +}