Merge branch 'vendor/DIFFUTILS'
[dragonfly.git] / contrib / ipfilter / ipsend / sock.c
1 /* $FreeBSD: src/contrib/ipfilter/ipsend/sock.c,v 1.3.2.4 2003/03/01 03:55:53 darrenr Exp $ */
2 /* $DragonFly: src/contrib/ipfilter/ipsend/sock.c,v 1.4 2007/02/01 10:33:25 corecode Exp $ */
3 /*
4  * sock.c (C) 1995-1998 Darren Reed
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  */
8 #include <sys/user.h>
9
10 #if defined(__sgi) && (IRIX > 602)
11 # include <sys/ptimers.h>
12 #endif
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <stddef.h>
18 #include <pwd.h>
19 #include <sys/types.h>
20 #include <sys/time.h>
21 #include <sys/param.h>
22 #include <sys/stat.h>
23 #ifndef ultrix
24 #include <fcntl.h>
25 #endif
26 #if (__FreeBSD_version >= 300000)
27 # include <sys/dirent.h>
28 #else
29 # include <sys/dirent.h>
30 #endif
31 #define _KERNEL
32 #define KERNEL
33 #ifdef  ultrix
34 # undef LOCORE
35 # include <sys/smp_lock.h>
36 #endif
37 #include <sys/file.h>
38 #undef  _KERNEL
39 #undef  KERNEL
40 #include <nlist.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/proc.h>
44 #if !defined(ultrix) && !defined(hpux)
45 # include <kvm.h>
46 #endif
47 #ifdef sun
48 #include <sys/systm.h>
49 #include <sys/session.h>
50 #endif
51 #if BSD >= 199103
52 #include <sys/sysctl.h>
53 #include <sys/filedesc.h>
54 #include <paths.h>
55 #endif
56 #include <math.h>
57 #include <netinet/in.h>
58 #include <netinet/in_systm.h>
59 #include <netinet/ip.h>
60 #include <netinet/tcp.h>
61 #include <net/if.h>
62 #include <net/route.h>
63 #include <netinet/ip_var.h>
64 #include <netinet/in_pcb.h>
65 #include <netinet/tcp_timer.h>
66 #include <netinet/tcp_var.h>
67 #include "ipsend.h"
68
69 #if !defined(lint)
70 static const char sccsid[] = "@(#)sock.c        1.2 1/11/96 (C)1995 Darren Reed";
71 static const char rcsid[] = "@(#)$Id: sock.c,v 2.1.4.6 2002/12/06 11:40:36 darrenr Exp $";
72 #endif
73
74
75 int     nproc;
76 struct  proc    *proc;
77
78 #ifndef KMEM
79 # ifdef _PATH_KMEM
80 #  define       KMEM    _PATH_KMEM
81 # endif
82 #endif
83 #ifndef KERNEL
84 # ifdef _PATH_UNIX
85 #  define       KERNEL  _PATH_UNIX
86 # endif
87 #endif
88 #ifndef KMEM
89 # define        KMEM    "/dev/kmem"
90 #endif
91 #ifndef KERNEL
92 # define        KERNEL  "/vmunix"
93 #endif
94
95
96 #if BSD < 199103
97 static  struct  proc    *getproc __P((void));
98 #else
99 static  struct  kinfo_proc      *getproc __P((void));
100 #endif
101
102
103 int     kmemcpy(buf, pos, n)
104 char    *buf;
105 void    *pos;
106 int     n;
107 {
108         static  int     kfd = -1;
109         off_t   offset = (u_long)pos;
110
111         if (kfd == -1)
112                 kfd = open(KMEM, O_RDONLY);
113
114         if (lseek(kfd, offset, SEEK_SET) == -1)
115             {
116                 perror("lseek");
117                 return -1;
118             }
119         if (read(kfd, buf, n) == -1)
120             {
121                 perror("read");
122                 return -1;
123             }
124         return n;
125 }
126
127 struct  nlist   names[4] = {
128         { "_proc" },
129         { "_nproc" },
130 #ifdef  ultrix
131         { "_u" },
132 #else
133         { NULL },
134 #endif
135         { NULL }
136         };
137
138 #if BSD < 199103
139 static struct proc *getproc()
140 {
141         struct  proc    *p;
142         pid_t   pid = getpid();
143         int     siz, n;
144
145         n = nlist(KERNEL, names);
146         if (n != 0)
147             {
148                 fprintf(stderr, "nlist(%#x) == %d\n", names, n);
149                 return NULL;
150             }
151         if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1)
152             {
153                 fprintf(stderr, "read nproc (%#x)\n", names[1].n_value);
154                 return NULL;
155             }
156         siz = nproc * sizeof(struct proc);
157         if (KMCPY(&p, names[0].n_value, sizeof(p)) == -1)
158             {
159                 fprintf(stderr, "read(%#x,%#x,%d) proc\n",
160                         names[0].n_value, &p, sizeof(p));
161                 return NULL;
162             }
163         proc = (struct proc *)malloc(siz);
164         if (KMCPY(proc, p, siz) == -1)
165             {
166                 fprintf(stderr, "read(%#x,%#x,%d) proc\n",
167                         p, proc, siz);
168                 return NULL;
169             }
170
171         p = proc;
172
173         for (n = nproc; n; n--, p++)
174                 if (p->p_pid == pid)
175                         break;
176         if (!n)
177                 return NULL;
178
179         return p;
180 }
181
182
183 struct  tcpcb   *find_tcp(fd, ti)
184 int     fd;
185 struct  tcpiphdr *ti;
186 {
187         struct  tcpcb   *t;
188         struct  inpcb   *i;
189         struct  socket  *s;
190         struct  user    *up;
191         struct  proc    *p;
192         struct  file    *f;
193         struct  fdnode  *o;
194
195         if (!(p = getproc()))
196                 return NULL;
197         up = (struct user *)malloc(sizeof(*up));
198 #ifndef ultrix
199         if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1)
200             {
201                 fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea);
202                 return NULL;
203             }
204 #else
205         if (KMCPY(up, names[2].n_value, sizeof(*up)) == -1)
206             {
207                 fprintf(stderr, "read(%#x,%#x) failed\n", p, names[2].n_value);
208                 return NULL;
209             }
210 #endif
211
212         o = (struct fdnode *)calloc(1, sizeof(*o) * (up->u_lastfile + 1));
213         if (KMCPY(o, up->u_ofile, (up->u_lastfile + 1) * sizeof(*o)) == -1)
214             {
215                 fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n",
216                         up->u_ofile, o, sizeof(*o));
217                 return NULL;
218             }
219         f = (struct file *)calloc(1, sizeof(*f));
220         if (KMCPY(f, o[fd].fp, sizeof(*f)) == -1)
221             {
222                 fprintf(stderr, "read(%#x,%#x,%d) - o[fd].fp - failed\n",
223                         up->u_ofile[fd], f, sizeof(*f));
224                 return NULL;
225             }
226
227         s = (struct socket *)calloc(1, sizeof(*s));
228         if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
229             {
230                 fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n",
231                         o[fd], s, sizeof(*s));
232                 return NULL;
233             }
234
235         i = (struct inpcb *)calloc(1, sizeof(*i));
236         if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
237             {
238                 fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n",
239                         s->so_pcb, i, sizeof(*i));
240                 return NULL;
241             }
242
243         t = (struct tcpcb *)calloc(1, sizeof(*t));
244         if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
245             {
246                 fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n",
247                         i->inp_ppcb, t, sizeof(*t));
248                 return NULL;
249             }
250         return (struct tcpcb *)i->inp_ppcb;
251 }
252 #else
253 static struct kinfo_proc *getproc()
254 {
255         static  struct  kinfo_proc kp;
256         pid_t   pid = getpid();
257         int     mib[4];
258         size_t  n;
259
260         mib[0] = CTL_KERN;
261         mib[1] = KERN_PROC;
262         mib[2] = KERN_PROC_PID;
263         mib[3] = pid;
264
265         n = sizeof(kp);
266         if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1)
267             {
268                 perror("sysctl");
269                 return NULL;
270             }
271         return &kp;
272 }
273
274 struct  tcpcb   *find_tcp(tfd, ti)
275 int     tfd;
276 struct  tcpiphdr *ti;
277 {
278         struct  tcpcb   *t;
279         struct  inpcb   *i;
280         struct  socket  *s;
281         struct  filedesc        *fd;
282         struct  kinfo_proc      *p;
283         struct  file    *f;
284         struct  fdnode  *o;
285
286         if (!(p = getproc()))
287                 return NULL;
288
289         fd = (struct filedesc *)malloc(sizeof(*fd));
290         if (KMCPY(fd, p->kp_fd, sizeof(*fd)) == -1)
291             {
292                 fprintf(stderr, "read(%#lx,%#lx) failed\n",
293                         (u_long)p, (u_long)p->kp_fd);
294                 return NULL;
295             }
296
297         o = (struct fdnode *)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1));
298         if (KMCPY(o, fd->fd_files, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
299             {
300                 fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
301                         (u_long)fd->fd_files, (u_long)o, (u_long)sizeof(*o));
302                 return NULL;
303             }
304         f = (struct file *)calloc(1, sizeof(*f));
305         if (KMCPY(f, o[tfd].fp, sizeof(*f)) == -1)
306             {
307                 fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd].fp - failed\n",
308                         (u_long)o[tfd].fp, (u_long)f, (u_long)sizeof(*f));
309                 return NULL;
310             }
311
312         s = (struct socket *)calloc(1, sizeof(*s));
313         if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
314             {
315                 fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n",
316                         (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s));
317                 return NULL;
318             }
319
320         i = (struct inpcb *)calloc(1, sizeof(*i));
321         if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
322             {
323                 fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n",
324                         (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i));
325                 return NULL;
326             }
327
328         t = (struct tcpcb *)calloc(1, sizeof(*t));
329         if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
330             {
331                 fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n",
332                         (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t));
333                 return NULL;
334             }
335         return (struct tcpcb *)i->inp_ppcb;
336 }
337 #endif /* BSD < 199301 */
338
339 int     do_socket(dev, mtu, ti, gwip)
340 char    *dev;
341 int     mtu;
342 struct  tcpiphdr *ti;
343 struct  in_addr gwip;
344 {
345         struct  sockaddr_in     rsin, lsin;
346         struct  tcpcb   *t, tcb;
347         int     fd, nfd, len;
348
349         printf("Dest. Port: %d\n", ti->ti_dport);
350
351         fd = socket(AF_INET, SOCK_STREAM, 0);
352         if (fd == -1)
353             {
354                 perror("socket");
355                 return -1;
356             }
357
358         if (fcntl(fd, F_SETFL, FNDELAY) == -1)
359             {
360                 perror("fcntl");
361                 return -1;
362             }
363
364         bzero((char *)&lsin, sizeof(lsin));
365         lsin.sin_family = AF_INET;
366         bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr,
367               sizeof(struct in_addr));
368         if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1)
369             {
370                 perror("bind");
371                 return -1;
372             }
373         len = sizeof(lsin);
374         (void) getsockname(fd, (struct sockaddr *)&lsin, &len);
375         ti->ti_sport = lsin.sin_port;
376         printf("sport %d\n", ntohs(lsin.sin_port));
377         nfd = initdevice(dev, ntohs(lsin.sin_port), 1);
378
379         if (!(t = find_tcp(fd, ti)))
380                 return -1;
381
382         bzero((char *)&rsin, sizeof(rsin));
383         rsin.sin_family = AF_INET;
384         bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr,
385               sizeof(struct in_addr));
386         rsin.sin_port = ti->ti_dport;
387         if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 &&
388             errno != EINPROGRESS)
389             {
390                 perror("connect");
391                 return -1;
392             }
393         KMCPY(&tcb, t, sizeof(tcb));
394         ti->ti_win = tcb.rcv_adv;
395         ti->ti_seq = tcb.snd_nxt - 1;
396         ti->ti_ack = tcb.rcv_nxt;
397
398         if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1)
399                 return -1;
400         (void)write(fd, "Hello World\n", 12);
401         sleep(2);
402         close(fd);
403         return 0;
404 }