lsock.c revision 80486
122514Sdarrenr/* 253024Sguido * lsock.c (C) 1995-1998 Darren Reed 322514Sdarrenr * 480486Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 522514Sdarrenr */ 631183Speter#if !defined(lint) 731183Speterstatic const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed"; 880486Sdarrenrstatic const char rcsid[] = "@(#)$Id: lsock.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $"; 922514Sdarrenr#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> 2022514Sdarrenr#include <fcntl.h> 2122514Sdarrenr#include <sys/dir.h> 2222514Sdarrenr#define __KERNEL__ 2322514Sdarrenr#if LINUX >= 0200 2422514Sdarrenr# undef UINT_MAX 2522514Sdarrenr# undef INT_MAX 2622514Sdarrenr# undef ULONG_MAX 2722514Sdarrenr# undef LONG_MAX 2822514Sdarrenr# include <linux/notifier.h> 2922514Sdarrenr#endif 3022514Sdarrenr#include <linux/fs.h> 3122514Sdarrenr#if LINUX >= 0200 3222514Sdarrenr#include "linux/netdevice.h" 3322514Sdarrenr#include "net/sock.h" 3422514Sdarrenr#endif 3522514Sdarrenr#undef __KERNEL__ 3622514Sdarrenr#include <linux/sched.h> 3722514Sdarrenr#include <linux/netdevice.h> 3822514Sdarrenr#include <nlist.h> 3922514Sdarrenr#include <sys/user.h> 4022514Sdarrenr#include <sys/socket.h> 4122514Sdarrenr#include <math.h> 4222514Sdarrenr#include <netinet/in.h> 4322514Sdarrenr#include <netinet/in_systm.h> 4422514Sdarrenr#include <net/if.h> 4531183Speter#if LINUX < 0200 4622514Sdarrenr#include <net/inet/sock.h> 4722514Sdarrenr#endif 4824583Sdarrenr#include "ipsend.h" 4922514Sdarrenr 5022514Sdarrenrint nproc; 5122514Sdarrenrstruct task_struct *proc; 5222514Sdarrenr 5322514Sdarrenr#ifndef KMEM 5422514Sdarrenr# ifdef _PATH_KMEM 5522514Sdarrenr# define KMEM _PATH_KMEM 5622514Sdarrenr# endif 5722514Sdarrenr#endif 5822514Sdarrenr#ifndef KMEM 5922514Sdarrenr# define KMEM "/dev/kmem" 6022514Sdarrenr#endif 6122514Sdarrenr#ifndef KERNEL 6222514Sdarrenr# define KERNEL "/System.map" 6322514Sdarrenr#endif 6422514Sdarrenr 6522514Sdarrenrint kmemcpy(buf, pos, n) 6622514Sdarrenrchar *buf; 6722514Sdarrenrvoid *pos; 6822514Sdarrenrint n; 6922514Sdarrenr{ 7022514Sdarrenr static int kfd = -1; 7122514Sdarrenr 7222514Sdarrenr if (kfd == -1) 7322514Sdarrenr kfd = open(KMEM, O_RDONLY); 7422514Sdarrenr 7522514Sdarrenr if (lseek(kfd, (off_t)pos, SEEK_SET) == -1) 7622514Sdarrenr { 7722514Sdarrenr perror("lseek"); 7822514Sdarrenr return -1; 7922514Sdarrenr } 8022514Sdarrenr if (read(kfd, buf, n) == -1) 8122514Sdarrenr { 8222514Sdarrenr perror("read"); 8322514Sdarrenr return -1; 8422514Sdarrenr } 8522514Sdarrenr return n; 8622514Sdarrenr} 8722514Sdarrenr 8822514Sdarrenrstruct nlist names[3] = { 8922514Sdarrenr { "_task" }, 9022514Sdarrenr { "_nr_tasks" }, 9122514Sdarrenr { NULL } 9222514Sdarrenr }; 9322514Sdarrenr 9422514Sdarrenrstruct task_struct *getproc() 9522514Sdarrenr{ 9622514Sdarrenr struct task_struct *p, **pp; 9722514Sdarrenr void *v; 9822514Sdarrenr pid_t pid = getpid(); 9922514Sdarrenr int siz, n; 10022514Sdarrenr 10122514Sdarrenr n = nlist(KERNEL, names); 10222514Sdarrenr if (n != 0) 10322514Sdarrenr { 10422514Sdarrenr fprintf(stderr, "nlist(%#x) == %d\n", names, n); 10522514Sdarrenr return NULL; 10622514Sdarrenr } 10724583Sdarrenr if (KMCPY(&nproc, names[1].n_value, sizeof(nproc)) == -1) 10822514Sdarrenr { 10922514Sdarrenr fprintf(stderr, "read nproc (%#x)\n", names[1].n_value); 11022514Sdarrenr return NULL; 11122514Sdarrenr } 11222514Sdarrenr siz = nproc * sizeof(struct task_struct *); 11324583Sdarrenr if (KMCPY(&v, names[0].n_value, sizeof(v)) == -1) 11422514Sdarrenr { 11522514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 11622514Sdarrenr names[0].n_value, &v, sizeof(v)); 11722514Sdarrenr return NULL; 11822514Sdarrenr } 11922514Sdarrenr pp = (struct task_struct **)malloc(siz); 12024583Sdarrenr if (KMCPY(pp, v, siz) == -1) 12122514Sdarrenr { 12222514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 12322514Sdarrenr v, pp, siz); 12422514Sdarrenr return NULL; 12522514Sdarrenr } 12622514Sdarrenr proc = (struct task_struct *)malloc(siz); 12722514Sdarrenr for (n = 0; n < NR_TASKS; n++) 12822514Sdarrenr { 12924583Sdarrenr if (KMCPY((proc + n), pp[n], sizeof(*proc)) == -1) 13022514Sdarrenr { 13122514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) proc\n", 13222514Sdarrenr pp[n], proc + n, sizeof(*proc)); 13322514Sdarrenr return NULL; 13422514Sdarrenr } 13522514Sdarrenr } 13622514Sdarrenr 13722514Sdarrenr p = proc; 13822514Sdarrenr 13922514Sdarrenr for (n = NR_TASKS; n; n--, p++) 14022514Sdarrenr if (p->pid == pid) 14122514Sdarrenr break; 14222514Sdarrenr if (!n) 14322514Sdarrenr return NULL; 14422514Sdarrenr 14522514Sdarrenr return p; 14622514Sdarrenr} 14722514Sdarrenr 14822514Sdarrenr 14922514Sdarrenrstruct sock *find_tcp(fd, ti) 15022514Sdarrenrint fd; 15122514Sdarrenrstruct tcpiphdr *ti; 15222514Sdarrenr{ 15322514Sdarrenr struct sock *s; 15422514Sdarrenr struct inode *i; 15522514Sdarrenr struct files_struct *fs; 15622514Sdarrenr struct task_struct *p; 15722514Sdarrenr struct file *f, **o; 15822514Sdarrenr 15922514Sdarrenr if (!(p = getproc())) 16022514Sdarrenr return NULL; 16122514Sdarrenr 16222514Sdarrenr fs = p->files; 16322514Sdarrenr o = (struct file **)calloc(1, sizeof(*o) * (fs->count + 1)); 16424583Sdarrenr if (KMCPY(o, fs->fd, (fs->count + 1) * sizeof(*o)) == -1) 16522514Sdarrenr { 16622514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - fd - failed\n", 16722514Sdarrenr fs->fd, o, sizeof(*o)); 16822514Sdarrenr return NULL; 16922514Sdarrenr } 17022514Sdarrenr f = (struct file *)calloc(1, sizeof(*f)); 17124583Sdarrenr if (KMCPY(f, o[fd], sizeof(*f)) == -1) 17222514Sdarrenr { 17322514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n", 17422514Sdarrenr o[fd], f, sizeof(*f)); 17522514Sdarrenr return NULL; 17622514Sdarrenr } 17722514Sdarrenr 17822514Sdarrenr i = (struct inode *)calloc(1, sizeof(*i)); 17924583Sdarrenr if (KMCPY(i, f->f_inode, sizeof(*i)) == -1) 18022514Sdarrenr { 18122514Sdarrenr fprintf(stderr, "read(%#x,%#x,%d) - f_inode - failed\n", 18222514Sdarrenr f->f_inode, i, sizeof(*i)); 18322514Sdarrenr return NULL; 18422514Sdarrenr } 18522514Sdarrenr return i->u.socket_i.data; 18622514Sdarrenr} 18722514Sdarrenr 18831183Speterint do_socket(dev, mtu, ti, gwip) 18922514Sdarrenrchar *dev; 19022514Sdarrenrint mtu; 19122514Sdarrenrstruct tcpiphdr *ti; 19222514Sdarrenrstruct in_addr gwip; 19322514Sdarrenr{ 19422514Sdarrenr struct sockaddr_in rsin, lsin; 19522514Sdarrenr struct sock *s, sk; 19622514Sdarrenr int fd, nfd, len; 19722514Sdarrenr 19822514Sdarrenr printf("Dest. Port: %d\n", ti->ti_dport); 19922514Sdarrenr 20022514Sdarrenr fd = socket(AF_INET, SOCK_STREAM, 0); 20122514Sdarrenr if (fd == -1) 20222514Sdarrenr { 20322514Sdarrenr perror("socket"); 20422514Sdarrenr return -1; 20522514Sdarrenr } 20622514Sdarrenr 20722514Sdarrenr if (fcntl(fd, F_SETFL, FNDELAY) == -1) 20822514Sdarrenr { 20922514Sdarrenr perror("fcntl"); 21022514Sdarrenr return -1; 21122514Sdarrenr } 21222514Sdarrenr 21322514Sdarrenr bzero((char *)&lsin, sizeof(lsin)); 21422514Sdarrenr lsin.sin_family = AF_INET; 21522514Sdarrenr bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 21622514Sdarrenr sizeof(struct in_addr)); 21722514Sdarrenr if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 21822514Sdarrenr { 21922514Sdarrenr perror("bind"); 22022514Sdarrenr return -1; 22122514Sdarrenr } 22222514Sdarrenr len = sizeof(lsin); 22322514Sdarrenr (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 22422514Sdarrenr ti->ti_sport = lsin.sin_port; 22522514Sdarrenr printf("sport %d\n", ntohs(lsin.sin_port)); 22631183Speter nfd = initdevice(dev, ntohs(lsin.sin_port), 0); 22722514Sdarrenr 22822514Sdarrenr if (!(s = find_tcp(fd, ti))) 22922514Sdarrenr return -1; 23022514Sdarrenr 23122514Sdarrenr bzero((char *)&rsin, sizeof(rsin)); 23222514Sdarrenr rsin.sin_family = AF_INET; 23322514Sdarrenr bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 23422514Sdarrenr sizeof(struct in_addr)); 23522514Sdarrenr rsin.sin_port = ti->ti_dport; 23622514Sdarrenr if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 23722514Sdarrenr errno != EINPROGRESS) 23822514Sdarrenr { 23922514Sdarrenr perror("connect"); 24022514Sdarrenr return -1; 24122514Sdarrenr } 24224583Sdarrenr KMCPY(&sk, s, sizeof(sk)); 24322514Sdarrenr ti->ti_win = sk.window; 24422514Sdarrenr ti->ti_seq = sk.sent_seq - 1; 24522514Sdarrenr ti->ti_ack = sk.rcv_ack_seq; 24631183Speter ti->ti_flags = TH_SYN; 24722514Sdarrenr 24831183Speter if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 24922514Sdarrenr return -1; 25022514Sdarrenr (void)write(fd, "Hello World\n", 12); 25122514Sdarrenr sleep(2); 25222514Sdarrenr close(fd); 25322514Sdarrenr return 0; 25422514Sdarrenr} 255