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