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