sock.c revision 22514
1/* 2 * sock.c (C) 1995 Darren Reed 3 * 4 * The author provides this program as-is, with no gaurantee for its 5 * suitability for any specific purpose. The author takes no responsibility 6 * for the misuse/abuse of this program and provides it for the sole purpose 7 * of testing packet filter policies. This file maybe distributed freely 8 * providing it is not modified and that this notice remains in tact. 9 */ 10#if !defined(lint) && defined(LIBC_SCCS) 11static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 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#define KERNEL 27#include <sys/file.h> 28#undef _KERNEL 29#undef KERNEL 30#include <nlist.h> 31#include <sys/user.h> 32#include <sys/socket.h> 33#include <sys/socketvar.h> 34#include <sys/proc.h> 35#include <kvm.h> 36#ifdef sun 37#include <sys/systm.h> 38#include <sys/session.h> 39#endif 40#if BSD >= 199103 41#include <sys/sysctl.h> 42#include <sys/filedesc.h> 43#include <paths.h> 44#endif 45#include <math.h> 46#include <netinet/in.h> 47#include <netinet/in_systm.h> 48#include <netinet/ip.h> 49#include <netinet/tcp.h> 50#include <net/if.h> 51#include <net/route.h> 52#include <netinet/ip_var.h> 53#include <netinet/in_pcb.h> 54#include <netinet/tcp_timer.h> 55#include <netinet/tcp_var.h> 56#include <netinet/tcpip.h> 57 58int nproc; 59struct proc *proc; 60 61extern int initdevice(), send_tcp(); 62 63#ifndef KMEM 64# ifdef _PATH_KMEM 65# define KMEM _PATH_KMEM 66# endif 67#endif 68#ifndef KERNEL 69# ifdef _PATH_UNIX 70# define KERNEL _PATH_UNIX 71# endif 72#endif 73#ifndef KMEM 74# define KMEM "/dev/kmem" 75#endif 76#ifndef KERNEL 77# define KERNEL "/vmunix" 78#endif 79 80int kmemcpy(buf, pos, n) 81char *buf; 82off_t pos; 83int n; 84{ 85 static int kfd = -1; 86 87 if (kfd == -1) 88 kfd = open(KMEM, O_RDONLY); 89 90 if (lseek(kfd, pos, SEEK_SET) == -1) 91 { 92 perror("lseek"); 93 return -1; 94 } 95 if (read(kfd, buf, n) == -1) 96 { 97 perror("read"); 98 return -1; 99 } 100 return n; 101} 102 103struct nlist names[3] = { 104 { "_proc" }, 105 { "_nproc" }, 106 { NULL } 107 }; 108 109#if BSD < 199103 110struct proc *getproc() 111{ 112 struct proc *p; 113 pid_t pid = getpid(); 114 int siz, n; 115 116 n = nlist(KERNEL, names); 117 if (n != 0) 118 { 119 fprintf(stderr, "nlist(%#x) == %d\n", names, n); 120 return NULL; 121 } 122 if (kmemcpy((char *)&nproc, (off_t)names[1].n_value, 123 sizeof(nproc)) == -1) 124 { 125 fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 126 return NULL; 127 } 128 siz = nproc * sizeof(struct proc); 129 if (kmemcpy((char *)&p, (off_t)names[0].n_value, sizeof(p)) == -1) 130 { 131 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 132 names[0].n_value, &p, sizeof(p)); 133 return NULL; 134 } 135 proc = (struct proc *)malloc(siz); 136 if (kmemcpy((char *)proc, (off_t)p, siz) == -1) 137 { 138 fprintf(stderr, "read(%#x,%#x,%d) proc\n", 139 p, proc, siz); 140 return NULL; 141 } 142 143 p = proc; 144 145 for (n = nproc; n; n--, p++) 146 if (p->p_pid == pid) 147 break; 148 if (!n) 149 return NULL; 150 151 return p; 152} 153 154 155struct tcpcb *find_tcp(fd, ti) 156int fd; 157struct tcpiphdr *ti; 158{ 159 struct tcpcb *t; 160 struct inpcb *i; 161 struct socket *s; 162 struct user *up; 163 struct proc *p; 164 struct file *f, **o; 165 166 if (!(p = getproc())) 167 return NULL; 168 169 up = (struct user *)malloc(sizeof(*up)); 170 if (kmemcpy((char *)up, (off_t)p->p_uarea, sizeof(*up)) == -1) 171 { 172 fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea); 173 return NULL; 174 } 175 176 o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1)); 177 if (kmemcpy((char *)o, (off_t)up->u_ofile, 178 (up->u_lastfile + 1) * sizeof(*o)) == -1) 179 { 180 fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n", 181 up->u_ofile_arr, o, sizeof(*o)); 182 return NULL; 183 } 184 f = (struct file *)calloc(1, sizeof(*f)); 185 if (kmemcpy((char *)f, (off_t)o[fd], sizeof(*f)) == -1) 186 { 187 fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 188 up->u_ofile_arr[fd], f, sizeof(*f)); 189 return NULL; 190 } 191 192 s = (struct socket *)calloc(1, sizeof(*s)); 193 if (kmemcpy((char *)s, (off_t)f->f_data, sizeof(*s)) == -1) 194 { 195 fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n", 196 o[fd], s, sizeof(*s)); 197 return NULL; 198 } 199 200 i = (struct inpcb *)calloc(1, sizeof(*i)); 201 if (kmemcpy((char *)i, (off_t)s->so_pcb, sizeof(*i)) == -1) 202 { 203 fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n", 204 s->so_pcb, i, sizeof(*i)); 205 return NULL; 206 } 207 208 t = (struct tcpcb *)calloc(1, sizeof(*t)); 209 if (kmemcpy((char *)t, (off_t)i->inp_ppcb, sizeof(*t)) == -1) 210 { 211 fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n", 212 i->inp_ppcb, t, sizeof(*t)); 213 return NULL; 214 } 215 return (struct tcpcb *)i->inp_ppcb; 216} 217#else 218struct kinfo_proc *getproc() 219{ 220 static struct kinfo_proc kp; 221 pid_t pid = getpid(); 222 int n, mib[4]; 223 224 mib[0] = CTL_KERN; 225 mib[1] = KERN_PROC; 226 mib[2] = KERN_PROC_PID; 227 mib[3] = pid; 228 229 n = 1; 230 if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 231 { 232 perror("sysctl"); 233 return NULL; 234 } 235 return &kp; 236} 237 238 239struct tcpcb *find_tcp(tfd, ti) 240int tfd; 241struct tcpiphdr *ti; 242{ 243 struct tcpcb *t; 244 struct inpcb *i; 245 struct socket *s; 246 struct filedesc *fd; 247 struct kinfo_proc *p; 248 struct file *f, **o; 249 250 if (!(p = getproc())) 251 return NULL; 252 253 fd = (struct filedesc *)malloc(sizeof(*fd)); 254 if (kmemcpy((char *)fd, (void *)p->kp_proc.p_fd, sizeof(*fd)) == -1) 255 { 256 fprintf(stderr, "read(%#lx,%#lx) failed\n", 257 (u_long)p, (u_long)p->kp_proc.p_fd); 258 return NULL; 259 } 260 261 o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1)); 262 if (kmemcpy((char *)o, (void *)fd->fd_ofiles, 263 (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 264 { 265 fprintf(stderr, "read(%#lx,%#lx,%d) - u_ofile - failed\n", 266 (u_long)fd->fd_ofiles, (u_long)o, sizeof(*o)); 267 return NULL; 268 } 269 f = (struct file *)calloc(1, sizeof(*f)); 270 if (kmemcpy((char *)f, (void *)o[tfd], sizeof(*f)) == -1) 271 { 272 fprintf(stderr, "read(%#lx,%#lx,%d) - o[tfd] - failed\n", 273 (u_long)o[tfd], (u_long)f, sizeof(*f)); 274 return NULL; 275 } 276 277 s = (struct socket *)calloc(1, sizeof(*s)); 278 if (kmemcpy((char *)s, (void *)f->f_data, sizeof(*s)) == -1) 279 { 280 fprintf(stderr, "read(%#lx,%#lx,%d) - f_data - failed\n", 281 (u_long)f->f_data, (u_long)s, sizeof(*s)); 282 return NULL; 283 } 284 285 i = (struct inpcb *)calloc(1, sizeof(*i)); 286 if (kmemcpy((char *)i, (void *)s->so_pcb, sizeof(*i)) == -1) 287 { 288 fprintf(stderr, "kvm_read(%#lx,%#lx,%d) - so_pcb - failed\n", 289 (u_long)s->so_pcb, (u_long)i, sizeof(*i)); 290 return NULL; 291 } 292 293 t = (struct tcpcb *)calloc(1, sizeof(*t)); 294 if (kmemcpy((char *)t, (void *)i->inp_ppcb, sizeof(*t)) == -1) 295 { 296 fprintf(stderr, "read(%#lx,%#lx,%d) - inp_ppcb - failed\n", 297 (u_long)i->inp_ppcb, (u_long)t, sizeof(*t)); 298 return NULL; 299 } 300 return (struct tcpcb *)i->inp_ppcb; 301} 302#endif /* BSD < 199301 */ 303 304int do_socket(dev, mtu, ti, gwip, flags) 305char *dev; 306int mtu; 307struct tcpiphdr *ti; 308struct in_addr gwip; 309int flags; 310{ 311 struct sockaddr_in rsin, lsin; 312 struct tcpcb *t, tcb; 313 int fd, nfd, len; 314 315 printf("Dest. Port: %d\n", ti->ti_dport); 316 317 fd = socket(AF_INET, SOCK_STREAM, 0); 318 if (fd == -1) 319 { 320 perror("socket"); 321 return -1; 322 } 323 324 if (fcntl(fd, F_SETFL, FNDELAY) == -1) 325 { 326 perror("fcntl"); 327 return -1; 328 } 329 330 bzero((char *)&lsin, sizeof(lsin)); 331 lsin.sin_family = AF_INET; 332 bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 333 sizeof(struct in_addr)); 334 if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 335 { 336 perror("bind"); 337 return -1; 338 } 339 len = sizeof(lsin); 340 (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 341 ti->ti_sport = lsin.sin_port; 342 printf("sport %d\n", ntohs(lsin.sin_port)); 343 nfd = initdevice(dev, ntohs(lsin.sin_port)); 344 345 if (!(t = find_tcp(fd, ti))) 346 return -1; 347 348 bzero((char *)&rsin, sizeof(rsin)); 349 rsin.sin_family = AF_INET; 350 bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 351 sizeof(struct in_addr)); 352 rsin.sin_port = ti->ti_dport; 353 if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 354 errno != EINPROGRESS) 355 { 356 perror("connect"); 357 return -1; 358 } 359 kmemcpy((char*)&tcb, (void *)t, sizeof(tcb)); 360 ti->ti_win = tcb.rcv_adv; 361 ti->ti_seq = tcb.snd_nxt - 1; 362 ti->ti_ack = tcb.rcv_nxt; 363 364 if (send_tcp(nfd, mtu, ti, gwip, TH_SYN) == -1) 365 return -1; 366 (void)write(fd, "Hello World\n", 12); 367 sleep(2); 368 close(fd); 369 return 0; 370} 371