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