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