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