fixed for newer perl
[tridge/junkcode.git] / sockspy-smb2.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 #include <ctype.h>
16 #include <signal.h>
17
18 #define MAX(a,b) ((a)>(b)?(a):(b))
19
20 void dump_data(int level, const char *buf1, int len)
21 {
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) {
25                 int i;
26                 for (i=0;i<len;i++)
27                         DEBUGADD(level,("%c", isprint(buf[i])?buf[i]:'.'));
28         }
29         const uint8_t *buf = (const uint8_t *)buf1;
30         int i=0;
31         if (len<=0) return;
32
33
34         DEBUGADD(level,("[%03X] ",i));
35         for (i=0;i<len;) {
36                 DEBUGADD(level,("%02X ",(int)buf[i]));
37                 i++;
38                 if (i%8 == 0) DEBUGADD(level,(" "));
39                 if (i%16 == 0) {      
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));
43                 }
44         }
45         if (i%16) {
46                 int n;
47                 n = 16 - (i%16);
48                 DEBUGADD(level,(" "));
49                 if (n>8) DEBUGADD(level,(" "));
50                 while (n--) DEBUGADD(level,("   "));
51                 n = MIN(8,i%16);
52                 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
53                 n = (i%16) - n;
54                 if (n>0) print_asc(level,&buf[i-n],n); 
55                 DEBUGADD(level,("\n"));    
56         }       
57 }
58
59 /* open a socket to a tcp remote host with the specified port */
60 static int open_socket_out(const char *host, int port)
61 {
62         struct sockaddr_in sock_out;
63         int res;
64         struct hostent *hp;  
65         struct in_addr addr;
66
67         res = socket(PF_INET, SOCK_STREAM, 0);
68         if (res == -1) {
69                 return -1;
70         }
71
72         if (inet_pton(AF_INET, host, &addr) > 0) {
73                 memcpy(&sock_out.sin_addr, &addr, sizeof(addr));
74         } else {
75                 hp = gethostbyname(host);
76                 if (!hp) {
77                         fprintf(stderr,"tseal: unknown host %s\n", host);
78                         return -1;
79                 }
80                 memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
81         }
82
83         sock_out.sin_port = htons(port);
84         sock_out.sin_family = PF_INET;
85
86         if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
87                 close(res);
88                 fprintf(stderr,"tseal: failed to connect to %s (%s)\n", 
89                         host, strerror(errno));
90                 return -1;
91         }
92
93         return res;
94 }
95
96
97 /*
98   open a socket of the specified type, port and address for incoming data
99 */
100 int open_socket_in(int port)
101 {
102         struct sockaddr_in sock;
103         int res;
104         int one=1;
105
106         memset(&sock,0,sizeof(sock));
107
108 #ifdef HAVE_SOCK_SIN_LEN
109         sock.sin_len = sizeof(sock);
110 #endif
111         sock.sin_port = htons(port);
112         sock.sin_family = AF_INET;
113
114         res = socket(AF_INET, SOCK_STREAM, 0);
115         if (res == -1) { 
116                 fprintf(stderr, "socket failed\n"); return -1; 
117                 return -1;
118         }
119
120         setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
121
122         if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) { 
123                 return(-1); 
124         }
125
126         return res;
127 }
128
129 /* write to a file descriptor, making sure we get all the data out or
130  * die trying */
131 static void write_all(int fd, unsigned char *s, size_t n)
132 {
133         while (n) {
134                 int r;
135                 r = write(fd, s, n);
136                 if (r <= 0) {
137                         exit(1);
138                 }
139                 s += r;
140                 n -= r;
141         }
142 }
143
144 /* read from a file descriptor, making sure we get all the data 
145    or die trying */
146 static void read_all(int fd, unsigned char *s, size_t n)
147 {
148         while (n) {
149                 int r;
150                 r = read(fd, s, n);
151                 if (r <= 0) {
152                         fprintf(stderr, "eof on sock %d\n", fd);
153                         exit(1);
154                 }
155                 s += r;
156                 n -= r;
157         }
158 }
159
160 static int frame;
161
162 static void recv_send(int sock1, int sock2)
163 {
164         unsigned char buf1[4];
165         int len;
166         unsigned char *buf;
167
168         read_all(sock1, buf1, 4);
169
170         len = ntohl((*(unsigned int *)buf1) & 0xFFFFFF00);
171         
172         buf = malloc(len+4);
173
174         read_all(sock1, buf+4, len);
175
176         printf("frame %4d of length %d\n", frame++, len);
177         dump_data(0, (char *)buf+4, len);
178
179         memcpy(buf, buf1, 4);
180         write_all(sock2, buf, len+4);
181
182         free(buf);
183 }
184
185 static void main_loop(int sock1, int sock2)
186 {
187         while (1) {
188                 fd_set fds;
189                 int ret;
190
191                 FD_ZERO(&fds);
192                 FD_SET(sock1, &fds);
193                 FD_SET(sock2, &fds);
194
195                 ret = select(MAX(sock1, sock2)+1, &fds, NULL, NULL, NULL);
196                 if (ret == -1 && errno == EINTR) continue;
197                 if (ret <= 0) break;
198
199                 if (FD_ISSET(sock1, &fds)) {
200                         recv_send(sock1, sock2);
201                 }
202
203                 if (FD_ISSET(sock2, &fds)) {
204                         recv_send(sock2, sock1);
205                 }
206         }       
207 }
208
209 int main(int argc, char *argv[])
210 {
211         int listen_port, dest_port;
212         char *host;
213         int sock_in;
214         int sock_out;
215         int listen_fd;
216         struct sockaddr addr;
217         socklen_t in_addrlen = sizeof(addr);
218
219         if (argc < 4) {
220                 printf("Usage: sockspy <inport> <host> <port>\n");
221                 exit(1);
222         }
223
224         listen_port = atoi(argv[1]);
225         host = argv[2];
226         dest_port = atoi(argv[3]);
227
228         listen_fd = open_socket_in(listen_port);
229
230         if (listen_fd == -1) {
231                 fprintf(stderr,"listen on port %d failed - %s\n", 
232                         listen_port, strerror(errno));
233                 exit(1);
234         }
235
236         if (listen(listen_fd, 5) == -1) {
237                 fprintf(stderr,"listen failed\n");
238                 exit(1);
239         }
240
241         signal(SIGCHLD, SIG_IGN);
242
243         while ((sock_in = accept(listen_fd,&addr,&in_addrlen)) != -1) {
244                 if (fork() == 0) {
245                         close(listen_fd);
246                         sock_out = open_socket_out(host, dest_port);
247                         if (sock_out == -1) {
248                                 exit(1);
249                         }
250
251                         main_loop(sock_in, sock_out);
252                         exit(0);
253                 }
254                 close(sock_in);
255         }
256         return 0;
257 }