added -A and -U
[tridge/junkcode.git] / sockspy-random.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
5 #include <errno.h>
6 #include <sys/socket.h>
7 #include <netdb.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <fcntl.h>
11 #include <sys/types.h>
12 #include <sys/time.h>
13 #include <arpa/inet.h>
14 #include <netinet/in.h>
15
16 #define MAX(a,b) ((a)>(b)?(a):(b))
17
18 /* open a socket to a tcp remote host with the specified port */
19 static int open_socket_out(const char *host, int port)
20 {
21         struct sockaddr_in sock_out;
22         int res;
23         struct hostent *hp;  
24         struct in_addr addr;
25
26         res = socket(PF_INET, SOCK_STREAM, 0);
27         if (res == -1) {
28                 return -1;
29         }
30
31         if (inet_pton(AF_INET, host, &addr) > 0) {
32                 memcpy(&sock_out.sin_addr, &addr, sizeof(addr));
33         } else {
34                 hp = gethostbyname(host);
35                 if (!hp) {
36                         fprintf(stderr,"unknown host %s\n", host);
37                         return -1;
38                 }
39                 memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
40         }
41
42         sock_out.sin_port = htons(port);
43         sock_out.sin_family = PF_INET;
44
45         if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
46                 close(res);
47                 fprintf(stderr,"failed to connect to %s (%s)\n", 
48                         host, strerror(errno));
49                 return -1;
50         }
51
52         return res;
53 }
54
55
56 /*
57   open a socket of the specified type, port and address for incoming data
58 */
59 int open_socket_in(int port)
60 {
61         struct sockaddr_in sock;
62         int res;
63         int one=1;
64
65         memset(&sock,0,sizeof(sock));
66
67 #ifdef HAVE_SOCK_SIN_LEN
68         sock.sin_len = sizeof(sock);
69 #endif
70         sock.sin_port = htons(port);
71         sock.sin_family = AF_INET;
72
73         res = socket(AF_INET, SOCK_STREAM, 0);
74         if (res == -1) { 
75                 fprintf(stderr, "socket failed\n"); return -1; 
76                 return -1;
77         }
78
79         setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
80
81         if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) { 
82                 return(-1); 
83         }
84
85         return res;
86 }
87
88 /* write to a file descriptor, making sure we get all the data out or
89  * die trying */
90 static void write_all(int fd, unsigned char *s, size_t n)
91 {
92         while (n) {
93                 int r;
94                 r = write(fd, s, n);
95                 if (r <= 0) {
96                         exit(1);
97                 }
98                 s += r;
99                 n -= r;
100         }
101 }
102
103
104 static void randomise(char *buf, int n)
105 {
106         int i;
107         if (random() % 100 < 70) {
108                 return;
109         }
110         for (i=0;i<3;i++) {
111                 buf[random() % n] = random();
112         }
113 }
114
115 static void main_loop(int sock1, int sock2)
116 {
117         unsigned char buf[1024];
118
119         srandom(getpid());
120
121         while (1) {
122                 fd_set fds;
123                 int ret;
124
125                 FD_ZERO(&fds);
126                 FD_SET(sock1, &fds);
127                 FD_SET(sock2, &fds);
128
129                 ret = select(MAX(sock1, sock2)+1, &fds, NULL, NULL, NULL);
130                 if (ret == -1 && errno == EINTR) continue;
131                 if (ret <= 0) break;
132
133                 if (FD_ISSET(sock1, &fds)) {
134                         int n = read(sock1, buf, sizeof(buf));
135                         if (n <= 0) break;
136
137 //                      randomise(buf, n);
138
139                         write_all(sock2, buf, n);
140                 }
141
142                 if (FD_ISSET(sock2, &fds)) {
143                         int n = read(sock2, buf, sizeof(buf));
144                         if (n <= 0) break;
145                         write_all(sock1, buf, n);
146                 }
147         }       
148 }
149
150 int main(int argc, char *argv[])
151 {
152         int listen_port, dest_port;
153         char *host;
154         int sock_in;
155         int sock_out;
156         int listen_fd;
157         struct sockaddr addr;
158         int in_addrlen = sizeof(addr);
159
160         if (argc < 4) {
161                 printf("Usage: sockspy <inport> <host> <port>\n");
162                 exit(1);
163         }
164
165         listen_port = atoi(argv[1]);
166         host = argv[2];
167         dest_port = atoi(argv[3]);
168
169         listen_fd = open_socket_in(listen_port);
170
171         if (listen_fd == -1) {
172                 fprintf(stderr,"listen on port %d failed - %s\n", 
173                         listen_port, strerror(errno));
174                 exit(1);
175         }
176
177         if (listen(listen_fd, 100) == -1) {
178                 fprintf(stderr,"listen failed\n");
179                 exit(1);
180         }
181
182         while (1) {
183                 sock_in = accept(listen_fd,&addr,&in_addrlen);
184                 if (sock_in == -1) {
185                         fprintf(stderr,"accept on port %d failed - %s\n", 
186                                 listen_port, strerror(errno));
187                         exit(1);
188                 }
189
190                 if (fork() == 0) {
191                         close(listen_fd);
192
193                         sock_out = open_socket_out(host, dest_port);
194                         if (sock_out == -1) {
195                                 exit(1);
196                         }
197
198                         main_loop(sock_in, sock_out);
199                         _exit(0);
200                 }
201
202                 close(sock_in);
203         }
204
205         return 0;
206 }