157109Speter/* $FreeBSD: stable/11/contrib/ipfilter/ipsend/sock.c 369277 2021-02-16 00:48:38Z cy $ */ 222514Sdarrenr/* 357109Speter * sock.c (C) 1995-1998 Darren Reed 422514Sdarrenr * 580490Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 6145519Sdarrenr * 722514Sdarrenr */ 8145519Sdarrenr#if !defined(lint) 9145519Sdarrenrstatic const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 10255332Scystatic const char rcsid[] = "@(#)$Id$"; 1192691Sdarrenr#endif 12145519Sdarrenr#include <sys/param.h> 1322514Sdarrenr#include <sys/types.h> 1422514Sdarrenr#include <sys/time.h> 1522514Sdarrenr#include <sys/stat.h> 16161357Sguido#if defined(__NetBSD__) && defined(__vax__) 17161357Sguido/* 18161357Sguido * XXX need to declare boolean_t for _KERNEL <sys/files.h> 19161357Sguido * which ends up including <sys/device.h> for vax. See PR#32907 20161357Sguido * for further details. 21161357Sguido */ 22161357Sguidotypedef int boolean_t; 23161357Sguido#endif 2422514Sdarrenr#include <fcntl.h> 2557109Speter# include <sys/dirent.h> 26255332Scy# ifdef __NetBSD__ 27172776Sdarrenr# include <machine/lock.h> 28172776Sdarrenr# endif 29180761Sdes# ifdef __FreeBSD__ 30180761Sdes# define _WANT_FILE 31180761Sdes# else 32180761Sdes# define _KERNEL 33180761Sdes# define KERNEL 34180761Sdes# endif 35145519Sdarrenr# include <sys/file.h> 36180761Sdes# ifdef __FreeBSD__ 37180761Sdes# undef _WANT_FILE 38180761Sdes# else 39180761Sdes# undef _KERNEL 40180761Sdes# undef KERNEL 41180761Sdes# endif 4222514Sdarrenr#include <nlist.h> 4322514Sdarrenr#include <sys/user.h> 4422514Sdarrenr#include <sys/socket.h> 4522514Sdarrenr#include <sys/socketvar.h> 4622514Sdarrenr#include <sys/proc.h> 4731183Speter# include <kvm.h> 4822514Sdarrenr#ifdef sun 4922514Sdarrenr#include <sys/systm.h> 5022514Sdarrenr#include <sys/session.h> 5122514Sdarrenr#endif 5222514Sdarrenr#include <sys/sysctl.h> 5322514Sdarrenr#include <sys/filedesc.h> 5422514Sdarrenr#include <paths.h> 5522514Sdarrenr#include <math.h> 5622514Sdarrenr#include <netinet/in.h> 5722514Sdarrenr#include <netinet/in_systm.h> 5822514Sdarrenr#include <netinet/ip.h> 5922514Sdarrenr#include <netinet/tcp.h> 6022514Sdarrenr#include <net/if.h> 61170268Sdarrenr# include <net/route.h> 6222514Sdarrenr#include <netinet/ip_var.h> 6322514Sdarrenr#include <netinet/in_pcb.h> 6422514Sdarrenr#include <netinet/tcp_timer.h> 6522514Sdarrenr#include <netinet/tcp_var.h> 66145519Sdarrenr#include <stdio.h> 67145519Sdarrenr#include <unistd.h> 68145519Sdarrenr#include <string.h> 69145519Sdarrenr#include <stdlib.h> 70145519Sdarrenr#include <stddef.h> 71145519Sdarrenr#include <pwd.h> 7224583Sdarrenr#include "ipsend.h" 7322514Sdarrenr 7480490Sdarrenr 7522514Sdarrenrint nproc; 7622514Sdarrenrstruct proc *proc; 7722514Sdarrenr 7822514Sdarrenr#ifndef KMEM 7922514Sdarrenr# ifdef _PATH_KMEM 8022514Sdarrenr# define KMEM _PATH_KMEM 8122514Sdarrenr# endif 8222514Sdarrenr#endif 8322514Sdarrenr#ifndef KERNEL 8422514Sdarrenr# ifdef _PATH_UNIX 8522514Sdarrenr# define KERNEL _PATH_UNIX 8622514Sdarrenr# endif 8722514Sdarrenr#endif 8822514Sdarrenr#ifndef KMEM 8922514Sdarrenr# define KMEM "/dev/kmem" 9022514Sdarrenr#endif 9122514Sdarrenr#ifndef KERNEL 9222514Sdarrenr# define KERNEL "/vmunix" 9322514Sdarrenr#endif 9422514Sdarrenr 9524583Sdarrenr 96369245Sgit2svnstatic struct kinfo_proc *getproc(void); 9724583Sdarrenr 9824583Sdarrenr 9922514Sdarrenrint kmemcpy(buf, pos, n) 100255332Scy char *buf; 101255332Scy void *pos; 102255332Scy int n; 10322514Sdarrenr{ 10422514Sdarrenr static int kfd = -1; 10531183Speter off_t offset = (u_long)pos; 10622514Sdarrenr 10722514Sdarrenr if (kfd == -1) 10822514Sdarrenr kfd = open(KMEM, O_RDONLY); 10922514Sdarrenr 11031183Speter if (lseek(kfd, offset, SEEK_SET) == -1) 11122514Sdarrenr { 11222514Sdarrenr perror("lseek"); 11322514Sdarrenr return -1; 11422514Sdarrenr } 11522514Sdarrenr if (read(kfd, buf, n) == -1) 11622514Sdarrenr { 11722514Sdarrenr perror("read"); 11822514Sdarrenr return -1; 11922514Sdarrenr } 12022514Sdarrenr return n; 12122514Sdarrenr} 12222514Sdarrenr 12331183Speterstruct nlist names[4] = { 12422514Sdarrenr { "_proc" }, 12522514Sdarrenr { "_nproc" }, 12631183Speter { NULL }, 12722514Sdarrenr { NULL } 12822514Sdarrenr }; 12922514Sdarrenr 13024583Sdarrenrstatic struct kinfo_proc *getproc() 13122514Sdarrenr{ 13222514Sdarrenr static struct kinfo_proc kp; 13322514Sdarrenr pid_t pid = getpid(); 13431183Speter int mib[4]; 13531183Speter size_t n; 13622514Sdarrenr 13722514Sdarrenr mib[0] = CTL_KERN; 13822514Sdarrenr mib[1] = KERN_PROC; 13922514Sdarrenr mib[2] = KERN_PROC_PID; 14022514Sdarrenr mib[3] = pid; 14122514Sdarrenr 14234739Speter n = sizeof(kp); 14322514Sdarrenr if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 14422514Sdarrenr { 14522514Sdarrenr perror("sysctl"); 14622514Sdarrenr return NULL; 14722514Sdarrenr } 14822514Sdarrenr return &kp; 14922514Sdarrenr} 15022514Sdarrenr 15122514Sdarrenr 15222514Sdarrenrstruct tcpcb *find_tcp(tfd, ti) 153255332Scy int tfd; 154255332Scy struct tcpiphdr *ti; 15522514Sdarrenr{ 15622514Sdarrenr struct tcpcb *t; 15722514Sdarrenr struct inpcb *i; 15822514Sdarrenr struct socket *s; 15922514Sdarrenr struct filedesc *fd; 16022514Sdarrenr struct kinfo_proc *p; 16122514Sdarrenr struct file *f, **o; 16222514Sdarrenr 16322514Sdarrenr if (!(p = getproc())) 16422514Sdarrenr return NULL; 16522514Sdarrenr 16622514Sdarrenr fd = (struct filedesc *)malloc(sizeof(*fd)); 167170268Sdarrenr if (fd == NULL) 168170268Sdarrenr return NULL; 169369277Scy#if defined( __FreeBSD__) 17070033Salfred if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 17170033Salfred { 17270033Salfred fprintf(stderr, "read(%#lx,%#lx) failed\n", 17370033Salfred (u_long)p, (u_long)p->ki_fd); 174170268Sdarrenr free(fd); 17570033Salfred return NULL; 17670033Salfred } 17770033Salfred#else 17824583Sdarrenr if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 17922514Sdarrenr { 18022514Sdarrenr fprintf(stderr, "read(%#lx,%#lx) failed\n", 18122514Sdarrenr (u_long)p, (u_long)p->kp_proc.p_fd); 182170268Sdarrenr free(fd); 18322514Sdarrenr return NULL; 18422514Sdarrenr } 18570033Salfred#endif 18622514Sdarrenr 187161357Sguido o = NULL; 188161357Sguido f = NULL; 189161357Sguido s = NULL; 190161357Sguido i = NULL; 191161357Sguido t = NULL; 192161357Sguido 193319175Scy o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o)); 19424583Sdarrenr if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 19522514Sdarrenr { 19631183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 19731183Speter (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 198161357Sguido goto finderror; 19922514Sdarrenr } 20022514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 20124583Sdarrenr if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 20222514Sdarrenr { 20331183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 20431183Speter (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 205161357Sguido goto finderror; 20622514Sdarrenr } 20722514Sdarrenr 20822514Sdarrenr s = (struct socket *)calloc(1, sizeof(*s)); 209109153Sdillon if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 21022514Sdarrenr { 21131183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 212161357Sguido (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 213161357Sguido goto finderror; 21422514Sdarrenr } 21522514Sdarrenr 21622514Sdarrenr i = (struct inpcb *)calloc(1, sizeof(*i)); 21724583Sdarrenr if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 21822514Sdarrenr { 21931183Speter fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 22031183Speter (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 221161357Sguido goto finderror; 22222514Sdarrenr } 22322514Sdarrenr 22422514Sdarrenr t = (struct tcpcb *)calloc(1, sizeof(*t)); 22524583Sdarrenr if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 22622514Sdarrenr { 22731183Speter fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 22831183Speter (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 229161357Sguido goto finderror; 23022514Sdarrenr } 23122514Sdarrenr return (struct tcpcb *)i->inp_ppcb; 232161357Sguido 233161357Sguidofinderror: 234161357Sguido if (o != NULL) 235161357Sguido free(o); 236161357Sguido if (f != NULL) 237161357Sguido free(f); 238161357Sguido if (s != NULL) 239161357Sguido free(s); 240161357Sguido if (i != NULL) 241161357Sguido free(i); 242161357Sguido if (t != NULL) 243161357Sguido free(t); 244161357Sguido return NULL; 24522514Sdarrenr} 24622514Sdarrenr 24724583Sdarrenrint do_socket(dev, mtu, ti, gwip) 248255332Scy char *dev; 249255332Scy int mtu; 250255332Scy struct tcpiphdr *ti; 251255332Scy struct in_addr gwip; 25222514Sdarrenr{ 25322514Sdarrenr struct sockaddr_in rsin, lsin; 25422514Sdarrenr struct tcpcb *t, tcb; 255172776Sdarrenr int fd, nfd; 256172776Sdarrenr socklen_t len; 25722514Sdarrenr 25822514Sdarrenr printf("Dest. Port: %d\n", ti->ti_dport); 25922514Sdarrenr 26022514Sdarrenr fd = socket(AF_INET, SOCK_STREAM, 0); 26122514Sdarrenr if (fd == -1) 26222514Sdarrenr { 26322514Sdarrenr perror("socket"); 26422514Sdarrenr return -1; 26522514Sdarrenr } 26622514Sdarrenr 26722514Sdarrenr if (fcntl(fd, F_SETFL, FNDELAY) == -1) 26822514Sdarrenr { 26922514Sdarrenr perror("fcntl"); 27022514Sdarrenr return -1; 27122514Sdarrenr } 27222514Sdarrenr 27322514Sdarrenr bzero((char *)&lsin, sizeof(lsin)); 27422514Sdarrenr lsin.sin_family = AF_INET; 27522514Sdarrenr bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 27622514Sdarrenr sizeof(struct in_addr)); 27722514Sdarrenr if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 27822514Sdarrenr { 27922514Sdarrenr perror("bind"); 28022514Sdarrenr return -1; 28122514Sdarrenr } 28222514Sdarrenr len = sizeof(lsin); 28322514Sdarrenr (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 28422514Sdarrenr ti->ti_sport = lsin.sin_port; 28522514Sdarrenr printf("sport %d\n", ntohs(lsin.sin_port)); 286161357Sguido 287145519Sdarrenr nfd = initdevice(dev, 1); 288161357Sguido if (nfd == -1) 289161357Sguido return -1; 29022514Sdarrenr 29122514Sdarrenr if (!(t = find_tcp(fd, ti))) 29222514Sdarrenr return -1; 29322514Sdarrenr 29422514Sdarrenr bzero((char *)&rsin, sizeof(rsin)); 29522514Sdarrenr rsin.sin_family = AF_INET; 29622514Sdarrenr bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 29722514Sdarrenr sizeof(struct in_addr)); 29822514Sdarrenr rsin.sin_port = ti->ti_dport; 29922514Sdarrenr if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 30022514Sdarrenr errno != EINPROGRESS) 30122514Sdarrenr { 30222514Sdarrenr perror("connect"); 30322514Sdarrenr return -1; 30422514Sdarrenr } 30524583Sdarrenr KMCPY(&tcb, t, sizeof(tcb)); 30622514Sdarrenr ti->ti_win = tcb.rcv_adv; 30722514Sdarrenr ti->ti_seq = tcb.snd_nxt - 1; 30822514Sdarrenr ti->ti_ack = tcb.rcv_nxt; 30922514Sdarrenr 31024583Sdarrenr if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 31122514Sdarrenr return -1; 31222514Sdarrenr (void)write(fd, "Hello World\n", 12); 31322514Sdarrenr sleep(2); 31422514Sdarrenr close(fd); 31522514Sdarrenr return 0; 31622514Sdarrenr} 317