xref: /freebsd-13-stable/sbin/ipf/ipsend/sock.c (revision 8ad303d68cec3ee1133550de37e0009502621e50)
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