comparison 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
comparison
equal deleted inserted replaced
41:e57bc4c885a7 42:891ebfb55e6b
1 /*
2 * This test program is the next level above sip-udp-dump: it binds
3 * to UDP port 5060, waits for a packet to come in, and when a SIP
4 * packet does arrive (call one of the numbers from BulkVS while this
5 * test program is running, to make BulkVS send SIP INVITE), it does
6 * two things with the captured packet:
7 *
8 * 1) The captured packet is written raw into one file named on the
9 * command line;
10 *
11 * 2) The packet is parsed with parse_incoming_sip_msg(), and the
12 * parsed structure is written out into the other file named on
13 * the command line.
14 *
15 * This program is intended to serve as a unit test for the parsing
16 * function.
17 */
18
19 #include <sys/types.h>
20 #include <sys/file.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <strings.h>
28 #include <unistd.h>
29 #include "../libsip/parse.h"
30
31 static int sock;
32 static struct sockaddr_in sin;
33 static struct sip_pkt_rx pkt;
34
35 static void
36 save_raw_packet(filename)
37 char *filename;
38 {
39 int fd;
40
41 fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
42 if (fd < 0) {
43 perror(filename);
44 exit(1);
45 }
46 write(fd, pkt.pkt_buffer, pkt.pkt_length);
47 close(fd);
48 }
49
50 static void
51 write_parse_output(filename)
52 char *filename;
53 {
54 FILE *of;
55 unsigned n;
56
57 of = fopen(filename, "w");
58 if (!of) {
59 perror(filename);
60 exit(1);
61 }
62 switch (pkt.parse_msgtype) {
63 case SIP_MSG_TYPE_REQ:
64 fprintf(of, "Message is a request\n");
65 fprintf(of, "Method: %s\n", pkt.req_method);
66 fprintf(of, "Request-URI: %s\n", pkt.req_uri);
67 break;
68 case SIP_MSG_TYPE_RESP:
69 fprintf(of, "Message is a response\n");
70 fprintf(of, "Status code: %u\n", pkt.status_code);
71 fprintf(of, "Status string: %s\n", pkt.status_str);
72 break;
73 default:
74 fprintf(of, "Parsed returned unknown message type %d\n",
75 pkt.parse_msgtype);
76 }
77 fprintf(of, "Number of header fields: %u\n", pkt.num_hdr_fields);
78 for (n = 0; n < pkt.num_hdr_fields; n++) {
79 fprintf(of, "Header field %u:\n", n);
80 fprintf(of, " Field name: %s\n",
81 pkt.hdr_fields[n].field_name);
82 fprintf(of, " Field value: %s\n",
83 pkt.hdr_fields[n].field_value);
84 }
85 fprintf(of, "Message body length: %u\n", pkt.msg_body_len);
86 fclose(of);
87 }
88
89 main(argc, argv)
90 char **argv;
91 {
92 int rc;
93 socklen_t addrlen;
94
95 if (argc != 3) {
96 fprintf(stderr, "usage: %s raw-file parsed-file\n", argv[0]);
97 exit(1);
98 }
99 sock = socket(AF_INET, SOCK_DGRAM, 0);
100 if (sock < 0) {
101 perror("socket");
102 exit(1);
103 }
104 sin.sin_family = AF_INET;
105 sin.sin_addr.s_addr = INADDR_ANY;
106 sin.sin_port = htons(5060);
107 rc = bind(sock, (struct sockaddr *) &sin, sizeof sin);
108 if (rc < 0)
109 perror("bind");
110 addrlen = sizeof sin;
111 rc = recvfrom(sock, pkt.pkt_buffer, MAX_SIP_RX_PACKET, 0,
112 (struct sockaddr *) &sin, &addrlen);
113 if (rc < 0) {
114 perror("recvfrom");
115 exit(1);
116 }
117 pkt.pkt_length = rc;
118 printf("Rx from %s:%u, %u bytes\n", inet_ntoa(sin.sin_addr),
119 ntohs(sin.sin_port), pkt.pkt_length);
120 save_raw_packet(argv[1]);
121 rc = parse_incoming_sip_msg(&pkt);
122 if (rc < 0) {
123 printf("Parse error: %d\n", rc);
124 exit(0);
125 }
126 write_parse_output(argv[2]);
127 exit(0);
128 }