sock.c revision 92691
157109Speter/* $FreeBSD: head/contrib/ipfilter/ipsend/sock.c 92691 2002-03-19 11:48:16Z darrenr $ */ 222514Sdarrenr/* 357109Speter * sock.c (C) 1995-1998 Darren Reed 422514Sdarrenr * 580490Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 622514Sdarrenr */ 792691Sdarrenr#ifdef __sgi 892691Sdarrenr# include <sys/ptimers.h> 992691Sdarrenr#endif 1022514Sdarrenr#include <stdio.h> 1122514Sdarrenr#include <unistd.h> 1222514Sdarrenr#include <string.h> 1322514Sdarrenr#include <stdlib.h> 1422514Sdarrenr#include <stddef.h> 1522514Sdarrenr#include <pwd.h> 1622514Sdarrenr#include <sys/types.h> 1722514Sdarrenr#include <sys/time.h> 1822514Sdarrenr#include <sys/param.h> 1922514Sdarrenr#include <sys/stat.h> 2031183Speter#ifndef ultrix 2122514Sdarrenr#include <fcntl.h> 2231183Speter#endif 2357109Speter#if (__FreeBSD_version >= 300000) 2457109Speter# include <sys/dirent.h> 2557109Speter#else 2657109Speter# include <sys/dir.h> 2734752Speter#endif 2822514Sdarrenr#define _KERNEL 2922514Sdarrenr#define KERNEL 3031183Speter#ifdef ultrix 3131183Speter# undef LOCORE 3231183Speter# include <sys/smp_lock.h> 3331183Speter#endif 3422514Sdarrenr#include <sys/file.h> 3522514Sdarrenr#undef _KERNEL 3622514Sdarrenr#undef KERNEL 3722514Sdarrenr#include <nlist.h> 3822514Sdarrenr#include <sys/user.h> 3922514Sdarrenr#include <sys/socket.h> 4022514Sdarrenr#include <sys/socketvar.h> 4122514Sdarrenr#include <sys/proc.h> 4231183Speter#if !defined(ultrix) && !defined(hpux) 4331183Speter# include <kvm.h> 4431183Speter#endif 4522514Sdarrenr#ifdef sun 4622514Sdarrenr#include <sys/systm.h> 4722514Sdarrenr#include <sys/session.h> 4822514Sdarrenr#endif 4922514Sdarrenr#if BSD >= 199103 5022514Sdarrenr#include <sys/sysctl.h> 5122514Sdarrenr#include <sys/filedesc.h> 5222514Sdarrenr#include <paths.h> 5322514Sdarrenr#endif 5422514Sdarrenr#include <math.h> 5522514Sdarrenr#include <netinet/in.h> 5622514Sdarrenr#include <netinet/in_systm.h> 5722514Sdarrenr#include <netinet/ip.h> 5822514Sdarrenr#include <netinet/tcp.h> 5922514Sdarrenr#include <net/if.h> 6022514Sdarrenr#include <net/route.h> 6122514Sdarrenr#include <netinet/ip_var.h> 6222514Sdarrenr#include <netinet/in_pcb.h> 6322514Sdarrenr#include <netinet/tcp_timer.h> 6422514Sdarrenr#include <netinet/tcp_var.h> 6524583Sdarrenr#include "ipsend.h" 6622514Sdarrenr 6780490Sdarrenr#if !defined(lint) 6880490Sdarrenrstatic const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 6992691Sdarrenrstatic const char rcsid[] = "@(#)$Id: sock.c,v 2.1.4.5 2002/02/22 15:32:58 darrenr Exp $"; 7080490Sdarrenr#endif 7180490Sdarrenr 7280490Sdarrenr 7322514Sdarrenrint nproc; 7422514Sdarrenrstruct proc *proc; 7522514Sdarrenr 7622514Sdarrenr#ifndef KMEM 7722514Sdarrenr# ifdef _PATH_KMEM 7822514Sdarrenr# define KMEM _PATH_KMEM 7922514Sdarrenr# endif 8022514Sdarrenr#endif 8122514Sdarrenr#ifndef KERNEL 8222514Sdarrenr# ifdef _PATH_UNIX 8322514Sdarrenr# define KERNEL _PATH_UNIX 8422514Sdarrenr# endif 8522514Sdarrenr#endif 8622514Sdarrenr#ifndef KMEM 8722514Sdarrenr# define KMEM "/dev/kmem" 8822514Sdarrenr#endif 8922514Sdarrenr#ifndef KERNEL 9022514Sdarrenr# define KERNEL "/vmunix" 9122514Sdarrenr#endif 9222514Sdarrenr 9324583Sdarrenr 9424583Sdarrenr#if BSD < 199103 9524583Sdarrenrstatic struct proc *getproc __P((void)); 9624583Sdarrenr#else 9724583Sdarrenrstatic struct kinfo_proc *getproc __P((void)); 9824583Sdarrenr#endif 9924583Sdarrenr 10024583Sdarrenr 10122514Sdarrenrint kmemcpy(buf, pos, n) 10222514Sdarrenrchar *buf; 10324583Sdarrenrvoid *pos; 10422514Sdarrenrint n; 10522514Sdarrenr{ 10622514Sdarrenr static int kfd = -1; 10731183Speter off_t offset = (u_long)pos; 10822514Sdarrenr 10922514Sdarrenr if (kfd == -1) 11022514Sdarrenr kfd = open(KMEM, O_RDONLY); 11122514Sdarrenr 11231183Speter if (lseek(kfd, offset, SEEK_SET) == -1) 11322514Sdarrenr { 11422514Sdarrenr perror("lseek"); 11522514Sdarrenr return -1; 11622514Sdarrenr } 11722514Sdarrenr if (read(kfd, buf, n) == -1) 11822514Sdarrenr { 11922514Sdarrenr perror("read"); 12022514Sdarrenr return -1; 12122514Sdarrenr } 12222514Sdarrenr return n; 12322514Sdarrenr} 12422514Sdarrenr 12531183Speterstruct nlist names[4] = { 12622514Sdarrenr { "_proc" }, 12722514Sdarrenr { "_nproc" }, 12831183Speter#ifdef ultrix 12931183Speter { "_u" }, 13031183Speter#else 13131183Speter { NULL }, 13231183Speter#endif 13322514Sdarrenr { NULL } 13422514Sdarrenr }; 13522514Sdarrenr 13622514Sdarrenr#if BSD < 199103 13724583Sdarrenrstatic struct proc *getproc() 13822514Sdarrenr{ 13922514Sdarrenr struct proc *p; 14022514Sdarrenr pid_t pid = getpid(); 14122514Sdarrenr int siz, n; 14222514Sdarrenr 14322514Sdarrenr n = nlist(KERNEL, names); 14422514Sdarrenr if (n != 0) 14522514Sdarrenr { 14622514Sdarrenr fprintf(stderr, "nlist(%#x) == %d\n", names, n); 14722514Sdarrenr return NULL; 14822514Sdarrenr } 14924583Sdarrenr if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 15022514Sdarrenr { 15122514Sdarrenr fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 15222514Sdarrenr return NULL; 15322514Sdarrenr } 15422514Sdarrenr siz = nproc * sizeof(struct proc); 15524583Sdarrenr if (KMCPY(&p, names[0].n_value, sizeof(p)) == -1) 15622514Sdarrenr { 15722514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 15822514Sdarrenr names[0].n_value, &p, sizeof(p)); 15922514Sdarrenr return NULL; 16022514Sdarrenr } 16122514Sdarrenr proc = (struct proc *)malloc(siz); 16224583Sdarrenr if (KMCPY(proc, p, siz) == -1) 16322514Sdarrenr { 16422514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 16522514Sdarrenr p, proc, siz); 16622514Sdarrenr return NULL; 16722514Sdarrenr } 16822514Sdarrenr 16922514Sdarrenr p = proc; 17022514Sdarrenr 17122514Sdarrenr for (n = nproc; n; n--, p++) 17222514Sdarrenr if (p->p_pid == pid) 17322514Sdarrenr break; 17422514Sdarrenr if (!n) 17522514Sdarrenr return NULL; 17622514Sdarrenr 17722514Sdarrenr return p; 17822514Sdarrenr} 17922514Sdarrenr 18022514Sdarrenr 18122514Sdarrenrstruct tcpcb *find_tcp(fd, ti) 18222514Sdarrenrint fd; 18322514Sdarrenrstruct tcpiphdr *ti; 18422514Sdarrenr{ 18522514Sdarrenr struct tcpcb *t; 18622514Sdarrenr struct inpcb *i; 18722514Sdarrenr struct socket *s; 18822514Sdarrenr struct user *up; 18922514Sdarrenr struct proc *p; 19022514Sdarrenr struct file *f, **o; 19122514Sdarrenr 19222514Sdarrenr if (!(p = getproc())) 19322514Sdarrenr return NULL; 19422514Sdarrenr up = (struct user *)malloc(sizeof(*up)); 19531183Speter#ifndef ultrix 19624583Sdarrenr if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1) 19722514Sdarrenr { 19822514Sdarrenr fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea); 19922514Sdarrenr return NULL; 20022514Sdarrenr } 20131183Speter#else 20231183Speter if (KMCPY(up, names[2].n_value, sizeof(*up)) == -1) 20331183Speter { 20431183Speter fprintf(stderr, "read(%#x,%#x) failed\n", p, names[2].n_value); 20531183Speter return NULL; 20631183Speter } 20731183Speter#endif 20822514Sdarrenr 20922514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1)); 21024583Sdarrenr if (KMCPY(o, up->u_ofile, (up->u_lastfile + 1) * sizeof(*o)) == -1) 21122514Sdarrenr { 21222514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n", 21331183Speter up->u_ofile, o, sizeof(*o)); 21422514Sdarrenr return NULL; 21522514Sdarrenr } 21622514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 21724583Sdarrenr if (KMCPY(f, o[fd], sizeof(*f)) == -1) 21822514Sdarrenr { 21922514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 22031183Speter up->u_ofile[fd], f, sizeof(*f)); 22122514Sdarrenr return NULL; 22222514Sdarrenr } 22322514Sdarrenr 22422514Sdarrenr s = (struct socket *)calloc(1, sizeof(*s)); 22524583Sdarrenr if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 22622514Sdarrenr { 22722514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n", 22822514Sdarrenr o[fd], s, sizeof(*s)); 22922514Sdarrenr return NULL; 23022514Sdarrenr } 23122514Sdarrenr 23222514Sdarrenr i = (struct inpcb *)calloc(1, sizeof(*i)); 23324583Sdarrenr if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 23422514Sdarrenr { 23522514Sdarrenr fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n", 23622514Sdarrenr s->so_pcb, i, sizeof(*i)); 23722514Sdarrenr return NULL; 23822514Sdarrenr } 23922514Sdarrenr 24022514Sdarrenr t = (struct tcpcb *)calloc(1, sizeof(*t)); 24124583Sdarrenr if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 24222514Sdarrenr { 24322514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n", 24422514Sdarrenr i->inp_ppcb, t, sizeof(*t)); 24522514Sdarrenr return NULL; 24622514Sdarrenr } 24722514Sdarrenr return (struct tcpcb *)i->inp_ppcb; 24822514Sdarrenr} 24922514Sdarrenr#else 25024583Sdarrenrstatic struct kinfo_proc *getproc() 25122514Sdarrenr{ 25222514Sdarrenr static struct kinfo_proc kp; 25322514Sdarrenr pid_t pid = getpid(); 25431183Speter int mib[4]; 25531183Speter size_t n; 25622514Sdarrenr 25722514Sdarrenr mib[0] = CTL_KERN; 25822514Sdarrenr mib[1] = KERN_PROC; 25922514Sdarrenr mib[2] = KERN_PROC_PID; 26022514Sdarrenr mib[3] = pid; 26122514Sdarrenr 26234739Speter n = sizeof(kp); 26322514Sdarrenr if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 26422514Sdarrenr { 26522514Sdarrenr perror("sysctl"); 26622514Sdarrenr return NULL; 26722514Sdarrenr } 26822514Sdarrenr return &kp; 26922514Sdarrenr} 27022514Sdarrenr 27122514Sdarrenr 27222514Sdarrenrstruct tcpcb *find_tcp(tfd, ti) 27322514Sdarrenrint tfd; 27422514Sdarrenrstruct tcpiphdr *ti; 27522514Sdarrenr{ 27622514Sdarrenr struct tcpcb *t; 27722514Sdarrenr struct inpcb *i; 27822514Sdarrenr struct socket *s; 27922514Sdarrenr struct filedesc *fd; 28022514Sdarrenr struct kinfo_proc *p; 28122514Sdarrenr struct file *f, **o; 28222514Sdarrenr 28322514Sdarrenr if (!(p = getproc())) 28422514Sdarrenr return NULL; 28522514Sdarrenr 28622514Sdarrenr fd = (struct filedesc *)malloc(sizeof(*fd)); 28770033Salfred#if defined( __FreeBSD_version) && __FreeBSD_version >= 500013 28870033Salfred if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 28970033Salfred { 29070033Salfred fprintf(stderr, "read(%#lx,%#lx) failed\n", 29170033Salfred (u_long)p, (u_long)p->ki_fd); 29270033Salfred return NULL; 29370033Salfred } 29470033Salfred#else 29524583Sdarrenr if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 29622514Sdarrenr { 29722514Sdarrenr fprintf(stderr, "read(%#lx,%#lx) failed\n", 29822514Sdarrenr (u_long)p, (u_long)p->kp_proc.p_fd); 29922514Sdarrenr return NULL; 30022514Sdarrenr } 30170033Salfred#endif 30222514Sdarrenr 30322514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1)); 30424583Sdarrenr if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 30522514Sdarrenr { 30631183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 30731183Speter (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 30822514Sdarrenr return NULL; 30922514Sdarrenr } 31022514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 31124583Sdarrenr if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 31222514Sdarrenr { 31331183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 31431183Speter (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 31522514Sdarrenr return NULL; 31622514Sdarrenr } 31722514Sdarrenr 31822514Sdarrenr s = (struct socket *)calloc(1, sizeof(*s)); 31924583Sdarrenr if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 32022514Sdarrenr { 32131183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 32231183Speter (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 32322514Sdarrenr return NULL; 32422514Sdarrenr } 32522514Sdarrenr 32622514Sdarrenr i = (struct inpcb *)calloc(1, sizeof(*i)); 32724583Sdarrenr if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 32822514Sdarrenr { 32931183Speter fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 33031183Speter (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 33122514Sdarrenr return NULL; 33222514Sdarrenr } 33322514Sdarrenr 33422514Sdarrenr t = (struct tcpcb *)calloc(1, sizeof(*t)); 33524583Sdarrenr if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 33622514Sdarrenr { 33731183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 33831183Speter (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 33922514Sdarrenr return NULL; 34022514Sdarrenr } 34122514Sdarrenr return (struct tcpcb *)i->inp_ppcb; 34222514Sdarrenr} 34322514Sdarrenr#endif /* BSD < 199301 */ 34422514Sdarrenr 34524583Sdarrenrint do_socket(dev, mtu, ti, gwip) 34622514Sdarrenrchar *dev; 34722514Sdarrenrint mtu; 34822514Sdarrenrstruct tcpiphdr *ti; 34922514Sdarrenrstruct in_addr gwip; 35022514Sdarrenr{ 35122514Sdarrenr struct sockaddr_in rsin, lsin; 35222514Sdarrenr struct tcpcb *t, tcb; 35322514Sdarrenr int fd, nfd, len; 35422514Sdarrenr 35522514Sdarrenr printf("Dest. Port: %d\n", ti->ti_dport); 35622514Sdarrenr 35722514Sdarrenr fd = socket(AF_INET, SOCK_STREAM, 0); 35822514Sdarrenr if (fd == -1) 35922514Sdarrenr { 36022514Sdarrenr perror("socket"); 36122514Sdarrenr return -1; 36222514Sdarrenr } 36322514Sdarrenr 36422514Sdarrenr if (fcntl(fd, F_SETFL, FNDELAY) == -1) 36522514Sdarrenr { 36622514Sdarrenr perror("fcntl"); 36722514Sdarrenr return -1; 36822514Sdarrenr } 36922514Sdarrenr 37022514Sdarrenr bzero((char *)&lsin, sizeof(lsin)); 37122514Sdarrenr lsin.sin_family = AF_INET; 37222514Sdarrenr bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 37322514Sdarrenr sizeof(struct in_addr)); 37422514Sdarrenr if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 37522514Sdarrenr { 37622514Sdarrenr perror("bind"); 37722514Sdarrenr return -1; 37822514Sdarrenr } 37922514Sdarrenr len = sizeof(lsin); 38022514Sdarrenr (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 38122514Sdarrenr ti->ti_sport = lsin.sin_port; 38222514Sdarrenr printf("sport %d\n", ntohs(lsin.sin_port)); 38324583Sdarrenr nfd = initdevice(dev, ntohs(lsin.sin_port), 1); 38422514Sdarrenr 38522514Sdarrenr if (!(t = find_tcp(fd, ti))) 38622514Sdarrenr return -1; 38722514Sdarrenr 38822514Sdarrenr bzero((char *)&rsin, sizeof(rsin)); 38922514Sdarrenr rsin.sin_family = AF_INET; 39022514Sdarrenr bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 39122514Sdarrenr sizeof(struct in_addr)); 39222514Sdarrenr rsin.sin_port = ti->ti_dport; 39322514Sdarrenr if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 39422514Sdarrenr errno != EINPROGRESS) 39522514Sdarrenr { 39622514Sdarrenr perror("connect"); 39722514Sdarrenr return -1; 39822514Sdarrenr } 39924583Sdarrenr KMCPY(&tcb, t, sizeof(tcb)); 40022514Sdarrenr ti->ti_win = tcb.rcv_adv; 40122514Sdarrenr ti->ti_seq = tcb.snd_nxt - 1; 40222514Sdarrenr ti->ti_ack = tcb.rcv_nxt; 40322514Sdarrenr 40424583Sdarrenr if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 40522514Sdarrenr return -1; 40622514Sdarrenr (void)write(fd, "Hello World\n", 12); 40722514Sdarrenr sleep(2); 40822514Sdarrenr close(fd); 40922514Sdarrenr return 0; 41022514Sdarrenr} 411