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