lsock.c revision 53024
1/* 2 * lsock.c (C) 1995-1998 Darren Reed 3 * 4 * Redistribution and use in source and binary forms are permitted 5 * provided that this notice is preserved and due credit is given 6 * to the original author and the contributors. 7 */ 8#if !defined(lint) 9static const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed"; 10static const char rcsid[] = "@(#)$Id: lsock.c,v 2.1 1999/08/04 17:31:11 darrenr Exp $"; 11#endif 12#include <stdio.h> 13#include <unistd.h> 14#include <string.h> 15#include <stdlib.h> 16#include <stddef.h> 17#include <pwd.h> 18#include <sys/types.h> 19#include <sys/time.h> 20#include <sys/param.h> 21#include <sys/stat.h> 22#include <fcntl.h> 23#include <sys/dir.h> 24#define __KERNEL__ 25#if LINUX >= 0200 26# undef UINT_MAX 27# undef INT_MAX 28# undef ULONG_MAX 29# undef LONG_MAX 30# include <linux/notifier.h> 31#endif 32#include <linux/fs.h> 33#if LINUX >= 0200 34#include "linux/netdevice.h" 35#include "net/sock.h" 36#endif 37#undef __KERNEL__ 38#include <linux/sched.h> 39#include <linux/netdevice.h> 40#include <nlist.h> 41#include <sys/user.h> 42#include <sys/socket.h> 43#include <math.h> 44#include <netinet/in.h> 45#include <netinet/in_systm.h> 46#include <net/if.h> 47#if LINUX < 0200 48#include <net/inet/sock.h> 49#endif 50#include "ipsend.h" 51 52int nproc; 53struct task_struct *proc; 54 55#ifndef KMEM 56# ifdef _PATH_KMEM 57# define KMEM _PATH_KMEM 58# endif 59#endif 60#ifndef KMEM 61# define KMEM "/dev/kmem" 62#endif 63#ifndef KERNEL 64# define KERNEL "/System.map" 65#endif 66 67int kmemcpy(buf, pos, n) 68char *buf; 69void *pos; 70int n; 71{ 72 static int kfd = -1; 73 74 if (kfd == -1) 75 kfd = open(KMEM, O_RDONLY); 76 77 if (lseek(kfd, (off_t)pos, SEEK_SET) == -1) 78 { 79 perror("lseek"); 80 return -1; 81 } 82 if (read(kfd, buf, n) == -1) 83 { 84 perror("read"); 85 return -1; 86 } 87 return n; 88} 89 90struct nlist names[3] = { 91 { "_task" }, 92 { "_nr_tasks" }, 93 { NULL } 94 }; 95 96struct task_struct *getproc() 97{ 98 struct task_struct *p, **pp; 99 void *v; 100 pid_t pid = getpid(); 101 int siz, n; 102 103 n = nlist(KERNEL, names); 104 if (n != 0) 105 { 106 fprintf(stderr, "nlist(%#x) == %d\n", names, n); 107 return NULL; 108 } 109 if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 110 { 111 fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 112 return NULL; 113 } 114 siz = nproc * sizeof(struct task_struct *); 115 if (KMCPY(&v, names[0].n_value, sizeof(v)) == -1) 116 { 117 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 118 names[0].n_value, &v, sizeof(v)); 119 return NULL; 120 } 121 pp = (struct task_struct **)malloc(siz); 122 if (KMCPY(pp, v, siz) == -1) 123 { 124 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 125 v, pp, siz); 126 return NULL; 127 } 128 proc = (struct task_struct *)malloc(siz); 129 for (n = 0; n < NR_TASKS; n++) 130 { 131 if (KMCPY((proc + n), pp[n], sizeof(*proc)) == -1) 132 { 133 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 134 pp[n], proc + n, sizeof(*proc)); 135 return NULL; 136 } 137 } 138 139 p = proc; 140 141 for (n = NR_TASKS; n; n--, p++) 142 if (p->pid == pid) 143 break; 144 if (!n) 145 return NULL; 146 147 return p; 148} 149 150 151struct sock *find_tcp(fd, ti) 152int fd; 153struct tcpiphdr *ti; 154{ 155 struct sock *s; 156 struct inode *i; 157 struct files_struct *fs; 158 struct task_struct *p; 159 struct file *f, **o; 160 161 if (!(p = getproc())) 162 return NULL; 163 164 fs = p->files; 165 o = (struct file **)calloc(1, sizeof(*o) * (fs->count + 1)); 166 if (KMCPY(o, fs->fd, (fs->count + 1) * sizeof(*o)) == -1) 167 { 168 fprintf(stderr, "read(%#x,%#x,%d) - fd - failed\n", 169 fs->fd, o, sizeof(*o)); 170 return NULL; 171 } 172 f = (struct file *)calloc(1, sizeof(*f)); 173 if (KMCPY(f, o[fd], sizeof(*f)) == -1) 174 { 175 fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 176 o[fd], f, sizeof(*f)); 177 return NULL; 178 } 179 180 i = (struct inode *)calloc(1, sizeof(*i)); 181 if (KMCPY(i, f->f_inode, sizeof(*i)) == -1) 182 { 183 fprintf(stderr, "read(%#x,%#x,%d) - f_inode - failed\n", 184 f->f_inode, i, sizeof(*i)); 185 return NULL; 186 } 187 return i->u.socket_i.data; 188} 189 190int do_socket(dev, mtu, ti, gwip) 191char *dev; 192int mtu; 193struct tcpiphdr *ti; 194struct in_addr gwip; 195{ 196 struct sockaddr_in rsin, lsin; 197 struct sock *s, sk; 198 int fd, nfd, len; 199 200 printf("Dest. Port: %d\n", ti->ti_dport); 201 202 fd = socket(AF_INET, SOCK_STREAM, 0); 203 if (fd == -1) 204 { 205 perror("socket"); 206 return -1; 207 } 208 209 if (fcntl(fd, F_SETFL, FNDELAY) == -1) 210 { 211 perror("fcntl"); 212 return -1; 213 } 214 215 bzero((char *)&lsin, sizeof(lsin)); 216 lsin.sin_family = AF_INET; 217 bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 218 sizeof(struct in_addr)); 219 if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 220 { 221 perror("bind"); 222 return -1; 223 } 224 len = sizeof(lsin); 225 (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 226 ti->ti_sport = lsin.sin_port; 227 printf("sport %d\n", ntohs(lsin.sin_port)); 228 nfd = initdevice(dev, ntohs(lsin.sin_port), 0); 229 230 if (!(s = find_tcp(fd, ti))) 231 return -1; 232 233 bzero((char *)&rsin, sizeof(rsin)); 234 rsin.sin_family = AF_INET; 235 bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 236 sizeof(struct in_addr)); 237 rsin.sin_port = ti->ti_dport; 238 if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 239 errno != EINPROGRESS) 240 { 241 perror("connect"); 242 return -1; 243 } 244 KMCPY(&sk, s, sizeof(sk)); 245 ti->ti_win = sk.window; 246 ti->ti_seq = sk.sent_seq - 1; 247 ti->ti_ack = sk.rcv_ack_seq; 248 ti->ti_flags = TH_SYN; 249 250 if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 251 return -1; 252 (void)write(fd, "Hello World\n", 12); 253 sleep(2); 254 close(fd); 255 return 0; 256} 257