1/* $FreeBSD$ */ 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$"; 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#include <sys/user.h> 43#include <sys/socket.h> 44#include <math.h> 45#include <netinet/in.h> 46#include <netinet/in_systm.h> 47#include <net/if.h> 48#if LINUX < 0200 49#include <net/inet/sock.h> 50#endif 51#include "ipsend.h" 52 53int nproc; 54struct task_struct *proc; 55 56#ifndef KMEM 57# ifdef _PATH_KMEM 58# define KMEM _PATH_KMEM 59# endif 60#endif 61#ifndef KMEM 62# define KMEM "/dev/kmem" 63#endif 64#ifndef KERNEL 65# define KERNEL "/System.map" 66#endif 67 68int kmemcpy(buf, pos, n) 69 char *buf; 70 void *pos; 71 int n; 72{ 73 static int kfd = -1; 74 75 if (kfd == -1) 76 kfd = open(KMEM, O_RDONLY); 77 78 if (lseek(kfd, (off_t)pos, SEEK_SET) == -1) 79 { 80 perror("lseek"); 81 return -1; 82 } 83 if (read(kfd, buf, n) == -1) 84 { 85 perror("read"); 86 return -1; 87 } 88 return n; 89} 90 91struct nlist names[3] = { 92 { "_task" }, 93 { "_nr_tasks" }, 94 { NULL } 95 }; 96 97struct task_struct *getproc() 98{ 99 struct task_struct *p, **pp; 100 void *v; 101 pid_t pid = getpid(); 102 int siz, n; 103 104 n = nlist(KERNEL, names); 105 if (n != 0) 106 { 107 fprintf(stderr, "nlist(%#x) == %d\n", names, n); 108 return NULL; 109 } 110 if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 111 { 112 fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 113 return NULL; 114 } 115 siz = nproc * sizeof(struct task_struct *); 116 if (KMCPY(&v, names[0].n_value, sizeof(v)) == -1) 117 { 118 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 119 names[0].n_value, &v, sizeof(v)); 120 return NULL; 121 } 122 pp = (struct task_struct **)malloc(siz); 123 if (KMCPY(pp, v, siz) == -1) 124 { 125 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 126 v, pp, siz); 127 return NULL; 128 } 129 proc = (struct task_struct *)malloc(siz); 130 for (n = 0; n < NR_TASKS; n++) 131 { 132 if (KMCPY((proc + n), pp[n], sizeof(*proc)) == -1) 133 { 134 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 135 pp[n], proc + n, sizeof(*proc)); 136 return NULL; 137 } 138 } 139 140 p = proc; 141 142 for (n = NR_TASKS; n; n--, p++) 143 if (p->pid == pid) 144 break; 145 if (!n) 146 return NULL; 147 148 return p; 149} 150 151 152struct sock *find_tcp(fd, ti) 153 int fd; 154 struct tcpiphdr *ti; 155{ 156 struct sock *s; 157 struct inode *i; 158 struct files_struct *fs; 159 struct task_struct *p; 160 struct file *f, **o; 161 162 if (!(p = getproc())) 163 return NULL; 164 165 fs = p->files; 166 o = (struct file **)calloc(1, sizeof(*o) * (fs->count + 1)); 167 if (KMCPY(o, fs->fd, (fs->count + 1) * sizeof(*o)) == -1) 168 { 169 fprintf(stderr, "read(%#x,%#x,%d) - fd - failed\n", 170 fs->fd, o, sizeof(*o)); 171 return NULL; 172 } 173 f = (struct file *)calloc(1, sizeof(*f)); 174 if (KMCPY(f, o[fd], sizeof(*f)) == -1) 175 { 176 fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 177 o[fd], f, sizeof(*f)); 178 return NULL; 179 } 180 181 i = (struct inode *)calloc(1, sizeof(*i)); 182 if (KMCPY(i, f->f_inode, sizeof(*i)) == -1) 183 { 184 fprintf(stderr, "read(%#x,%#x,%d) - f_inode - failed\n", 185 f->f_inode, i, sizeof(*i)); 186 return NULL; 187 } 188 return i->u.socket_i.data; 189} 190 191int do_socket(dev, mtu, ti, gwip) 192 char *dev; 193 int mtu; 194 struct tcpiphdr *ti; 195 struct in_addr gwip; 196{ 197 struct sockaddr_in rsin, lsin; 198 struct sock *s, sk; 199 int fd, nfd, len; 200 201 printf("Dest. Port: %d\n", ti->ti_dport); 202 203 fd = socket(AF_INET, SOCK_STREAM, 0); 204 if (fd == -1) 205 { 206 perror("socket"); 207 return -1; 208 } 209 210 if (fcntl(fd, F_SETFL, FNDELAY) == -1) 211 { 212 perror("fcntl"); 213 return -1; 214 } 215 216 bzero((char *)&lsin, sizeof(lsin)); 217 lsin.sin_family = AF_INET; 218 bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 219 sizeof(struct in_addr)); 220 if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 221 { 222 perror("bind"); 223 return -1; 224 } 225 len = sizeof(lsin); 226 (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 227 ti->ti_sport = lsin.sin_port; 228 printf("sport %d\n", ntohs(lsin.sin_port)); 229 nfd = initdevice(dev, 0); 230 if (nfd == -1) 231 return -1; 232 233 if (!(s = find_tcp(fd, ti))) 234 return -1; 235 236 bzero((char *)&rsin, sizeof(rsin)); 237 rsin.sin_family = AF_INET; 238 bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 239 sizeof(struct in_addr)); 240 rsin.sin_port = ti->ti_dport; 241 if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 242 errno != EINPROGRESS) 243 { 244 perror("connect"); 245 return -1; 246 } 247 KMCPY(&sk, s, sizeof(sk)); 248 ti->ti_win = sk.window; 249 ti->ti_seq = sk.sent_seq - 1; 250 ti->ti_ack = sk.rcv_ack_seq; 251 ti->ti_flags = TH_SYN; 252 253 if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 254 return -1; 255 (void)write(fd, "Hello World\n", 12); 256 sleep(2); 257 close(fd); 258 return 0; 259} 260