9d3f334e9f52d07d6e96c9ce49df92e98e84a96e
[l2tpns.git] / 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 port = PORT;
27
28 int main(int argc, char *argv[])
29 {
30 int on = 1;
31 struct sockaddr_in addr;
32 int s;
33 char *packet;
34
35 while ((s = getopt(argc, argv, "?p:")) > 0)
36 {
37 switch (s)
38 {
39 case 'p' :
40 port = atoi(optarg);
41 break;
42 case '?' :
43 printf("Options:\n");
44 printf("\t-p port to listen on\n");
45 return(0);
46 break;
47 }
48 }
49
50 memset(&addr, 0, sizeof(addr));
51 addr.sin_family = AF_INET;
52 addr.sin_port = htons(port);
53
54 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
55 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
56 if (bind(s, (void *) &addr, sizeof(addr)) < 0)
57 {
58 perror("bind");
59 return -1;
60 }
61
62 signal(SIGALRM, sigalarm);
63 alarm(1);
64
65 printf("Waiting on port %d\n", port);
66 packet = (char *)malloc(65535);
67 while (1)
68 {
69 struct sockaddr_in addr;
70 int alen = sizeof(addr), l;
71
72 l = recvfrom(s, packet, 65535, 0, (void *) &addr, &alen);
73 if (l < 0) continue;
74 recv_count++;
75 pps++;
76 bytes += l;
77
78 sendto(s, packet, l, 0, (struct sockaddr *)&addr, alen);
79 }
80
81 free(packet);
82 }
83
84 void sigalarm(int junk)
85 {
86 printf("Recv: %10llu %0.1fMbits/s (%lu pps)\n", recv_count, (bytes / 1024.0 / 1024.0 * 8), pps);
87 pps = bytes = 0;
88 alarm(1);
89 }
90