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