Apply patch from Geoffrey D. Bennett to fix retry of control packets.
[l2tpns.git] / test / bounce.c
1 #include <arpa/inet.h>
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <linux/if.h>
5 #include <netdb.h>
6 #include <netinet/in.h>
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/socket.h>
12 #include <sys/types.h>
13 #include <linux/ip.h>
14 #include <linux/udp.h>
15 #include <pthread.h>
16 #include <unistd.h>
17 #include <signal.h>
18 #include <getopt.h>
19
20 #define PORT 39000
21
22 void sigalarm(int junk);
23 unsigned long long recv_count = 0;
24 unsigned long pps = 0;
25 unsigned long bytes = 0;
26 unsigned long dropped = 0, seq = 0;
27 unsigned port = PORT;
28
29 int main(int argc, char *argv[])
30 {
31 int on = 1;
32 struct sockaddr_in addr;
33 int s;
34 char *packet;
35
36 while ((s = getopt(argc, argv, "?p:")) > 0)
37 {
38 switch (s)
39 {
40 case 'p' :
41 port = atoi(optarg);
42 break;
43 case '?' :
44 printf("Options:\n");
45 printf("\t-p port to listen on\n");
46 return(0);
47 break;
48 }
49 }
50
51 memset(&addr, 0, sizeof(addr));
52 addr.sin_family = AF_INET;
53 addr.sin_port = htons(port);
54
55 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
56 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
57 if (bind(s, (void *) &addr, sizeof(addr)) < 0)
58 {
59 perror("bind");
60 return -1;
61 }
62
63 signal(SIGALRM, sigalarm);
64 alarm(1);
65
66 printf("Waiting on port %d\n", port);
67 packet = (char *)malloc(65535);
68 while (1)
69 {
70 struct sockaddr_in addr;
71 socklen_t alen = sizeof(addr);
72 int l;
73 unsigned int iseq;
74
75 l = recvfrom(s, packet, 65535, 0, (void *) &addr, &alen);
76 if (l < 0) continue;
77 recv_count++;
78 pps++;
79 bytes += l;
80 iseq = *((unsigned int *) packet);
81 if (seq != iseq)
82 dropped += (iseq - seq);
83 seq = iseq + 1;
84
85 sendto(s, packet, l, 0, (struct sockaddr *)&addr, alen);
86 }
87
88 free(packet);
89 }
90
91 void sigalarm(int unusedg __attribute__ ((unused)))
92 {
93 printf("Recv: %10llu %0.1fMbits/s (%lu pps) (%5ld dropped)\n", recv_count, (bytes / 1024.0 / 1024.0 * 8), pps, dropped);
94 pps = bytes = 0;
95 alarm(1);
96 }
97