sharedscreen hack
[tridge/junkcode.git] / udpproxy.c
1 #define _GNU_SOURCE
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <time.h>
7 #include <errno.h>
8 #include <sys/socket.h>
9 #include <netdb.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <fcntl.h>
13 #include <sys/types.h>
14 #include <sys/time.h>
15 #include <arpa/inet.h>
16 #include <netinet/in.h>
17
18 static void get_address(const char *host, struct in_addr *addr)
19 {
20        if (inet_pton(AF_INET, host, addr) <= 0) {
21                struct hostent *hp;
22                hp = gethostbyname(host);
23                if (!hp) {
24                        fprintf(stderr,"unknown host %s\n", host);
25                        exit(1);
26                }
27                memcpy(addr, hp->h_addr, hp->h_length);
28        }
29 }
30
31 /*
32   open a socket of the specified type, port and address for incoming data
33 */
34 int open_socket_in(int port)
35 {
36         struct sockaddr_in sock;
37         int res;
38         int one=1;
39
40         memset(&sock,0,sizeof(sock));
41
42 #ifdef HAVE_SOCK_SIN_LEN
43         sock.sin_len = sizeof(sock);
44 #endif
45         sock.sin_port = htons(port);
46         sock.sin_family = AF_INET;
47
48         res = socket(AF_INET, SOCK_DGRAM, 0);
49         if (res == -1) { 
50                 fprintf(stderr, "socket failed\n"); return -1; 
51                 return -1;
52         }
53
54         setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
55
56         if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) { 
57                 return(-1); 
58         }
59
60         return res;
61 }
62
63 static void main_loop(int sock, const char *host1, const char *host2)
64 {
65         unsigned char buf[10240];
66         struct in_addr addr1, addr2;
67
68         get_address(host1, &addr1);
69         get_address(host2, &addr2);
70
71         while (1) {
72                 fd_set fds;
73                 int ret;
74                 struct in_addr *addr;
75
76                 FD_ZERO(&fds);
77                 FD_SET(sock, &fds);
78
79                 ret = select(sock, &fds, NULL, NULL, NULL);
80                 if (ret == -1 && errno == EINTR) continue;
81                 if (ret <= 0) break;
82
83                 if (FD_ISSET(sock, &fds)) {
84                         static struct sockaddr_in from;
85                         static socklen_t fromlen = sizeof(from);
86                         int n = recvfrom(sock, buf, sizeof(buf), 0, 
87                                          (struct sockaddr *)&from, &fromlen);
88                         if (n <= 0) break;
89
90                         if (from.sin_addr.s_addr == addr1.s_addr) {
91                                 addr = &addr2;
92                         } else if (from.sin_addr.s_addr == addr2.s_addr) {
93                                 addr = &addr1;
94                         } else {
95                                 printf("Unexpected packet from %s\n", inet_ntoa(from.sin_addr));
96                                 continue;
97                         }
98
99                         from.sin_addr = *addr;
100                         ret = sendto(sock, buf, n, 0, (struct sockaddr *)&from, sizeof(from));
101                         if (ret != n) {
102                                 printf("Failed to send %d bytes to %s - %d\n",
103                                        n, inet_ntoa(*addr), ret);
104                         }
105                 }
106         }       
107 }
108
109 int main(int argc, char *argv[])
110 {
111         int listen_port;
112         char *host1, *host2;
113         int sock_in;
114
115         if (argc < 4) {
116                 printf("Usage: udpproxy <port> <host1> <host2>\n");
117                 exit(1);
118         }
119
120         listen_port = atoi(argv[1]);
121         host1 = argv[2];
122         host2 = argv[3];
123
124         sock_in = open_socket_in(listen_port);
125         if (sock_in == -1) {
126                 fprintf(stderr,"sock on port %d failed - %s\n", 
127                         listen_port, strerror(errno));
128                 exit(1);
129         }
130
131         main_loop(sock_in, host1, host2);
132
133         return 0;
134 }