snit.c revision 53024
1/* 2 * (C)opyright 1992-1998 Darren Reed. (from tcplog) 3 * 4 * Redistribution and use in source and binary forms are permitted 5 * provided that this notice is preserved and due credit is given 6 * to the original author and the contributors. 7 */ 8 9#include <stdio.h> 10#include <netdb.h> 11#include <ctype.h> 12#include <signal.h> 13#include <errno.h> 14#include <sys/types.h> 15#include <sys/time.h> 16#include <sys/timeb.h> 17#include <sys/socket.h> 18#include <sys/file.h> 19#include <sys/ioctl.h> 20#include <net/nit.h> 21#include <sys/fcntlcom.h> 22#include <sys/dir.h> 23#include <net/nit_if.h> 24#include <net/nit_pf.h> 25#include <net/nit_buf.h> 26#include <net/packetfilt.h> 27#include <sys/stropts.h> 28 29#include <net/if.h> 30#include <netinet/in.h> 31#include <netinet/in_systm.h> 32#include <netinet/ip.h> 33#include <netinet/if_ether.h> 34#include <netinet/ip_var.h> 35#include <netinet/udp.h> 36#include <netinet/udp_var.h> 37#include <netinet/tcp.h> 38 39#include "ipsend.h" 40 41#if !defined(lint) 42static const char sccsid[] = "@(#)snit.c 1.5 1/11/96 (C)1995 Darren Reed"; 43static const char rcsid[] = "@(#)$Id: snit.c,v 2.1 1999/08/04 17:31:15 darrenr Exp $"; 44#endif 45 46#define CHUNKSIZE 8192 47#define BUFSPACE (4*CHUNKSIZE) 48 49/* 50 * Be careful to only include those defined in the flags option for the 51 * interface are included in the header size. 52 */ 53#define BUFHDR_SIZE (sizeof(struct nit_bufhdr)) 54#define NIT_HDRSIZE (BUFHDR_SIZE) 55 56static int timeout; 57 58 59int initdevice(device, sport, tout) 60char *device; 61int sport, tout; 62{ 63 struct strioctl si; 64 struct timeval to; 65 struct ifreq ifr; 66 int fd; 67 68 if ((fd = open("/dev/nit", O_RDWR)) < 0) 69 { 70 perror("/dev/nit"); 71 exit(-1); 72 } 73 74 /* 75 * arrange to get messages from the NIT STREAM and use NIT_BUF option 76 */ 77 ioctl(fd, I_SRDOPT, (char*)RMSGD); 78 ioctl(fd, I_PUSH, "nbuf"); 79 80 /* 81 * set the timeout 82 */ 83 timeout = tout; 84 si.ic_timout = 1; 85 to.tv_sec = 1; 86 to.tv_usec = 0; 87 si.ic_cmd = NIOCSTIME; 88 si.ic_len = sizeof(to); 89 si.ic_dp = (char*)&to; 90 if (ioctl(fd, I_STR, (char*)&si) == -1) 91 { 92 perror("ioctl: NIT timeout"); 93 exit(-1); 94 } 95 96 /* 97 * request the interface 98 */ 99 strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 100 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' '; 101 si.ic_cmd = NIOCBIND; 102 si.ic_len = sizeof(ifr); 103 si.ic_dp = (char*)𝔦 104 if (ioctl(fd, I_STR, (char*)&si) == -1) 105 { 106 perror(ifr.ifr_name); 107 exit(1); 108 } 109 return fd; 110} 111 112 113/* 114 * output an IP packet onto a fd opened for /dev/nit 115 */ 116int sendip(fd, pkt, len) 117int fd, len; 118char *pkt; 119{ 120 struct sockaddr sk, *sa = &sk; 121 struct strbuf cbuf, *cp = &cbuf, dbuf, *dp = &dbuf; 122 123 /* 124 * For ethernet, need at least 802.3 header and IP header. 125 */ 126 if (len < (sizeof(sa->sa_data) + sizeof(struct ip))) 127 return -1; 128 /* 129 * to avoid any output processing for IP, say we're not. 130 */ 131 sa->sa_family = AF_UNSPEC; 132 bcopy(pkt, sa->sa_data, sizeof(sa->sa_data)); 133 pkt += sizeof(sa->sa_data); 134 len -= sizeof(sa->sa_data); 135 136 /* 137 * construct NIT STREAMS messages, first control then data. 138 */ 139 cp->len = sizeof(*sa); 140 cp->maxlen = sizeof(*sa); 141 cp->buf = (char *)sa; 142 143 dp->buf = pkt; 144 dp->len = len; 145 dp->maxlen = dp->len; 146 147 if (putmsg(fd, cp, dp, 0) == -1) 148 { 149 perror("putmsg"); 150 return -1; 151 } 152 153 if (ioctl(fd, I_FLUSH, FLUSHW) == -1) 154 { 155 perror("I_FLUSH"); 156 return -1; 157 } 158 return len; 159} 160