141edb306SCy Schubert /* 241edb306SCy Schubert * sock.c (C) 1995-1998 Darren Reed 341edb306SCy Schubert * 441edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing. 541edb306SCy Schubert * 641edb306SCy Schubert */ 741edb306SCy Schubert #include <sys/param.h> 841edb306SCy Schubert #include <sys/types.h> 941edb306SCy Schubert #include <sys/time.h> 1041edb306SCy Schubert #include <sys/stat.h> 1141edb306SCy Schubert #if defined(__NetBSD__) && defined(__vax__) 1241edb306SCy Schubert /* 1341edb306SCy Schubert * XXX need to declare boolean_t for _KERNEL <sys/files.h> 1441edb306SCy Schubert * which ends up including <sys/device.h> for vax. See PR#32907 1541edb306SCy Schubert * for further details. 1641edb306SCy Schubert */ 1741edb306SCy Schubert typedef int boolean_t; 1841edb306SCy Schubert #endif 1941edb306SCy Schubert #include <fcntl.h> 2041edb306SCy Schubert # include <sys/dirent.h> 2141edb306SCy Schubert # ifdef __NetBSD__ 2241edb306SCy Schubert # include <machine/lock.h> 2341edb306SCy Schubert # endif 2441edb306SCy Schubert # ifdef __FreeBSD__ 2541edb306SCy Schubert # define _WANT_FILE 2641edb306SCy Schubert # else 2741edb306SCy Schubert # define _KERNEL 2841edb306SCy Schubert # define KERNEL 2941edb306SCy Schubert # endif 3041edb306SCy Schubert # include <sys/file.h> 3141edb306SCy Schubert # ifdef __FreeBSD__ 3241edb306SCy Schubert # undef _WANT_FILE 3341edb306SCy Schubert # else 3441edb306SCy Schubert # undef _KERNEL 3541edb306SCy Schubert # undef KERNEL 3641edb306SCy Schubert # endif 3741edb306SCy Schubert #include <nlist.h> 3841edb306SCy Schubert #include <sys/user.h> 3941edb306SCy Schubert #include <sys/socket.h> 4041edb306SCy Schubert #define _WANT_SOCKET 4141edb306SCy Schubert #include <sys/socketvar.h> 4241edb306SCy Schubert #include <sys/proc.h> 4341edb306SCy Schubert # include <kvm.h> 4441edb306SCy Schubert #ifdef sun 4541edb306SCy Schubert #include <sys/systm.h> 4641edb306SCy Schubert #include <sys/session.h> 4741edb306SCy Schubert #endif 4841edb306SCy Schubert #include <sys/sysctl.h> 4941edb306SCy Schubert #include <sys/filedesc.h> 5041edb306SCy Schubert #include <paths.h> 5141edb306SCy Schubert #include <math.h> 5241edb306SCy Schubert #include <netinet/in.h> 5341edb306SCy Schubert #include <netinet/in_systm.h> 5441edb306SCy Schubert #include <netinet/ip.h> 5541edb306SCy Schubert #include <netinet/tcp.h> 5641edb306SCy Schubert #include <net/if.h> 5741edb306SCy Schubert # include <net/route.h> 5841edb306SCy Schubert #include <netinet/ip_var.h> 5941edb306SCy Schubert #define _WANT_INPCB 6041edb306SCy Schubert #include <netinet/in_pcb.h> 6141edb306SCy Schubert #include <netinet/tcp_timer.h> 6241edb306SCy Schubert #define _WANT_TCPCB 6341edb306SCy Schubert #include <netinet/tcp_var.h> 6441edb306SCy Schubert #include <stdio.h> 6541edb306SCy Schubert #include <unistd.h> 6641edb306SCy Schubert #include <string.h> 6741edb306SCy Schubert #include <stdlib.h> 6841edb306SCy Schubert #include <stddef.h> 6941edb306SCy Schubert #include <pwd.h> 7041edb306SCy Schubert #include "ipsend.h" 7141edb306SCy Schubert 7241edb306SCy Schubert 7341edb306SCy Schubert int nproc; 7441edb306SCy Schubert struct proc *proc; 7541edb306SCy Schubert 7641edb306SCy Schubert #ifndef KMEM 7741edb306SCy Schubert # ifdef _PATH_KMEM 7841edb306SCy Schubert # define KMEM _PATH_KMEM 7941edb306SCy Schubert # endif 8041edb306SCy Schubert #endif 8141edb306SCy Schubert #ifndef KERNEL 8241edb306SCy Schubert # ifdef _PATH_UNIX 8341edb306SCy Schubert # define KERNEL _PATH_UNIX 8441edb306SCy Schubert # endif 8541edb306SCy Schubert #endif 8641edb306SCy Schubert #ifndef KMEM 8741edb306SCy Schubert # define KMEM "/dev/kmem" 8841edb306SCy Schubert #endif 8941edb306SCy Schubert #ifndef KERNEL 9041edb306SCy Schubert # define KERNEL "/vmunix" 9141edb306SCy Schubert #endif 9241edb306SCy Schubert 9341edb306SCy Schubert 9441edb306SCy Schubert static struct kinfo_proc *getproc(void); 9541edb306SCy Schubert 9641edb306SCy Schubert 97efeb8bffSCy Schubert int 98efeb8bffSCy Schubert kmemcpy(char *buf, void *pos, int n) 9941edb306SCy Schubert { 10041edb306SCy Schubert static int kfd = -1; 10141edb306SCy Schubert off_t offset = (u_long)pos; 10241edb306SCy Schubert 10341edb306SCy Schubert if (kfd == -1) 10441edb306SCy Schubert kfd = open(KMEM, O_RDONLY); 10541edb306SCy Schubert 10641edb306SCy Schubert if (lseek(kfd, offset, SEEK_SET) == -1) 10741edb306SCy Schubert { 10841edb306SCy Schubert perror("lseek"); 109*2582ae57SCy Schubert return (-1); 11041edb306SCy Schubert } 11141edb306SCy Schubert if (read(kfd, buf, n) == -1) 11241edb306SCy Schubert { 11341edb306SCy Schubert perror("read"); 114*2582ae57SCy Schubert return (-1); 11541edb306SCy Schubert } 116*2582ae57SCy Schubert return (n); 11741edb306SCy Schubert } 11841edb306SCy Schubert 11941edb306SCy Schubert struct nlist names[4] = { 12041edb306SCy Schubert { "_proc" }, 12141edb306SCy Schubert { "_nproc" }, 12241edb306SCy Schubert { NULL }, 12341edb306SCy Schubert { NULL } 12441edb306SCy Schubert }; 12541edb306SCy Schubert 126efeb8bffSCy Schubert static struct 127efeb8bffSCy Schubert kinfo_proc *getproc(void) 12841edb306SCy Schubert { 12941edb306SCy Schubert static struct kinfo_proc kp; 13041edb306SCy Schubert pid_t pid = getpid(); 13141edb306SCy Schubert int mib[4]; 13241edb306SCy Schubert size_t n; 13341edb306SCy Schubert 13441edb306SCy Schubert mib[0] = CTL_KERN; 13541edb306SCy Schubert mib[1] = KERN_PROC; 13641edb306SCy Schubert mib[2] = KERN_PROC_PID; 13741edb306SCy Schubert mib[3] = pid; 13841edb306SCy Schubert 13941edb306SCy Schubert n = sizeof(kp); 14041edb306SCy Schubert if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 14141edb306SCy Schubert { 14241edb306SCy Schubert perror("sysctl"); 143*2582ae57SCy Schubert return (NULL); 14441edb306SCy Schubert } 145*2582ae57SCy Schubert return (&kp); 14641edb306SCy Schubert } 14741edb306SCy Schubert 14841edb306SCy Schubert 149efeb8bffSCy Schubert struct tcpcb * 150efeb8bffSCy Schubert find_tcp(int tfd, struct tcpiphdr *ti) 15141edb306SCy Schubert { 15241edb306SCy Schubert struct tcpcb *t; 15341edb306SCy Schubert struct inpcb *i; 15441edb306SCy Schubert struct socket *s; 15541edb306SCy Schubert struct filedesc *fd; 15641edb306SCy Schubert struct kinfo_proc *p; 15741edb306SCy Schubert struct file *f, **o; 15841edb306SCy Schubert 15941edb306SCy Schubert if (!(p = getproc())) 160*2582ae57SCy Schubert return (NULL); 16141edb306SCy Schubert 16241edb306SCy Schubert fd = (struct filedesc *)malloc(sizeof(*fd)); 16341edb306SCy Schubert if (fd == NULL) 164*2582ae57SCy Schubert return (NULL); 16541edb306SCy Schubert #if defined( __FreeBSD__) 16641edb306SCy Schubert if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 16741edb306SCy Schubert { 16841edb306SCy Schubert fprintf(stderr, "read(%#lx,%#lx) failed\n", 16941edb306SCy Schubert (u_long)p, (u_long)p->ki_fd); 17041edb306SCy Schubert free(fd); 171*2582ae57SCy Schubert return (NULL); 17241edb306SCy Schubert } 17341edb306SCy Schubert #else 17441edb306SCy Schubert if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 17541edb306SCy Schubert { 17641edb306SCy Schubert fprintf(stderr, "read(%#lx,%#lx) failed\n", 17741edb306SCy Schubert (u_long)p, (u_long)p->kp_proc.p_fd); 17841edb306SCy Schubert free(fd); 179*2582ae57SCy Schubert return (NULL); 18041edb306SCy Schubert } 18141edb306SCy Schubert #endif 18241edb306SCy Schubert 18341edb306SCy Schubert o = NULL; 18441edb306SCy Schubert f = NULL; 18541edb306SCy Schubert s = NULL; 18641edb306SCy Schubert i = NULL; 18741edb306SCy Schubert t = NULL; 18841edb306SCy Schubert 18941edb306SCy Schubert o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o)); 19041edb306SCy Schubert if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 19141edb306SCy Schubert { 19241edb306SCy Schubert fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 19341edb306SCy Schubert (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 19441edb306SCy Schubert goto finderror; 19541edb306SCy Schubert } 19641edb306SCy Schubert f = (struct file *)calloc(1, sizeof(*f)); 19741edb306SCy Schubert if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 19841edb306SCy Schubert { 19941edb306SCy Schubert fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 20041edb306SCy Schubert (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 20141edb306SCy Schubert goto finderror; 20241edb306SCy Schubert } 20341edb306SCy Schubert 20441edb306SCy Schubert s = (struct socket *)calloc(1, sizeof(*s)); 20541edb306SCy Schubert if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 20641edb306SCy Schubert { 20741edb306SCy Schubert fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 20841edb306SCy Schubert (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 20941edb306SCy Schubert goto finderror; 21041edb306SCy Schubert } 21141edb306SCy Schubert 21241edb306SCy Schubert i = (struct inpcb *)calloc(1, sizeof(*i)); 21341edb306SCy Schubert if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 21441edb306SCy Schubert { 21541edb306SCy Schubert fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 21641edb306SCy Schubert (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 21741edb306SCy Schubert goto finderror; 21841edb306SCy Schubert } 21941edb306SCy Schubert 22041edb306SCy Schubert t = (struct tcpcb *)calloc(1, sizeof(*t)); 22141edb306SCy Schubert if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 22241edb306SCy Schubert { 22341edb306SCy Schubert fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 22441edb306SCy Schubert (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 22541edb306SCy Schubert goto finderror; 22641edb306SCy Schubert } 22741edb306SCy Schubert return (struct tcpcb *)i->inp_ppcb; 22841edb306SCy Schubert 22941edb306SCy Schubert finderror: 23041edb306SCy Schubert if (o != NULL) 23141edb306SCy Schubert free(o); 23241edb306SCy Schubert if (f != NULL) 23341edb306SCy Schubert free(f); 23441edb306SCy Schubert if (s != NULL) 23541edb306SCy Schubert free(s); 23641edb306SCy Schubert if (i != NULL) 23741edb306SCy Schubert free(i); 23841edb306SCy Schubert if (t != NULL) 23941edb306SCy Schubert free(t); 240*2582ae57SCy Schubert return (NULL); 24141edb306SCy Schubert } 24241edb306SCy Schubert 243efeb8bffSCy Schubert int 244efeb8bffSCy Schubert do_socket(char *dev, int mtu, struct tcpiphdr *ti, struct in_addr gwip) 24541edb306SCy Schubert { 24641edb306SCy Schubert struct sockaddr_in rsin, lsin; 24741edb306SCy Schubert struct tcpcb *t, tcb; 24841edb306SCy Schubert int fd, nfd; 24941edb306SCy Schubert socklen_t len; 25041edb306SCy Schubert 25141edb306SCy Schubert printf("Dest. Port: %d\n", ti->ti_dport); 25241edb306SCy Schubert 25341edb306SCy Schubert fd = socket(AF_INET, SOCK_STREAM, 0); 25441edb306SCy Schubert if (fd == -1) 25541edb306SCy Schubert { 25641edb306SCy Schubert perror("socket"); 257*2582ae57SCy Schubert return (-1); 25841edb306SCy Schubert } 25941edb306SCy Schubert 26041edb306SCy Schubert if (fcntl(fd, F_SETFL, FNDELAY) == -1) 26141edb306SCy Schubert { 26241edb306SCy Schubert perror("fcntl"); 263*2582ae57SCy Schubert return (-1); 26441edb306SCy Schubert } 26541edb306SCy Schubert 26641edb306SCy Schubert bzero((char *)&lsin, sizeof(lsin)); 26741edb306SCy Schubert lsin.sin_family = AF_INET; 26841edb306SCy Schubert bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 26941edb306SCy Schubert sizeof(struct in_addr)); 27041edb306SCy Schubert if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 27141edb306SCy Schubert { 27241edb306SCy Schubert perror("bind"); 273*2582ae57SCy Schubert return (-1); 27441edb306SCy Schubert } 27541edb306SCy Schubert len = sizeof(lsin); 27641edb306SCy Schubert (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 27741edb306SCy Schubert ti->ti_sport = lsin.sin_port; 27841edb306SCy Schubert printf("sport %d\n", ntohs(lsin.sin_port)); 27941edb306SCy Schubert 28041edb306SCy Schubert nfd = initdevice(dev, 1); 28141edb306SCy Schubert if (nfd == -1) 282*2582ae57SCy Schubert return (-1); 28341edb306SCy Schubert 28441edb306SCy Schubert if (!(t = find_tcp(fd, ti))) 285*2582ae57SCy Schubert return (-1); 28641edb306SCy Schubert 28741edb306SCy Schubert bzero((char *)&rsin, sizeof(rsin)); 28841edb306SCy Schubert rsin.sin_family = AF_INET; 28941edb306SCy Schubert bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 29041edb306SCy Schubert sizeof(struct in_addr)); 29141edb306SCy Schubert rsin.sin_port = ti->ti_dport; 29241edb306SCy Schubert if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 29341edb306SCy Schubert errno != EINPROGRESS) 29441edb306SCy Schubert { 29541edb306SCy Schubert perror("connect"); 296*2582ae57SCy Schubert return (-1); 29741edb306SCy Schubert } 29841edb306SCy Schubert KMCPY(&tcb, t, sizeof(tcb)); 29941edb306SCy Schubert ti->ti_win = tcb.rcv_adv; 30041edb306SCy Schubert ti->ti_seq = tcb.snd_nxt - 1; 30141edb306SCy Schubert ti->ti_ack = tcb.rcv_nxt; 30241edb306SCy Schubert 30341edb306SCy Schubert if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 304*2582ae57SCy Schubert return (-1); 30541edb306SCy Schubert (void)write(fd, "Hello World\n", 12); 30641edb306SCy Schubert sleep(2); 30741edb306SCy Schubert close(fd); 308*2582ae57SCy Schubert return (0); 30941edb306SCy Schubert } 310