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