sock.c revision 70033
157109Speter/* $FreeBSD: head/contrib/ipfilter/ipsend/sock.c 70033 2000-12-14 23:35:57Z alfred $ */ 222514Sdarrenr/* 357109Speter * sock.c (C) 1995-1998 Darren Reed 422514Sdarrenr * 531183Speter * Redistribution and use in source and binary forms are permitted 631183Speter * provided that this notice is preserved and due credit is given 731183Speter * to the original author and the contributors. 822514Sdarrenr */ 931183Speter#if !defined(lint) 1031183Speterstatic const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 1157109Speterstatic const char rcsid[] = "@(#)$Id: sock.c,v 2.1 1999/08/04 17:31:16 darrenr Exp $"; 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> 2331183Speter#ifndef ultrix 2422514Sdarrenr#include <fcntl.h> 2531183Speter#endif 2657109Speter#if (__FreeBSD_version >= 300000) 2757109Speter# include <sys/dirent.h> 2857109Speter#else 2957109Speter# include <sys/dir.h> 3034752Speter#endif 3122514Sdarrenr#define _KERNEL 3222514Sdarrenr#define KERNEL 3331183Speter#ifdef ultrix 3431183Speter# undef LOCORE 3531183Speter# include <sys/smp_lock.h> 3631183Speter#endif 3722514Sdarrenr#include <sys/file.h> 3822514Sdarrenr#undef _KERNEL 3922514Sdarrenr#undef KERNEL 4022514Sdarrenr#include <nlist.h> 4122514Sdarrenr#include <sys/user.h> 4222514Sdarrenr#include <sys/socket.h> 4322514Sdarrenr#include <sys/socketvar.h> 4422514Sdarrenr#include <sys/proc.h> 4531183Speter#if !defined(ultrix) && !defined(hpux) 4631183Speter# include <kvm.h> 4731183Speter#endif 4822514Sdarrenr#ifdef sun 4922514Sdarrenr#include <sys/systm.h> 5022514Sdarrenr#include <sys/session.h> 5122514Sdarrenr#endif 5222514Sdarrenr#if BSD >= 199103 5322514Sdarrenr#include <sys/sysctl.h> 5422514Sdarrenr#include <sys/filedesc.h> 5522514Sdarrenr#include <paths.h> 5622514Sdarrenr#endif 5722514Sdarrenr#include <math.h> 5822514Sdarrenr#include <netinet/in.h> 5922514Sdarrenr#include <netinet/in_systm.h> 6022514Sdarrenr#include <netinet/ip.h> 6122514Sdarrenr#include <netinet/tcp.h> 6222514Sdarrenr#include <net/if.h> 6322514Sdarrenr#include <net/route.h> 6422514Sdarrenr#include <netinet/ip_var.h> 6522514Sdarrenr#include <netinet/in_pcb.h> 6622514Sdarrenr#include <netinet/tcp_timer.h> 6722514Sdarrenr#include <netinet/tcp_var.h> 6824583Sdarrenr#include "ipsend.h" 6922514Sdarrenr 7022514Sdarrenrint nproc; 7122514Sdarrenrstruct proc *proc; 7222514Sdarrenr 7322514Sdarrenr#ifndef KMEM 7422514Sdarrenr# ifdef _PATH_KMEM 7522514Sdarrenr# define KMEM _PATH_KMEM 7622514Sdarrenr# endif 7722514Sdarrenr#endif 7822514Sdarrenr#ifndef KERNEL 7922514Sdarrenr# ifdef _PATH_UNIX 8022514Sdarrenr# define KERNEL _PATH_UNIX 8122514Sdarrenr# endif 8222514Sdarrenr#endif 8322514Sdarrenr#ifndef KMEM 8422514Sdarrenr# define KMEM "/dev/kmem" 8522514Sdarrenr#endif 8622514Sdarrenr#ifndef KERNEL 8722514Sdarrenr# define KERNEL "/vmunix" 8822514Sdarrenr#endif 8922514Sdarrenr 9024583Sdarrenr 9124583Sdarrenr#if BSD < 199103 9224583Sdarrenrstatic struct proc *getproc __P((void)); 9324583Sdarrenr#else 9424583Sdarrenrstatic struct kinfo_proc *getproc __P((void)); 9524583Sdarrenr#endif 9624583Sdarrenr 9724583Sdarrenr 9822514Sdarrenrint kmemcpy(buf, pos, n) 9922514Sdarrenrchar *buf; 10024583Sdarrenrvoid *pos; 10122514Sdarrenrint n; 10222514Sdarrenr{ 10322514Sdarrenr static int kfd = -1; 10431183Speter off_t offset = (u_long)pos; 10522514Sdarrenr 10622514Sdarrenr if (kfd == -1) 10722514Sdarrenr kfd = open(KMEM, O_RDONLY); 10822514Sdarrenr 10931183Speter if (lseek(kfd, offset, SEEK_SET) == -1) 11022514Sdarrenr { 11122514Sdarrenr perror("lseek"); 11222514Sdarrenr return -1; 11322514Sdarrenr } 11422514Sdarrenr if (read(kfd, buf, n) == -1) 11522514Sdarrenr { 11622514Sdarrenr perror("read"); 11722514Sdarrenr return -1; 11822514Sdarrenr } 11922514Sdarrenr return n; 12022514Sdarrenr} 12122514Sdarrenr 12231183Speterstruct nlist names[4] = { 12322514Sdarrenr { "_proc" }, 12422514Sdarrenr { "_nproc" }, 12531183Speter#ifdef ultrix 12631183Speter { "_u" }, 12731183Speter#else 12831183Speter { NULL }, 12931183Speter#endif 13022514Sdarrenr { NULL } 13122514Sdarrenr }; 13222514Sdarrenr 13322514Sdarrenr#if BSD < 199103 13424583Sdarrenrstatic struct proc *getproc() 13522514Sdarrenr{ 13622514Sdarrenr struct proc *p; 13722514Sdarrenr pid_t pid = getpid(); 13822514Sdarrenr int siz, n; 13922514Sdarrenr 14022514Sdarrenr n = nlist(KERNEL, names); 14122514Sdarrenr if (n != 0) 14222514Sdarrenr { 14322514Sdarrenr fprintf(stderr, "nlist(%#x) == %d\n", names, n); 14422514Sdarrenr return NULL; 14522514Sdarrenr } 14624583Sdarrenr if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 14722514Sdarrenr { 14822514Sdarrenr fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 14922514Sdarrenr return NULL; 15022514Sdarrenr } 15122514Sdarrenr siz = nproc * sizeof(struct proc); 15224583Sdarrenr if (KMCPY(&p, names[0].n_value, sizeof(p)) == -1) 15322514Sdarrenr { 15422514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 15522514Sdarrenr names[0].n_value, &p, sizeof(p)); 15622514Sdarrenr return NULL; 15722514Sdarrenr } 15822514Sdarrenr proc = (struct proc *)malloc(siz); 15924583Sdarrenr if (KMCPY(proc, p, siz) == -1) 16022514Sdarrenr { 16122514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 16222514Sdarrenr p, proc, siz); 16322514Sdarrenr return NULL; 16422514Sdarrenr } 16522514Sdarrenr 16622514Sdarrenr p = proc; 16722514Sdarrenr 16822514Sdarrenr for (n = nproc; n; n--, p++) 16922514Sdarrenr if (p->p_pid == pid) 17022514Sdarrenr break; 17122514Sdarrenr if (!n) 17222514Sdarrenr return NULL; 17322514Sdarrenr 17422514Sdarrenr return p; 17522514Sdarrenr} 17622514Sdarrenr 17722514Sdarrenr 17822514Sdarrenrstruct tcpcb *find_tcp(fd, ti) 17922514Sdarrenrint fd; 18022514Sdarrenrstruct tcpiphdr *ti; 18122514Sdarrenr{ 18222514Sdarrenr struct tcpcb *t; 18322514Sdarrenr struct inpcb *i; 18422514Sdarrenr struct socket *s; 18522514Sdarrenr struct user *up; 18622514Sdarrenr struct proc *p; 18722514Sdarrenr struct file *f, **o; 18822514Sdarrenr 18922514Sdarrenr if (!(p = getproc())) 19022514Sdarrenr return NULL; 19131183Speterprintf("fl %x ty %x cn %d mc %d\n", 19231183Speterf->f_flag, f->f_type, f->f_count, f->f_msgcount); 19322514Sdarrenr up = (struct user *)malloc(sizeof(*up)); 19431183Speter#ifndef ultrix 19524583Sdarrenr if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1) 19622514Sdarrenr { 19722514Sdarrenr fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea); 19822514Sdarrenr return NULL; 19922514Sdarrenr } 20031183Speter#else 20131183Speter if (KMCPY(up, names[2].n_value, sizeof(*up)) == -1) 20231183Speter { 20331183Speter fprintf(stderr, "read(%#x,%#x) failed\n", p, names[2].n_value); 20431183Speter return NULL; 20531183Speter } 20631183Speter#endif 20722514Sdarrenr 20822514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1)); 20924583Sdarrenr if (KMCPY(o, up->u_ofile, (up->u_lastfile + 1) * sizeof(*o)) == -1) 21022514Sdarrenr { 21122514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n", 21231183Speter up->u_ofile, o, sizeof(*o)); 21322514Sdarrenr return NULL; 21422514Sdarrenr } 21522514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 21624583Sdarrenr if (KMCPY(f, o[fd], sizeof(*f)) == -1) 21722514Sdarrenr { 21822514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 21931183Speter up->u_ofile[fd], f, sizeof(*f)); 22022514Sdarrenr return NULL; 22122514Sdarrenr } 22222514Sdarrenr 22322514Sdarrenr s = (struct socket *)calloc(1, sizeof(*s)); 22424583Sdarrenr if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 22522514Sdarrenr { 22622514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - f_data - failed\n", 22722514Sdarrenr o[fd], s, sizeof(*s)); 22822514Sdarrenr return NULL; 22922514Sdarrenr } 23022514Sdarrenr 23122514Sdarrenr i = (struct inpcb *)calloc(1, sizeof(*i)); 23224583Sdarrenr if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 23322514Sdarrenr { 23422514Sdarrenr fprintf(stderr, "kvm_read(%#x,%#x,%d) - so_pcb - failed\n", 23522514Sdarrenr s->so_pcb, i, sizeof(*i)); 23622514Sdarrenr return NULL; 23722514Sdarrenr } 23822514Sdarrenr 23922514Sdarrenr t = (struct tcpcb *)calloc(1, sizeof(*t)); 24024583Sdarrenr if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 24122514Sdarrenr { 24222514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - inp_ppcb - failed\n", 24322514Sdarrenr i->inp_ppcb, t, sizeof(*t)); 24422514Sdarrenr return NULL; 24522514Sdarrenr } 24622514Sdarrenr return (struct tcpcb *)i->inp_ppcb; 24722514Sdarrenr} 24822514Sdarrenr#else 24924583Sdarrenrstatic struct kinfo_proc *getproc() 25022514Sdarrenr{ 25122514Sdarrenr static struct kinfo_proc kp; 25222514Sdarrenr pid_t pid = getpid(); 25331183Speter int mib[4]; 25431183Speter size_t n; 25522514Sdarrenr 25622514Sdarrenr mib[0] = CTL_KERN; 25722514Sdarrenr mib[1] = KERN_PROC; 25822514Sdarrenr mib[2] = KERN_PROC_PID; 25922514Sdarrenr mib[3] = pid; 26022514Sdarrenr 26134739Speter n = sizeof(kp); 26222514Sdarrenr if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 26322514Sdarrenr { 26422514Sdarrenr perror("sysctl"); 26522514Sdarrenr return NULL; 26622514Sdarrenr } 26722514Sdarrenr return &kp; 26822514Sdarrenr} 26922514Sdarrenr 27022514Sdarrenr 27122514Sdarrenrstruct tcpcb *find_tcp(tfd, ti) 27222514Sdarrenrint tfd; 27322514Sdarrenrstruct tcpiphdr *ti; 27422514Sdarrenr{ 27522514Sdarrenr struct tcpcb *t; 27622514Sdarrenr struct inpcb *i; 27722514Sdarrenr struct socket *s; 27822514Sdarrenr struct filedesc *fd; 27922514Sdarrenr struct kinfo_proc *p; 28022514Sdarrenr struct file *f, **o; 28122514Sdarrenr 28222514Sdarrenr if (!(p = getproc())) 28322514Sdarrenr return NULL; 28422514Sdarrenr 28522514Sdarrenr fd = (struct filedesc *)malloc(sizeof(*fd)); 28670033Salfred#if defined( __FreeBSD_version) && __FreeBSD_version >= 500013 28770033Salfred if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 28870033Salfred { 28970033Salfred fprintf(stderr, "read(%#lx,%#lx) failed\n", 29070033Salfred (u_long)p, (u_long)p->ki_fd); 29170033Salfred return NULL; 29270033Salfred } 29370033Salfred#else 29424583Sdarrenr if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 29522514Sdarrenr { 29622514Sdarrenr fprintf(stderr, "read(%#lx,%#lx) failed\n", 29722514Sdarrenr (u_long)p, (u_long)p->kp_proc.p_fd); 29822514Sdarrenr return NULL; 29922514Sdarrenr } 30070033Salfred#endif 30122514Sdarrenr 30222514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1)); 30324583Sdarrenr if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 30422514Sdarrenr { 30531183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 30631183Speter (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 30722514Sdarrenr return NULL; 30822514Sdarrenr } 30922514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 31024583Sdarrenr if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 31122514Sdarrenr { 31231183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 31331183Speter (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 31422514Sdarrenr return NULL; 31522514Sdarrenr } 31622514Sdarrenr 31722514Sdarrenr s = (struct socket *)calloc(1, sizeof(*s)); 31824583Sdarrenr if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 31922514Sdarrenr { 32031183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 32131183Speter (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 32222514Sdarrenr return NULL; 32322514Sdarrenr } 32422514Sdarrenr 32522514Sdarrenr i = (struct inpcb *)calloc(1, sizeof(*i)); 32624583Sdarrenr if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 32722514Sdarrenr { 32831183Speter fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 32931183Speter (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 33022514Sdarrenr return NULL; 33122514Sdarrenr } 33222514Sdarrenr 33322514Sdarrenr t = (struct tcpcb *)calloc(1, sizeof(*t)); 33424583Sdarrenr if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 33522514Sdarrenr { 33631183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 33731183Speter (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 33822514Sdarrenr return NULL; 33922514Sdarrenr } 34022514Sdarrenr return (struct tcpcb *)i->inp_ppcb; 34122514Sdarrenr} 34222514Sdarrenr#endif /* BSD < 199301 */ 34322514Sdarrenr 34424583Sdarrenrint do_socket(dev, mtu, ti, gwip) 34522514Sdarrenrchar *dev; 34622514Sdarrenrint mtu; 34722514Sdarrenrstruct tcpiphdr *ti; 34822514Sdarrenrstruct in_addr gwip; 34922514Sdarrenr{ 35022514Sdarrenr struct sockaddr_in rsin, lsin; 35122514Sdarrenr struct tcpcb *t, tcb; 35222514Sdarrenr int fd, nfd, len; 35322514Sdarrenr 35422514Sdarrenr printf("Dest. Port: %d\n", ti->ti_dport); 35522514Sdarrenr 35622514Sdarrenr fd = socket(AF_INET, SOCK_STREAM, 0); 35722514Sdarrenr if (fd == -1) 35822514Sdarrenr { 35922514Sdarrenr perror("socket"); 36022514Sdarrenr return -1; 36122514Sdarrenr } 36222514Sdarrenr 36322514Sdarrenr if (fcntl(fd, F_SETFL, FNDELAY) == -1) 36422514Sdarrenr { 36522514Sdarrenr perror("fcntl"); 36622514Sdarrenr return -1; 36722514Sdarrenr } 36822514Sdarrenr 36922514Sdarrenr bzero((char *)&lsin, sizeof(lsin)); 37022514Sdarrenr lsin.sin_family = AF_INET; 37122514Sdarrenr bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 37222514Sdarrenr sizeof(struct in_addr)); 37322514Sdarrenr if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 37422514Sdarrenr { 37522514Sdarrenr perror("bind"); 37622514Sdarrenr return -1; 37722514Sdarrenr } 37822514Sdarrenr len = sizeof(lsin); 37922514Sdarrenr (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 38022514Sdarrenr ti->ti_sport = lsin.sin_port; 38122514Sdarrenr printf("sport %d\n", ntohs(lsin.sin_port)); 38224583Sdarrenr nfd = initdevice(dev, ntohs(lsin.sin_port), 1); 38322514Sdarrenr 38422514Sdarrenr if (!(t = find_tcp(fd, ti))) 38522514Sdarrenr return -1; 38622514Sdarrenr 38722514Sdarrenr bzero((char *)&rsin, sizeof(rsin)); 38822514Sdarrenr rsin.sin_family = AF_INET; 38922514Sdarrenr bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 39022514Sdarrenr sizeof(struct in_addr)); 39122514Sdarrenr rsin.sin_port = ti->ti_dport; 39222514Sdarrenr if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 39322514Sdarrenr errno != EINPROGRESS) 39422514Sdarrenr { 39522514Sdarrenr perror("connect"); 39622514Sdarrenr return -1; 39722514Sdarrenr } 39824583Sdarrenr KMCPY(&tcb, t, sizeof(tcb)); 39922514Sdarrenr ti->ti_win = tcb.rcv_adv; 40022514Sdarrenr ti->ti_seq = tcb.snd_nxt - 1; 40122514Sdarrenr ti->ti_ack = tcb.rcv_nxt; 40222514Sdarrenr 40324583Sdarrenr if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 40422514Sdarrenr return -1; 40522514Sdarrenr (void)write(fd, "Hello World\n", 12); 40622514Sdarrenr sleep(2); 40722514Sdarrenr close(fd); 40822514Sdarrenr return 0; 40922514Sdarrenr} 410