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