]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ipfilter/ipsend/sock.c
Merge commit 47b0262d3 from llvm git (by me):
[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$";
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 #include <fcntl.h>
25 # include <sys/dirent.h>
26 # ifdef __NetBSD__
27 #  include <machine/lock.h>
28 # endif
29 # ifdef __FreeBSD__
30 #  define _WANT_FILE
31 # else
32 #  define _KERNEL
33 #  define       KERNEL
34 # endif
35 # include <sys/file.h>
36 # ifdef __FreeBSD__
37 #  undef _WANT_FILE
38 # else
39 #  undef  _KERNEL
40 #  undef  KERNEL
41 # endif
42 #include <nlist.h>
43 #include <sys/user.h>
44 #include <sys/socket.h>
45 #include <sys/socketvar.h>
46 #include <sys/proc.h>
47 # include <kvm.h>
48 #ifdef sun
49 #include <sys/systm.h>
50 #include <sys/session.h>
51 #endif
52 #include <sys/sysctl.h>
53 #include <sys/filedesc.h>
54 #include <paths.h>
55 #include <math.h>
56 #include <netinet/in.h>
57 #include <netinet/in_systm.h>
58 #include <netinet/ip.h>
59 #include <netinet/tcp.h>
60 #include <net/if.h>
61 # include <net/route.h>
62 #include <netinet/ip_var.h>
63 #define _WANT_INPCB
64 #include <netinet/in_pcb.h>
65 #include <netinet/tcp_timer.h>
66 #define _WANT_TCPCB
67 #include <netinet/tcp_var.h>
68 #include <stdio.h>
69 #include <unistd.h>
70 #include <string.h>
71 #include <stdlib.h>
72 #include <stddef.h>
73 #include <pwd.h>
74 #include "ipsend.h"
75
76
77 int     nproc;
78 struct  proc    *proc;
79
80 #ifndef KMEM
81 # ifdef _PATH_KMEM
82 #  define       KMEM    _PATH_KMEM
83 # endif
84 #endif
85 #ifndef KERNEL
86 # ifdef _PATH_UNIX
87 #  define       KERNEL  _PATH_UNIX
88 # endif
89 #endif
90 #ifndef KMEM
91 # define        KMEM    "/dev/kmem"
92 #endif
93 #ifndef KERNEL
94 # define        KERNEL  "/vmunix"
95 #endif
96
97
98 #if BSD < 199103
99 static  struct  proc    *getproc __P((void));
100 #else
101 static  struct  kinfo_proc      *getproc __P((void));
102 #endif
103
104
105 int     kmemcpy(buf, pos, n)
106         char    *buf;
107         void    *pos;
108         int     n;
109 {
110         static  int     kfd = -1;
111         off_t   offset = (u_long)pos;
112
113         if (kfd == -1)
114                 kfd = open(KMEM, O_RDONLY);
115
116         if (lseek(kfd, offset, SEEK_SET) == -1)
117             {
118                 perror("lseek");
119                 return -1;
120             }
121         if (read(kfd, buf, n) == -1)
122             {
123                 perror("read");
124                 return -1;
125             }
126         return n;
127 }
128
129 struct  nlist   names[4] = {
130         { "_proc" },
131         { "_nproc" },
132         { NULL },
133         { NULL }
134         };
135
136 static struct kinfo_proc *getproc()
137 {
138         static  struct  kinfo_proc kp;
139         pid_t   pid = getpid();
140         int     mib[4];
141         size_t  n;
142
143         mib[0] = CTL_KERN;
144         mib[1] = KERN_PROC;
145         mib[2] = KERN_PROC_PID;
146         mib[3] = pid;
147
148         n = sizeof(kp);
149         if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1)
150             {
151                 perror("sysctl");
152                 return NULL;
153             }
154         return &kp;
155 }
156
157
158 struct  tcpcb   *find_tcp(tfd, ti)
159         int     tfd;
160         struct  tcpiphdr *ti;
161 {
162         struct  tcpcb   *t;
163         struct  inpcb   *i;
164         struct  socket  *s;
165         struct  filedesc        *fd;
166         struct  kinfo_proc      *p;
167         struct  file    *f, **o;
168
169         if (!(p = getproc()))
170                 return NULL;
171
172         fd = (struct filedesc *)malloc(sizeof(*fd));
173         if (fd == NULL)
174                 return NULL;
175 #if defined( __FreeBSD_version)
176         if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1)
177             {
178                 fprintf(stderr, "read(%#lx,%#lx) failed\n",
179                         (u_long)p, (u_long)p->ki_fd);
180                 free(fd);
181                 return NULL;
182             }
183 #else
184         if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1)
185             {
186                 fprintf(stderr, "read(%#lx,%#lx) failed\n",
187                         (u_long)p, (u_long)p->kp_proc.p_fd);
188                 free(fd);
189                 return NULL;
190             }
191 #endif
192
193         o = NULL;
194         f = NULL;
195         s = NULL;
196         i = NULL;
197         t = NULL;
198
199         o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o));
200         if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
201             {
202                 fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
203                         (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o));
204                 goto finderror;
205             }
206         f = (struct file *)calloc(1, sizeof(*f));
207         if (KMCPY(f, o[tfd], sizeof(*f)) == -1)
208             {
209                 fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n",
210                         (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f));
211                 goto finderror;
212             }
213
214         s = (struct socket *)calloc(1, sizeof(*s));
215         if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
216             {
217                 fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n",
218                         (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s));
219                 goto finderror;
220             }
221
222         i = (struct inpcb *)calloc(1, sizeof(*i));
223         if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
224             {
225                 fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n",
226                         (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i));
227                 goto finderror;
228             }
229
230         t = (struct tcpcb *)calloc(1, sizeof(*t));
231         if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
232             {
233                 fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n",
234                         (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t));
235                 goto finderror;
236             }
237         return (struct tcpcb *)i->inp_ppcb;
238
239 finderror:
240         if (o != NULL)
241                 free(o);
242         if (f != NULL)
243                 free(f);
244         if (s != NULL)
245                 free(s);
246         if (i != NULL)
247                 free(i);
248         if (t != NULL)
249                 free(t);
250         return NULL;
251 }
252
253 int     do_socket(dev, mtu, ti, gwip)
254         char    *dev;
255         int     mtu;
256         struct  tcpiphdr *ti;
257         struct  in_addr gwip;
258 {
259         struct  sockaddr_in     rsin, lsin;
260         struct  tcpcb   *t, tcb;
261         int     fd, nfd;
262         socklen_t len;
263
264         printf("Dest. Port: %d\n", ti->ti_dport);
265
266         fd = socket(AF_INET, SOCK_STREAM, 0);
267         if (fd == -1)
268             {
269                 perror("socket");
270                 return -1;
271             }
272
273         if (fcntl(fd, F_SETFL, FNDELAY) == -1)
274             {
275                 perror("fcntl");
276                 return -1;
277             }
278
279         bzero((char *)&lsin, sizeof(lsin));
280         lsin.sin_family = AF_INET;
281         bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr,
282               sizeof(struct in_addr));
283         if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1)
284             {
285                 perror("bind");
286                 return -1;
287             }
288         len = sizeof(lsin);
289         (void) getsockname(fd, (struct sockaddr *)&lsin, &len);
290         ti->ti_sport = lsin.sin_port;
291         printf("sport %d\n", ntohs(lsin.sin_port));
292
293         nfd = initdevice(dev, 1);
294         if (nfd == -1)
295                 return -1;
296
297         if (!(t = find_tcp(fd, ti)))
298                 return -1;
299
300         bzero((char *)&rsin, sizeof(rsin));
301         rsin.sin_family = AF_INET;
302         bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr,
303               sizeof(struct in_addr));
304         rsin.sin_port = ti->ti_dport;
305         if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 &&
306             errno != EINPROGRESS)
307             {
308                 perror("connect");
309                 return -1;
310             }
311         KMCPY(&tcb, t, sizeof(tcb));
312         ti->ti_win = tcb.rcv_adv;
313         ti->ti_seq = tcb.snd_nxt - 1;
314         ti->ti_ack = tcb.rcv_nxt;
315
316         if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1)
317                 return -1;
318         (void)write(fd, "Hello World\n", 12);
319         sleep(2);
320         close(fd);
321         return 0;
322 }