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