1/*	$NetBSD: lsock.c,v 1.3 2017/06/15 23:55:42 kamil Exp $	*/
2
3/*
4 * lsock.c (C) 1995-1998 Darren Reed
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 *
8 */
9#if !defined(lint)
10static const char sccsid[] = "@(#)lsock.c	1.2 1/11/96 (C)1995 Darren Reed";
11static const char rcsid[] = "@(#)Id: lsock.c,v 1.1.1.2 2012/07/22 13:44:37 darrenr Exp $";
12#endif
13#include <stdio.h>
14#include <unistd.h>
15#include <string.h>
16#include <stdlib.h>
17#include <stddef.h>
18#include <pwd.h>
19#include <sys/types.h>
20#include <sys/time.h>
21#include <sys/param.h>
22#include <sys/stat.h>
23#include <fcntl.h>
24#include <sys/dir.h>
25#define	__KERNEL__
26#if LINUX >= 0200
27# undef UINT_MAX
28# undef INT_MAX
29# undef ULONG_MAX
30# undef LONG_MAX
31# include <linux/notifier.h>
32#endif
33#include <linux/fs.h>
34#if LINUX >= 0200
35#include "linux/netdevice.h"
36#include "net/sock.h"
37#endif
38#undef	__KERNEL__
39#include <linux/sched.h>
40#include <linux/netdevice.h>
41#include <nlist.h>
42#if defined(__FreeBSD__)
43#include <sys/user.h>
44#endif
45#include <sys/socket.h>
46#include <math.h>
47#include <netinet/in.h>
48#include <netinet/in_systm.h>
49#include <net/if.h>
50#if LINUX < 0200
51#include <net/inet/sock.h>
52#endif
53#include "ipsend.h"
54
55int	nproc;
56struct	task_struct	*proc;
57
58#ifndef	KMEM
59# ifdef	_PATH_KMEM
60#  define	KMEM	_PATH_KMEM
61# endif
62#endif
63#ifndef	KMEM
64# define	KMEM	"/dev/kmem"
65#endif
66#ifndef	KERNEL
67# define	KERNEL	"/System.map"
68#endif
69
70int	kmemcpy(buf, pos, n)
71	char	*buf;
72	void	*pos;
73	int	n;
74{
75	static	int	kfd = -1;
76
77	if (kfd == -1)
78		kfd = open(KMEM, O_RDONLY);
79
80	if (lseek(kfd, (off_t)pos, SEEK_SET) == -1)
81	    {
82		perror("lseek");
83		return -1;
84	    }
85	if (read(kfd, buf, n) == -1)
86	    {
87		perror("read");
88		return -1;
89	    }
90	return n;
91}
92
93struct	nlist	names[3] = {
94	{ "_task" },
95	{ "_nr_tasks" },
96	{ NULL }
97	};
98
99struct	task_struct	*getproc()
100{
101	struct	task_struct	*p, **pp;
102	void	*v;
103	pid_t	pid = getpid();
104	int	siz, n;
105
106	n = nlist(KERNEL, names);
107	if (n != 0)
108	    {
109		fprintf(stderr, "nlist(%#x) == %d\n", names, n);
110		return NULL;
111	    }
112	if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1)
113	    {
114		fprintf(stderr, "read nproc (%#x)\n", names[1].n_value);
115		return NULL;
116	    }
117	siz = nproc * sizeof(struct task_struct *);
118	if (KMCPY(&v, names[0].n_value, sizeof(v)) == -1)
119	    {
120		fprintf(stderr, "read(%#x,%#x,%d) proc\n",
121			names[0].n_value, &v, sizeof(v));
122		return NULL;
123	    }
124	pp = (struct task_struct **)malloc(siz);
125	if (KMCPY(pp, v, siz) == -1)
126	    {
127		fprintf(stderr, "read(%#x,%#x,%d) proc\n",
128			v, pp, siz);
129		return NULL;
130	    }
131	proc = (struct task_struct *)malloc(siz);
132	for (n = 0; n < NR_TASKS; n++)
133	    {
134		if (KMCPY((proc + n), pp[n], sizeof(*proc)) == -1)
135		    {
136			fprintf(stderr, "read(%#x,%#x,%d) proc\n",
137				pp[n], proc + n, sizeof(*proc));
138			return NULL;
139		    }
140	    }
141
142	p = proc;
143
144	for (n = NR_TASKS; n; n--, p++)
145		if (p->pid == pid)
146			break;
147	if (!n)
148		return NULL;
149
150	return p;
151}
152
153
154struct	sock	*find_tcp(fd, ti)
155	int	fd;
156	struct	tcpiphdr *ti;
157{
158	struct	sock	*s;
159	struct	inode	*i;
160	struct	files_struct	*fs;
161	struct	task_struct	*p;
162	struct	file	*f, **o;
163
164	if (!(p = getproc()))
165		return NULL;
166
167	fs = p->files;
168	o = (struct file **)calloc(1, sizeof(*o) * (fs->count + 1));
169	if (KMCPY(o, fs->fd, (fs->count + 1) * sizeof(*o)) == -1)
170	    {
171		fprintf(stderr, "read(%#x,%#x,%d) - fd - failed\n",
172			fs->fd, o, sizeof(*o));
173		return NULL;
174	    }
175	f = (struct file *)calloc(1, sizeof(*f));
176	if (KMCPY(f, o[fd], sizeof(*f)) == -1)
177	    {
178		fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n",
179			o[fd], f, sizeof(*f));
180		return NULL;
181	    }
182
183	i = (struct inode *)calloc(1, sizeof(*i));
184	if (KMCPY(i, f->f_inode, sizeof(*i)) == -1)
185	    {
186		fprintf(stderr, "read(%#x,%#x,%d) - f_inode - failed\n",
187			f->f_inode, i, sizeof(*i));
188		return NULL;
189	    }
190	return i->u.socket_i.data;
191}
192
193int	do_socket(dev, mtu, ti, gwip)
194	char	*dev;
195	int	mtu;
196	struct	tcpiphdr *ti;
197	struct	in_addr	gwip;
198{
199	struct	sockaddr_in	rsin, lsin;
200	struct	sock	*s, sk;
201	int	fd, nfd, len;
202
203	printf("Dest. Port: %d\n", ti->ti_dport);
204
205	fd = socket(AF_INET, SOCK_STREAM, 0);
206	if (fd == -1)
207	    {
208		perror("socket");
209		return -1;
210	    }
211
212	if (fcntl(fd, F_SETFL, FNDELAY) == -1)
213	    {
214		perror("fcntl");
215		return -1;
216	    }
217
218	bzero((char *)&lsin, sizeof(lsin));
219	lsin.sin_family = AF_INET;
220	bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr,
221	      sizeof(struct in_addr));
222	if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1)
223	    {
224		perror("bind");
225		return -1;
226	    }
227	len = sizeof(lsin);
228	(void) getsockname(fd, (struct sockaddr *)&lsin, &len);
229	ti->ti_sport = lsin.sin_port;
230	printf("sport %d\n", ntohs(lsin.sin_port));
231	nfd = initdevice(dev, 0);
232	if (nfd == -1)
233		return -1;
234
235	if (!(s = find_tcp(fd, ti)))
236		return -1;
237
238	bzero((char *)&rsin, sizeof(rsin));
239	rsin.sin_family = AF_INET;
240	bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr,
241	      sizeof(struct in_addr));
242	rsin.sin_port = ti->ti_dport;
243	if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 &&
244	    errno != EINPROGRESS)
245	    {
246		perror("connect");
247		return -1;
248	    }
249	KMCPY(&sk, s, sizeof(sk));
250	ti->ti_win = sk.window;
251	ti->ti_seq = sk.sent_seq - 1;
252	ti->ti_ack = sk.rcv_ack_seq;
253	ti->ti_flags = TH_SYN;
254
255	if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1)
256		return -1;
257	(void)write(fd, "Hello World\n", 12);
258	sleep(2);
259	close(fd);
260	return 0;
261}
262