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