xref: /netbsd-src/external/bsd/ipf/dist/ipsend/lsock.c (revision 5e046308b479219d87a0474afbef6978b9e1177b)
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)
10 static const char sccsid[] = "@(#)lsock.c	1.2 1/11/96 (C)1995 Darren Reed";
11 static 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 
55 int	nproc;
56 struct	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 
kmemcpy(buf,pos,n)70 int	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 
93 struct	nlist	names[3] = {
94 	{ "_task" },
95 	{ "_nr_tasks" },
96 	{ NULL }
97 	};
98 
getproc()99 struct	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 
find_tcp(fd,ti)154 struct	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 
do_socket(dev,mtu,ti,gwip)193 int	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