sock.c revision 369277
1/* $FreeBSD: stable/11/contrib/ipfilter/ipsend/sock.c 369277 2021-02-16 00:48:38Z cy $ */
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)
9static const char sccsid[] = "@(#)sock.c	1.2 1/11/96 (C)1995 Darren Reed";
10static 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 */
22typedef 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#include <sys/socketvar.h>
46#include <sys/proc.h>
47# include <kvm.h>
48#ifdef sun
49#include <sys/systm.h>
50#include <sys/session.h>
51#endif
52#include <sys/sysctl.h>
53#include <sys/filedesc.h>
54#include <paths.h>
55#include <math.h>
56#include <netinet/in.h>
57#include <netinet/in_systm.h>
58#include <netinet/ip.h>
59#include <netinet/tcp.h>
60#include <net/if.h>
61# include <net/route.h>
62#include <netinet/ip_var.h>
63#include <netinet/in_pcb.h>
64#include <netinet/tcp_timer.h>
65#include <netinet/tcp_var.h>
66#include <stdio.h>
67#include <unistd.h>
68#include <string.h>
69#include <stdlib.h>
70#include <stddef.h>
71#include <pwd.h>
72#include "ipsend.h"
73
74
75int	nproc;
76struct	proc	*proc;
77
78#ifndef	KMEM
79# ifdef	_PATH_KMEM
80#  define	KMEM	_PATH_KMEM
81# endif
82#endif
83#ifndef	KERNEL
84# ifdef	_PATH_UNIX
85#  define	KERNEL	_PATH_UNIX
86# endif
87#endif
88#ifndef	KMEM
89# define	KMEM	"/dev/kmem"
90#endif
91#ifndef	KERNEL
92# define	KERNEL	"/vmunix"
93#endif
94
95
96static	struct	kinfo_proc	*getproc(void);
97
98
99int	kmemcpy(buf, pos, n)
100	char	*buf;
101	void	*pos;
102	int	n;
103{
104	static	int	kfd = -1;
105	off_t	offset = (u_long)pos;
106
107	if (kfd == -1)
108		kfd = open(KMEM, O_RDONLY);
109
110	if (lseek(kfd, offset, SEEK_SET) == -1)
111	    {
112		perror("lseek");
113		return -1;
114	    }
115	if (read(kfd, buf, n) == -1)
116	    {
117		perror("read");
118		return -1;
119	    }
120	return n;
121}
122
123struct	nlist	names[4] = {
124	{ "_proc" },
125	{ "_nproc" },
126	{ NULL },
127	{ NULL }
128	};
129
130static struct kinfo_proc *getproc()
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
152struct	tcpcb	*find_tcp(tfd, ti)
153	int	tfd;
154	struct	tcpiphdr *ti;
155{
156	struct	tcpcb	*t;
157	struct	inpcb	*i;
158	struct	socket	*s;
159	struct	filedesc	*fd;
160	struct	kinfo_proc	*p;
161	struct	file	*f, **o;
162
163	if (!(p = getproc()))
164		return NULL;
165
166	fd = (struct filedesc *)malloc(sizeof(*fd));
167	if (fd == NULL)
168		return NULL;
169#if defined( __FreeBSD__)
170	if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1)
171	    {
172		fprintf(stderr, "read(%#lx,%#lx) failed\n",
173			(u_long)p, (u_long)p->ki_fd);
174		free(fd);
175		return NULL;
176	    }
177#else
178	if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1)
179	    {
180		fprintf(stderr, "read(%#lx,%#lx) failed\n",
181			(u_long)p, (u_long)p->kp_proc.p_fd);
182		free(fd);
183		return NULL;
184	    }
185#endif
186
187	o = NULL;
188	f = NULL;
189	s = NULL;
190	i = NULL;
191	t = NULL;
192
193	o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o));
194	if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
195	    {
196		fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
197			(u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o));
198		goto finderror;
199	    }
200	f = (struct file *)calloc(1, sizeof(*f));
201	if (KMCPY(f, o[tfd], sizeof(*f)) == -1)
202	    {
203		fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n",
204			(u_long)o[tfd], (u_long)f, (u_long)sizeof(*f));
205		goto finderror;
206	    }
207
208	s = (struct socket *)calloc(1, sizeof(*s));
209	if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
210	    {
211		fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n",
212			(u_long)f->f_data, (u_long)s, (u_long)sizeof(*s));
213		goto finderror;
214	    }
215
216	i = (struct inpcb *)calloc(1, sizeof(*i));
217	if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
218	    {
219		fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n",
220			(u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i));
221		goto finderror;
222	    }
223
224	t = (struct tcpcb *)calloc(1, sizeof(*t));
225	if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
226	    {
227		fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n",
228			(u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t));
229		goto finderror;
230	    }
231	return (struct tcpcb *)i->inp_ppcb;
232
233finderror:
234	if (o != NULL)
235		free(o);
236	if (f != NULL)
237		free(f);
238	if (s != NULL)
239		free(s);
240	if (i != NULL)
241		free(i);
242	if (t != NULL)
243		free(t);
244	return NULL;
245}
246
247int	do_socket(dev, mtu, ti, gwip)
248	char	*dev;
249	int	mtu;
250	struct	tcpiphdr *ti;
251	struct	in_addr	gwip;
252{
253	struct	sockaddr_in	rsin, lsin;
254	struct	tcpcb	*t, tcb;
255	int	fd, nfd;
256	socklen_t len;
257
258	printf("Dest. Port: %d\n", ti->ti_dport);
259
260	fd = socket(AF_INET, SOCK_STREAM, 0);
261	if (fd == -1)
262	    {
263		perror("socket");
264		return -1;
265	    }
266
267	if (fcntl(fd, F_SETFL, FNDELAY) == -1)
268	    {
269		perror("fcntl");
270		return -1;
271	    }
272
273	bzero((char *)&lsin, sizeof(lsin));
274	lsin.sin_family = AF_INET;
275	bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr,
276	      sizeof(struct in_addr));
277	if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1)
278	    {
279		perror("bind");
280		return -1;
281	    }
282	len = sizeof(lsin);
283	(void) getsockname(fd, (struct sockaddr *)&lsin, &len);
284	ti->ti_sport = lsin.sin_port;
285	printf("sport %d\n", ntohs(lsin.sin_port));
286
287	nfd = initdevice(dev, 1);
288	if (nfd == -1)
289		return -1;
290
291	if (!(t = find_tcp(fd, ti)))
292		return -1;
293
294	bzero((char *)&rsin, sizeof(rsin));
295	rsin.sin_family = AF_INET;
296	bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr,
297	      sizeof(struct in_addr));
298	rsin.sin_port = ti->ti_dport;
299	if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 &&
300	    errno != EINPROGRESS)
301	    {
302		perror("connect");
303		return -1;
304	    }
305	KMCPY(&tcb, t, sizeof(tcb));
306	ti->ti_win = tcb.rcv_adv;
307	ti->ti_seq = tcb.snd_nxt - 1;
308	ti->ti_ack = tcb.rcv_nxt;
309
310	if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1)
311		return -1;
312	(void)write(fd, "Hello World\n", 12);
313	sleep(2);
314	close(fd);
315	return 0;
316}
317