sock.c revision 24583
122514Sdarrenr/* 222514Sdarrenr * sock.c (C) 1995 Darren Reed 322514Sdarrenr * 422514Sdarrenr * The author provides this program as-is, with no gaurantee for its 522514Sdarrenr * suitability for any specific purpose. The author takes no responsibility 622514Sdarrenr * for the misuse/abuse of this program and provides it for the sole purpose 722514Sdarrenr * of testing packet filter policies. This file maybe distributed freely 822514Sdarrenr * providing it is not modified and that this notice remains in tact. 922514Sdarrenr */ 1022514Sdarrenr#if !defined(lint) && defined(LIBC_SCCS) 1122514Sdarrenrstatic char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 1222514Sdarrenr#endif 1322514Sdarrenr#include <stdio.h> 1422514Sdarrenr#include <unistd.h> 1522514Sdarrenr#include <string.h> 1622514Sdarrenr#include <stdlib.h> 1722514Sdarrenr#include <stddef.h> 1822514Sdarrenr#include <pwd.h> 1922514Sdarrenr#include <sys/types.h> 2022514Sdarrenr#include <sys/time.h> 2122514Sdarrenr#include <sys/param.h> 2222514Sdarrenr#include <sys/stat.h> 2322514Sdarrenr#include <fcntl.h> 2422514Sdarrenr#include <sys/dir.h> 2522514Sdarrenr#define _KERNEL 2622514Sdarrenr#define KERNEL 2722514Sdarrenr#include <sys/file.h> 2822514Sdarrenr#undef _KERNEL 2922514Sdarrenr#undef KERNEL 3022514Sdarrenr#include <nlist.h> 3122514Sdarrenr#include <sys/user.h> 3222514Sdarrenr#include <sys/socket.h> 3322514Sdarrenr#include <sys/socketvar.h> 3422514Sdarrenr#include <sys/proc.h> 3522514Sdarrenr#include <kvm.h> 3622514Sdarrenr#ifdef sun 3722514Sdarrenr#include <sys/systm.h> 3822514Sdarrenr#include <sys/session.h> 3922514Sdarrenr#endif 4022514Sdarrenr#if BSD >= 199103 4122514Sdarrenr#include <sys/sysctl.h> 4222514Sdarrenr#include <sys/filedesc.h> 4322514Sdarrenr#include <paths.h> 4422514Sdarrenr#endif 4522514Sdarrenr#include <math.h> 4622514Sdarrenr#include <netinet/in.h> 4722514Sdarrenr#include <netinet/in_systm.h> 4822514Sdarrenr#include <netinet/ip.h> 4922514Sdarrenr#include <netinet/tcp.h> 5022514Sdarrenr#include <net/if.h> 5122514Sdarrenr#include <net/route.h> 5222514Sdarrenr#include <netinet/ip_var.h> 5322514Sdarrenr#include <netinet/in_pcb.h> 5422514Sdarrenr#include <netinet/tcp_timer.h> 5522514Sdarrenr#include <netinet/tcp_var.h> 5624583Sdarrenr#include "ipsend.h" 5722514Sdarrenr 5822514Sdarrenrint nproc; 5922514Sdarrenrstruct proc *proc; 6022514Sdarrenr 6122514Sdarrenr#ifndef KMEM 6222514Sdarrenr# ifdef _PATH_KMEM 6322514Sdarrenr# define KMEM _PATH_KMEM 6422514Sdarrenr# endif 6522514Sdarrenr#endif 6622514Sdarrenr#ifndef KERNEL 6722514Sdarrenr# ifdef _PATH_UNIX 6822514Sdarrenr# define KERNEL _PATH_UNIX 6922514Sdarrenr# endif 7022514Sdarrenr#endif 7122514Sdarrenr#ifndef KMEM 7222514Sdarrenr# define KMEM "/dev/kmem" 7322514Sdarrenr#endif 7422514Sdarrenr#ifndef KERNEL 7522514Sdarrenr# define KERNEL "/vmunix" 7622514Sdarrenr#endif 7722514Sdarrenr 7824583Sdarrenr 7924583Sdarrenr#if BSD < 199103 8024583Sdarrenrstatic struct proc *getproc __P((void)); 8124583Sdarrenr#else 8224583Sdarrenrstatic struct kinfo_proc *getproc __P((void)); 8324583Sdarrenr#endif 8424583Sdarrenr 8524583Sdarrenr 8622514Sdarrenrint kmemcpy(buf, pos, n) 8722514Sdarrenrchar *buf; 8824583Sdarrenrvoid *pos; 8922514Sdarrenrint n; 9022514Sdarrenr{ 9122514Sdarrenr static int kfd = -1; 9222514Sdarrenr 9322514Sdarrenr if (kfd == -1) 9422514Sdarrenr kfd = open(KMEM, O_RDONLY); 9522514Sdarrenr 9624583Sdarrenr if (lseek(kfd, (off_t)pos, SEEK_SET) == -1) 9722514Sdarrenr { 9822514Sdarrenr perror("lseek"); 9922514Sdarrenr return -1; 10022514Sdarrenr } 10122514Sdarrenr if (read(kfd, buf, n) == -1) 10222514Sdarrenr { 10322514Sdarrenr perror("read"); 10422514Sdarrenr return -1; 10522514Sdarrenr } 10622514Sdarrenr return n; 10722514Sdarrenr} 10822514Sdarrenr 10922514Sdarrenrstruct nlist names[3] = { 11022514Sdarrenr { "_proc" }, 11122514Sdarrenr { "_nproc" }, 11222514Sdarrenr { NULL } 11322514Sdarrenr }; 11422514Sdarrenr 11522514Sdarrenr#if BSD < 199103 11624583Sdarrenrstatic struct proc *getproc() 11722514Sdarrenr{ 11822514Sdarrenr struct proc *p; 11922514Sdarrenr pid_t pid = getpid(); 12022514Sdarrenr int siz, n; 12122514Sdarrenr 12222514Sdarrenr n = nlist(KERNEL, names); 12322514Sdarrenr if (n != 0) 12422514Sdarrenr { 12522514Sdarrenr fprintf(stderr, "nlist(%#x) == %d\n", names, n); 12622514Sdarrenr return NULL; 12722514Sdarrenr } 12824583Sdarrenr if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 12922514Sdarrenr { 13022514Sdarrenr fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 13122514Sdarrenr return NULL; 13222514Sdarrenr } 13322514Sdarrenr siz = nproc * sizeof(struct proc); 13424583Sdarrenr if (KMCPY(&p, names[0].n_value, sizeof(p)) == -1) 13522514Sdarrenr { 13622514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 13722514Sdarrenr names[0].n_value, &p, sizeof(p)); 13822514Sdarrenr return NULL; 13922514Sdarrenr } 14022514Sdarrenr proc = (struct proc *)malloc(siz); 14124583Sdarrenr if (KMCPY(proc, p, siz) == -1) 14222514Sdarrenr { 14322514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 14422514Sdarrenr p, proc, siz); 14522514Sdarrenr return NULL; 14622514Sdarrenr } 14722514Sdarrenr 14822514Sdarrenr p = proc; 14922514Sdarrenr 15022514Sdarrenr for (n = nproc; n; n--, p++) 15122514Sdarrenr if (p->p_pid == pid) 15222514Sdarrenr break; 15322514Sdarrenr if (!n) 15422514Sdarrenr return NULL; 15522514Sdarrenr 15622514Sdarrenr return p; 15722514Sdarrenr} 15822514Sdarrenr 15922514Sdarrenr 16022514Sdarrenrstruct tcpcb *find_tcp(fd, ti) 16122514Sdarrenrint fd; 16222514Sdarrenrstruct tcpiphdr *ti; 16322514Sdarrenr{ 16422514Sdarrenr struct tcpcb *t; 16522514Sdarrenr struct inpcb *i; 16622514Sdarrenr struct socket *s; 16722514Sdarrenr struct user *up; 16822514Sdarrenr struct proc *p; 16922514Sdarrenr struct file *f, **o; 17022514Sdarrenr 17122514Sdarrenr if (!(p = getproc())) 17222514Sdarrenr return NULL; 17322514Sdarrenr 17422514Sdarrenr up = (struct user *)malloc(sizeof(*up)); 17524583Sdarrenr if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1) 17622514Sdarrenr { 17722514Sdarrenr fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea); 17822514Sdarrenr return NULL; 17922514Sdarrenr } 18022514Sdarrenr 18122514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1)); 18224583Sdarrenr if (KMCPY(o, up->u_ofile, (up->u_lastfile + 1) * sizeof(*o)) == -1) 18322514Sdarrenr { 18422514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n", 18522514Sdarrenr up->u_ofile_arr, o, sizeof(*o)); 18622514Sdarrenr return NULL; 18722514Sdarrenr } 18822514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 18924583Sdarrenr if (KMCPY(f, o[fd], sizeof(*f)) == -1) 19022514Sdarrenr { 19122514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 19222514Sdarrenr up->u_ofile_arr[fd], f, sizeof(*f)); 19322514Sdarrenr return NULL; 19422514Sdarrenr } 19522514Sdarrenr 19622514Sdarrenr s = (struct socket *)calloc(1, sizeof(*s)); 19724583Sdarrenr if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 19822514Sdarrenr { 19922514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n", 20022514Sdarrenr o[fd], s, sizeof(*s)); 20122514Sdarrenr return NULL; 20222514Sdarrenr } 20322514Sdarrenr 20422514Sdarrenr i = (struct inpcb *)calloc(1, sizeof(*i)); 20524583Sdarrenr if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 20622514Sdarrenr { 20722514Sdarrenr fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n", 20822514Sdarrenr s->so_pcb, i, sizeof(*i)); 20922514Sdarrenr return NULL; 21022514Sdarrenr } 21122514Sdarrenr 21222514Sdarrenr t = (struct tcpcb *)calloc(1, sizeof(*t)); 21324583Sdarrenr if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 21422514Sdarrenr { 21522514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n", 21622514Sdarrenr i->inp_ppcb, t, sizeof(*t)); 21722514Sdarrenr return NULL; 21822514Sdarrenr } 21922514Sdarrenr return (struct tcpcb *)i->inp_ppcb; 22022514Sdarrenr} 22122514Sdarrenr#else 22224583Sdarrenrstatic struct kinfo_proc *getproc() 22322514Sdarrenr{ 22422514Sdarrenr static struct kinfo_proc kp; 22522514Sdarrenr pid_t pid = getpid(); 22622514Sdarrenr int n, mib[4]; 22722514Sdarrenr 22822514Sdarrenr mib[0] = CTL_KERN; 22922514Sdarrenr mib[1] = KERN_PROC; 23022514Sdarrenr mib[2] = KERN_PROC_PID; 23122514Sdarrenr mib[3] = pid; 23222514Sdarrenr 23322514Sdarrenr n = 1; 23422514Sdarrenr if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 23522514Sdarrenr { 23622514Sdarrenr perror("sysctl"); 23722514Sdarrenr return NULL; 23822514Sdarrenr } 23922514Sdarrenr return &kp; 24022514Sdarrenr} 24122514Sdarrenr 24222514Sdarrenr 24322514Sdarrenrstruct tcpcb *find_tcp(tfd, ti) 24422514Sdarrenrint tfd; 24522514Sdarrenrstruct tcpiphdr *ti; 24622514Sdarrenr{ 24722514Sdarrenr struct tcpcb *t; 24822514Sdarrenr struct inpcb *i; 24922514Sdarrenr struct socket *s; 25022514Sdarrenr struct filedesc *fd; 25122514Sdarrenr struct kinfo_proc *p; 25222514Sdarrenr struct file *f, **o; 25322514Sdarrenr 25422514Sdarrenr if (!(p = getproc())) 25522514Sdarrenr return NULL; 25622514Sdarrenr 25722514Sdarrenr fd = (struct filedesc *)malloc(sizeof(*fd)); 25824583Sdarrenr if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 25922514Sdarrenr { 26022514Sdarrenr fprintf(stderr, "read(%#lx,%#lx) failed\n", 26122514Sdarrenr (u_long)p, (u_long)p->kp_proc.p_fd); 26222514Sdarrenr return NULL; 26322514Sdarrenr } 26422514Sdarrenr 26522514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1)); 26624583Sdarrenr if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 26722514Sdarrenr { 26822514Sdarrenr fprintf(stderr, "read(%#lx,%#lx,%d) - u_ofile - failed\n", 26922514Sdarrenr (u_long)fd->fd_ofiles, (u_long)o, sizeof(*o)); 27022514Sdarrenr return NULL; 27122514Sdarrenr } 27222514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 27324583Sdarrenr if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 27422514Sdarrenr { 27522514Sdarrenr fprintf(stderr, "read(%#lx,%#lx,%d) - o[tfd] - failed\n", 27622514Sdarrenr (u_long)o[tfd], (u_long)f, sizeof(*f)); 27722514Sdarrenr return NULL; 27822514Sdarrenr } 27922514Sdarrenr 28022514Sdarrenr s = (struct socket *)calloc(1, sizeof(*s)); 28124583Sdarrenr if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 28222514Sdarrenr { 28322514Sdarrenr fprintf(stderr, "read(%#lx,%#lx,%d) - f_data - failed\n", 28422514Sdarrenr (u_long)f->f_data, (u_long)s, sizeof(*s)); 28522514Sdarrenr return NULL; 28622514Sdarrenr } 28722514Sdarrenr 28822514Sdarrenr i = (struct inpcb *)calloc(1, sizeof(*i)); 28924583Sdarrenr if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 29022514Sdarrenr { 29122514Sdarrenr fprintf(stderr, "kvm_read(%#lx,%#lx,%d) - so_pcb - failed\n", 29222514Sdarrenr (u_long)s->so_pcb, (u_long)i, sizeof(*i)); 29322514Sdarrenr return NULL; 29422514Sdarrenr } 29522514Sdarrenr 29622514Sdarrenr t = (struct tcpcb *)calloc(1, sizeof(*t)); 29724583Sdarrenr if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 29822514Sdarrenr { 29922514Sdarrenr fprintf(stderr, "read(%#lx,%#lx,%d) - inp_ppcb - failed\n", 30022514Sdarrenr (u_long)i->inp_ppcb, (u_long)t, sizeof(*t)); 30122514Sdarrenr return NULL; 30222514Sdarrenr } 30322514Sdarrenr return (struct tcpcb *)i->inp_ppcb; 30422514Sdarrenr} 30522514Sdarrenr#endif /* BSD < 199301 */ 30622514Sdarrenr 30724583Sdarrenrint do_socket(dev, mtu, ti, gwip) 30822514Sdarrenrchar *dev; 30922514Sdarrenrint mtu; 31022514Sdarrenrstruct tcpiphdr *ti; 31122514Sdarrenrstruct in_addr gwip; 31222514Sdarrenr{ 31322514Sdarrenr struct sockaddr_in rsin, lsin; 31422514Sdarrenr struct tcpcb *t, tcb; 31522514Sdarrenr int fd, nfd, len; 31622514Sdarrenr 31722514Sdarrenr printf("Dest. Port: %d\n", ti->ti_dport); 31822514Sdarrenr 31922514Sdarrenr fd = socket(AF_INET, SOCK_STREAM, 0); 32022514Sdarrenr if (fd == -1) 32122514Sdarrenr { 32222514Sdarrenr perror("socket"); 32322514Sdarrenr return -1; 32422514Sdarrenr } 32522514Sdarrenr 32622514Sdarrenr if (fcntl(fd, F_SETFL, FNDELAY) == -1) 32722514Sdarrenr { 32822514Sdarrenr perror("fcntl"); 32922514Sdarrenr return -1; 33022514Sdarrenr } 33122514Sdarrenr 33222514Sdarrenr bzero((char *)&lsin, sizeof(lsin)); 33322514Sdarrenr lsin.sin_family = AF_INET; 33422514Sdarrenr bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 33522514Sdarrenr sizeof(struct in_addr)); 33622514Sdarrenr if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 33722514Sdarrenr { 33822514Sdarrenr perror("bind"); 33922514Sdarrenr return -1; 34022514Sdarrenr } 34122514Sdarrenr len = sizeof(lsin); 34222514Sdarrenr (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 34322514Sdarrenr ti->ti_sport = lsin.sin_port; 34422514Sdarrenr printf("sport %d\n", ntohs(lsin.sin_port)); 34524583Sdarrenr nfd = initdevice(dev, ntohs(lsin.sin_port), 1); 34622514Sdarrenr 34722514Sdarrenr if (!(t = find_tcp(fd, ti))) 34822514Sdarrenr return -1; 34922514Sdarrenr 35022514Sdarrenr bzero((char *)&rsin, sizeof(rsin)); 35122514Sdarrenr rsin.sin_family = AF_INET; 35222514Sdarrenr bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 35322514Sdarrenr sizeof(struct in_addr)); 35422514Sdarrenr rsin.sin_port = ti->ti_dport; 35522514Sdarrenr if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 35622514Sdarrenr errno != EINPROGRESS) 35722514Sdarrenr { 35822514Sdarrenr perror("connect"); 35922514Sdarrenr return -1; 36022514Sdarrenr } 36124583Sdarrenr KMCPY(&tcb, t, sizeof(tcb)); 36222514Sdarrenr ti->ti_win = tcb.rcv_adv; 36322514Sdarrenr ti->ti_seq = tcb.snd_nxt - 1; 36422514Sdarrenr ti->ti_ack = tcb.rcv_nxt; 36522514Sdarrenr 36624583Sdarrenr if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 36722514Sdarrenr return -1; 36822514Sdarrenr (void)write(fd, "Hello World\n", 12); 36922514Sdarrenr sleep(2); 37022514Sdarrenr close(fd); 37122514Sdarrenr return 0; 37222514Sdarrenr} 373