1145519Sdarrenr/* $FreeBSD: releng/10.2/contrib/ipfilter/ipsend/lsock.c 255332 2013-09-06 23:11:19Z cy $ */ 2145510Sdarrenr 322514Sdarrenr/* 453024Sguido * lsock.c (C) 1995-1998 Darren Reed 522514Sdarrenr * 680486Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145510Sdarrenr * 822514Sdarrenr */ 931183Speter#if !defined(lint) 1031183Speterstatic const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed"; 11255332Scystatic const char rcsid[] = "@(#)$Id$"; 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#if LINUX >= 0200 2722514Sdarrenr# undef UINT_MAX 2822514Sdarrenr# undef INT_MAX 2922514Sdarrenr# undef ULONG_MAX 3022514Sdarrenr# undef LONG_MAX 3122514Sdarrenr# include <linux/notifier.h> 3222514Sdarrenr#endif 3322514Sdarrenr#include <linux/fs.h> 3422514Sdarrenr#if LINUX >= 0200 3522514Sdarrenr#include "linux/netdevice.h" 3622514Sdarrenr#include "net/sock.h" 3722514Sdarrenr#endif 3822514Sdarrenr#undef __KERNEL__ 3922514Sdarrenr#include <linux/sched.h> 4022514Sdarrenr#include <linux/netdevice.h> 4122514Sdarrenr#include <nlist.h> 4222514Sdarrenr#include <sys/user.h> 4322514Sdarrenr#include <sys/socket.h> 4422514Sdarrenr#include <math.h> 4522514Sdarrenr#include <netinet/in.h> 4622514Sdarrenr#include <netinet/in_systm.h> 4722514Sdarrenr#include <net/if.h> 4831183Speter#if LINUX < 0200 4922514Sdarrenr#include <net/inet/sock.h> 5022514Sdarrenr#endif 5124583Sdarrenr#include "ipsend.h" 5222514Sdarrenr 5322514Sdarrenrint nproc; 5422514Sdarrenrstruct task_struct *proc; 5522514Sdarrenr 5622514Sdarrenr#ifndef KMEM 5722514Sdarrenr# ifdef _PATH_KMEM 5822514Sdarrenr# define KMEM _PATH_KMEM 5922514Sdarrenr# endif 6022514Sdarrenr#endif 6122514Sdarrenr#ifndef KMEM 6222514Sdarrenr# define KMEM "/dev/kmem" 6322514Sdarrenr#endif 6422514Sdarrenr#ifndef KERNEL 6522514Sdarrenr# define KERNEL "/System.map" 6622514Sdarrenr#endif 6722514Sdarrenr 6822514Sdarrenrint kmemcpy(buf, pos, n) 69255332Scy char *buf; 70255332Scy void *pos; 71255332Scy int n; 7222514Sdarrenr{ 7322514Sdarrenr static int kfd = -1; 7422514Sdarrenr 7522514Sdarrenr if (kfd == -1) 7622514Sdarrenr kfd = open(KMEM, O_RDONLY); 7722514Sdarrenr 7822514Sdarrenr if (lseek(kfd, (off_t)pos, SEEK_SET) == -1) 7922514Sdarrenr { 8022514Sdarrenr perror("lseek"); 8122514Sdarrenr return -1; 8222514Sdarrenr } 8322514Sdarrenr if (read(kfd, buf, n) == -1) 8422514Sdarrenr { 8522514Sdarrenr perror("read"); 8622514Sdarrenr return -1; 8722514Sdarrenr } 8822514Sdarrenr return n; 8922514Sdarrenr} 9022514Sdarrenr 9122514Sdarrenrstruct nlist names[3] = { 9222514Sdarrenr { "_task" }, 9322514Sdarrenr { "_nr_tasks" }, 9422514Sdarrenr { NULL } 9522514Sdarrenr }; 9622514Sdarrenr 9722514Sdarrenrstruct task_struct *getproc() 9822514Sdarrenr{ 9922514Sdarrenr struct task_struct *p, **pp; 10022514Sdarrenr void *v; 10122514Sdarrenr pid_t pid = getpid(); 10222514Sdarrenr int siz, n; 10322514Sdarrenr 10422514Sdarrenr n = nlist(KERNEL, names); 10522514Sdarrenr if (n != 0) 10622514Sdarrenr { 10722514Sdarrenr fprintf(stderr, "nlist(%#x) == %d\n", names, n); 10822514Sdarrenr return NULL; 10922514Sdarrenr } 11024583Sdarrenr if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 11122514Sdarrenr { 11222514Sdarrenr fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 11322514Sdarrenr return NULL; 11422514Sdarrenr } 11522514Sdarrenr siz = nproc * sizeof(struct task_struct *); 11624583Sdarrenr if (KMCPY(&v, names[0].n_value, sizeof(v)) == -1) 11722514Sdarrenr { 11822514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 11922514Sdarrenr names[0].n_value, &v, sizeof(v)); 12022514Sdarrenr return NULL; 12122514Sdarrenr } 12222514Sdarrenr pp = (struct task_struct **)malloc(siz); 12324583Sdarrenr if (KMCPY(pp, v, siz) == -1) 12422514Sdarrenr { 12522514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 12622514Sdarrenr v, pp, siz); 12722514Sdarrenr return NULL; 12822514Sdarrenr } 12922514Sdarrenr proc = (struct task_struct *)malloc(siz); 13022514Sdarrenr for (n = 0; n < NR_TASKS; n++) 13122514Sdarrenr { 13224583Sdarrenr if (KMCPY((proc + n), pp[n], sizeof(*proc)) == -1) 13322514Sdarrenr { 13422514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 13522514Sdarrenr pp[n], proc + n, sizeof(*proc)); 13622514Sdarrenr return NULL; 13722514Sdarrenr } 13822514Sdarrenr } 13922514Sdarrenr 14022514Sdarrenr p = proc; 14122514Sdarrenr 14222514Sdarrenr for (n = NR_TASKS; n; n--, p++) 14322514Sdarrenr if (p->pid == pid) 14422514Sdarrenr break; 14522514Sdarrenr if (!n) 14622514Sdarrenr return NULL; 14722514Sdarrenr 14822514Sdarrenr return p; 14922514Sdarrenr} 15022514Sdarrenr 15122514Sdarrenr 15222514Sdarrenrstruct sock *find_tcp(fd, ti) 153255332Scy int fd; 154255332Scy struct tcpiphdr *ti; 15522514Sdarrenr{ 15622514Sdarrenr struct sock *s; 15722514Sdarrenr struct inode *i; 15822514Sdarrenr struct files_struct *fs; 15922514Sdarrenr struct task_struct *p; 16022514Sdarrenr struct file *f, **o; 16122514Sdarrenr 16222514Sdarrenr if (!(p = getproc())) 16322514Sdarrenr return NULL; 16422514Sdarrenr 16522514Sdarrenr fs = p->files; 16622514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (fs->count + 1)); 16724583Sdarrenr if (KMCPY(o, fs->fd, (fs->count + 1) * sizeof(*o)) == -1) 16822514Sdarrenr { 16922514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - fd - failed\n", 17022514Sdarrenr fs->fd, o, sizeof(*o)); 17122514Sdarrenr return NULL; 17222514Sdarrenr } 17322514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 17424583Sdarrenr if (KMCPY(f, o[fd], sizeof(*f)) == -1) 17522514Sdarrenr { 17622514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 17722514Sdarrenr o[fd], f, sizeof(*f)); 17822514Sdarrenr return NULL; 17922514Sdarrenr } 18022514Sdarrenr 18122514Sdarrenr i = (struct inode *)calloc(1, sizeof(*i)); 18224583Sdarrenr if (KMCPY(i, f->f_inode, sizeof(*i)) == -1) 18322514Sdarrenr { 18422514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - f_inode - failed\n", 18522514Sdarrenr f->f_inode, i, sizeof(*i)); 18622514Sdarrenr return NULL; 18722514Sdarrenr } 18822514Sdarrenr return i->u.socket_i.data; 18922514Sdarrenr} 19022514Sdarrenr 19131183Speterint do_socket(dev, mtu, ti, gwip) 192255332Scy char *dev; 193255332Scy int mtu; 194255332Scy struct tcpiphdr *ti; 195255332Scy struct in_addr gwip; 19622514Sdarrenr{ 19722514Sdarrenr struct sockaddr_in rsin, lsin; 19822514Sdarrenr struct sock *s, sk; 19922514Sdarrenr int fd, nfd, len; 20022514Sdarrenr 20122514Sdarrenr printf("Dest. Port: %d\n", ti->ti_dport); 20222514Sdarrenr 20322514Sdarrenr fd = socket(AF_INET, SOCK_STREAM, 0); 20422514Sdarrenr if (fd == -1) 20522514Sdarrenr { 20622514Sdarrenr perror("socket"); 20722514Sdarrenr return -1; 20822514Sdarrenr } 20922514Sdarrenr 21022514Sdarrenr if (fcntl(fd, F_SETFL, FNDELAY) == -1) 21122514Sdarrenr { 21222514Sdarrenr perror("fcntl"); 21322514Sdarrenr return -1; 21422514Sdarrenr } 21522514Sdarrenr 21622514Sdarrenr bzero((char *)&lsin, sizeof(lsin)); 21722514Sdarrenr lsin.sin_family = AF_INET; 21822514Sdarrenr bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 21922514Sdarrenr sizeof(struct in_addr)); 22022514Sdarrenr if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 22122514Sdarrenr { 22222514Sdarrenr perror("bind"); 22322514Sdarrenr return -1; 22422514Sdarrenr } 22522514Sdarrenr len = sizeof(lsin); 22622514Sdarrenr (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 22722514Sdarrenr ti->ti_sport = lsin.sin_port; 22822514Sdarrenr printf("sport %d\n", ntohs(lsin.sin_port)); 229145510Sdarrenr nfd = initdevice(dev, 0); 230161357Sguido if (nfd == -1) 231161357Sguido return -1; 23222514Sdarrenr 23322514Sdarrenr if (!(s = find_tcp(fd, ti))) 23422514Sdarrenr return -1; 23522514Sdarrenr 23622514Sdarrenr bzero((char *)&rsin, sizeof(rsin)); 23722514Sdarrenr rsin.sin_family = AF_INET; 23822514Sdarrenr bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 23922514Sdarrenr sizeof(struct in_addr)); 24022514Sdarrenr rsin.sin_port = ti->ti_dport; 24122514Sdarrenr if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 24222514Sdarrenr errno != EINPROGRESS) 24322514Sdarrenr { 24422514Sdarrenr perror("connect"); 24522514Sdarrenr return -1; 24622514Sdarrenr } 24724583Sdarrenr KMCPY(&sk, s, sizeof(sk)); 24822514Sdarrenr ti->ti_win = sk.window; 24922514Sdarrenr ti->ti_seq = sk.sent_seq - 1; 25022514Sdarrenr ti->ti_ack = sk.rcv_ack_seq; 25131183Speter ti->ti_flags = TH_SYN; 25222514Sdarrenr 25331183Speter if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 25422514Sdarrenr return -1; 25522514Sdarrenr (void)write(fd, "Hello World\n", 12); 25622514Sdarrenr sleep(2); 25722514Sdarrenr close(fd); 25822514Sdarrenr return 0; 25922514Sdarrenr} 260