8 #include <sys/socket.h>
13 #include <sys/types.h>
15 #include <arpa/inet.h>
16 #include <netinet/in.h>
18 #define MAX(a,b) ((a)>(b)?(a):(b))
20 /* open a socket to a remote host with the specified port */
21 static int open_socket_out(const char *host, int port)
23 struct sockaddr_in sock_out;
28 res = socket(PF_INET, SOCK_DGRAM, 0);
33 if (inet_pton(AF_INET, host, &addr) > 0) {
34 memcpy(&sock_out.sin_addr, &addr, sizeof(addr));
36 hp = gethostbyname(host);
38 fprintf(stderr,"unknown host %s\n", host);
41 memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
44 sock_out.sin_port = htons(port);
45 sock_out.sin_family = PF_INET;
47 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
49 fprintf(stderr,"failed to connect to %s (%s)\n",
50 host, strerror(errno));
59 open a socket of the specified type, port and address for incoming data
61 int open_socket_in(int port)
63 struct sockaddr_in sock;
67 memset(&sock,0,sizeof(sock));
69 #ifdef HAVE_SOCK_SIN_LEN
70 sock.sin_len = sizeof(sock);
72 sock.sin_port = htons(port);
73 sock.sin_family = AF_INET;
75 res = socket(AF_INET, SOCK_DGRAM, 0);
77 fprintf(stderr, "socket failed\n"); return -1;
81 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
83 if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) {
90 /* write to a file descriptor, making sure we get all the data out or
92 static void write_all(int fd, unsigned char *s, size_t n)
106 static void main_loop(int sock1, int sock2)
108 unsigned char buf[1024];
110 struct sockaddr from;
111 socklen_t fromlen = sizeof(from);
115 char *fname1, *fname2;
116 asprintf(&fname1, "udpspy-in.%d", i);
117 asprintf(&fname2, "udpspy-out.%d", i);
118 log1 = open(fname1, O_WRONLY|O_CREAT|O_EXCL, 0644);
119 log2 = open(fname2, O_WRONLY|O_CREAT|O_EXCL, 0644);
123 } while (i<1000 && (log1 == -1 || log2 == -1));
125 if (log1 == -1 || log2 == -1) {
126 fprintf(stderr,"Failed to open log files\n");
138 ret = select(MAX(sock1, sock2)+1, &fds, NULL, NULL, NULL);
139 if (ret == -1 && errno == EINTR) continue;
142 if (FD_ISSET(sock1, &fds)) {
143 int n = recvfrom(sock1, buf, sizeof(buf), 0, &from, &fromlen);
147 connect(sock1,&from,sizeof(from));
151 printf("out %d bytes\n", n);
152 write_all(sock2, buf, n);
153 write_all(log1, buf, n);
156 if (FD_ISSET(sock2, &fds)) {
157 int n = read(sock2, buf, sizeof(buf));
160 printf("in %d bytes\n", n);
161 write_all(sock1, buf, n);
162 write_all(log2, buf, n);
167 int main(int argc, char *argv[])
169 int listen_port, dest_port;
173 struct sockaddr addr;
174 int in_addrlen = sizeof(addr);
177 printf("Usage: sockspy <inport> <host> <port>\n");
181 listen_port = atoi(argv[1]);
183 dest_port = atoi(argv[3]);
185 sock_in = open_socket_in(listen_port);
188 fprintf(stderr,"sock on port %d failed - %s\n",
189 listen_port, strerror(errno));
193 sock_out = open_socket_out(host, dest_port);
194 if (sock_out == -1) {
198 main_loop(sock_in, sock_out);