6 #include <sys/socket.h>
11 #include <sys/types.h>
13 #include <arpa/inet.h>
14 #include <netinet/in.h>
18 #define MAX(a,b) ((a)>(b)?(a):(b))
20 void dump_data(int level, const char *buf1, int len)
22 #define DEBUGADD(lvl, x) printf x
23 #define MIN(a,b) ((a)<(b)?(a):(b))
24 void print_asc(int level, const uint8_t *buf,int len) {
27 DEBUGADD(level,("%c", isprint(buf[i])?buf[i]:'.'));
29 const uint8_t *buf = (const uint8_t *)buf1;
34 DEBUGADD(level,("[%03X] ",i));
36 DEBUGADD(level,("%02X ",(int)buf[i]));
38 if (i%8 == 0) DEBUGADD(level,(" "));
40 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
41 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
42 if (i<len) DEBUGADD(level,("[%03X] ",i));
48 DEBUGADD(level,(" "));
49 if (n>8) DEBUGADD(level,(" "));
50 while (n--) DEBUGADD(level,(" "));
52 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
54 if (n>0) print_asc(level,&buf[i-n],n);
55 DEBUGADD(level,("\n"));
59 /* open a socket to a tcp remote host with the specified port */
60 static int open_socket_out(const char *host, int port)
62 struct sockaddr_in sock_out;
67 res = socket(PF_INET, SOCK_STREAM, 0);
72 if (inet_pton(AF_INET, host, &addr) > 0) {
73 memcpy(&sock_out.sin_addr, &addr, sizeof(addr));
75 hp = gethostbyname(host);
77 fprintf(stderr,"tseal: unknown host %s\n", host);
80 memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
83 sock_out.sin_port = htons(port);
84 sock_out.sin_family = PF_INET;
86 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
88 fprintf(stderr,"tseal: failed to connect to %s (%s)\n",
89 host, strerror(errno));
98 open a socket of the specified type, port and address for incoming data
100 int open_socket_in(int port)
102 struct sockaddr_in sock;
106 memset(&sock,0,sizeof(sock));
108 #ifdef HAVE_SOCK_SIN_LEN
109 sock.sin_len = sizeof(sock);
111 sock.sin_port = htons(port);
112 sock.sin_family = AF_INET;
114 res = socket(AF_INET, SOCK_STREAM, 0);
116 fprintf(stderr, "socket failed\n"); return -1;
120 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
122 if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) {
129 /* write to a file descriptor, making sure we get all the data out or
131 static void write_all(int fd, unsigned char *s, size_t n)
144 /* read from a file descriptor, making sure we get all the data
146 static void read_all(int fd, unsigned char *s, size_t n)
152 fprintf(stderr, "eof on sock %d\n", fd);
162 static void recv_send(int sock1, int sock2)
164 unsigned char buf1[4];
168 read_all(sock1, buf1, 4);
170 len = ntohl((*(unsigned int *)buf1) & 0xFFFFFF00);
174 read_all(sock1, buf+4, len);
176 printf("frame %4d of length %d\n", frame++, len);
177 dump_data(0, (char *)buf+4, len);
179 memcpy(buf, buf1, 4);
180 write_all(sock2, buf, len+4);
185 static void main_loop(int sock1, int sock2)
195 ret = select(MAX(sock1, sock2)+1, &fds, NULL, NULL, NULL);
196 if (ret == -1 && errno == EINTR) continue;
199 if (FD_ISSET(sock1, &fds)) {
200 recv_send(sock1, sock2);
203 if (FD_ISSET(sock2, &fds)) {
204 recv_send(sock2, sock1);
209 int main(int argc, char *argv[])
211 int listen_port, dest_port;
216 struct sockaddr addr;
217 socklen_t in_addrlen = sizeof(addr);
220 printf("Usage: sockspy <inport> <host> <port>\n");
224 listen_port = atoi(argv[1]);
226 dest_port = atoi(argv[3]);
228 listen_fd = open_socket_in(listen_port);
230 if (listen_fd == -1) {
231 fprintf(stderr,"listen on port %d failed - %s\n",
232 listen_port, strerror(errno));
236 if (listen(listen_fd, 5) == -1) {
237 fprintf(stderr,"listen failed\n");
241 signal(SIGCHLD, SIG_IGN);
243 while ((sock_in = accept(listen_fd,&addr,&in_addrlen)) != -1) {
246 sock_out = open_socket_out(host, dest_port);
247 if (sock_out == -1) {
251 main_loop(sock_in, sock_out);