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