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