1/* $FreeBSD: releng/10.3/contrib/ipfilter/ipsend/sirix.c 255332 2013-09-06 23:11:19Z cy $ */ 2 3/* 4 * (C)opyright 1992-1998 Darren Reed. 5 * (C)opyright 1997 Marc Boucher. 6 * 7 * See the IPFILTER.LICENCE file for details on licencing. 8 * 9 */ 10#include <stdio.h> 11#include <sys/types.h> 12#include <string.h> 13#include <unistd.h> 14#include <stdlib.h> 15#include <errno.h> 16#include <sys/socket.h> 17#include <sys/ioctl.h> 18 19#include <net/if.h> 20#include <net/raw.h> 21#include <netinet/in.h> 22#include <netinet/in_systm.h> 23#include <netinet/ip.h> 24#include <netinet/if_ether.h> 25#include <netinet/ip_var.h> 26#include "ipsend.h" 27#include <netinet/udp_var.h> 28 29#if !defined(lint) && defined(LIBC_SCCS) 30static char sirix[] = "@(#)sirix.c 1.0 10/9/97 (C)1997 Marc Boucher"; 31#endif 32 33 34int initdevice(char *device, int tout) 35{ 36 int fd; 37 struct sockaddr_raw sr; 38 39 if ((fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN)) < 0) 40 { 41 perror("socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN)"); 42 return -1; 43 } 44 45 memset(&sr, 0, sizeof(sr)); 46 sr.sr_family = AF_RAW; 47 sr.sr_port = ETHERTYPE_IP; 48 strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname)); 49 if (bind(fd, &sr, sizeof(sr)) < 0) 50 { 51 perror("bind AF_RAW"); 52 close(fd); 53 return -1; 54 } 55 return fd; 56} 57 58 59/* 60 * output an IP packet 61 */ 62int sendip(int fd, char *pkt, int len) 63{ 64 struct sockaddr_raw sr; 65 int srlen = sizeof(sr); 66 struct ifreq ifr; 67 struct ether_header *eh = (struct ether_header *)pkt; 68 69 if (getsockname(fd, &sr, &srlen) == -1) 70 { 71 perror("getsockname"); 72 return -1; 73 } 74 75 memset(&ifr, 0, sizeof(ifr)); 76 strncpy(ifr.ifr_name, sr.sr_ifname, sizeof ifr.ifr_name); 77 78 if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) 79 { 80 perror("ioctl SIOCGIFADDR"); 81 return -1; 82 } 83 84 memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost)); 85 86 if (write(fd, pkt, len) == -1) 87 { 88 perror("send"); 89 return -1; 90 } 91 92 return len; 93} 94