/* * $Id: libnet_raw.c,v 1.9 2004/02/18 18:19:00 mike Exp $ * * libnet * libnet_raw.c - raw sockets routines * * Copyright (c) 1998 - 2004 Mike D. Schiffman * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "common.h" #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif /* TODO this doesn't make any sense, the code in the #else branch is littered with conditionals on __WIN32__ that are never reachable, what happened? */ #if defined (__WIN32__) int libnet_open_raw4(libnet_t *l) { return (libnet_open_link(l)); } int libnet_open_raw6(libnet_t *l) { return (libnet_open_link(l)); } int libnet_close_raw4(libnet_t *l) { return (libnet_close_link_interface(l)); } int libnet_close_raw6(libnet_t *l) { return (libnet_close_link_interface(l)); } #else static int libnet_finish_setup_socket(libnet_t *l) { #if !(__WIN32__) int n = 1; #if (__svr4__) void *nptr = &n; #else int *nptr = &n; #endif /* __svr4__ */ #else BOOL n; #endif unsigned len; #ifdef SO_BROADCAST /* * man 7 socket * * Set or get the broadcast flag. When enabled, datagram sockets * receive packets sent to a broadcast address and they are allowed * to send packets to a broadcast address. This option has no * effect on stream-oriented sockets. */ if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, nptr, sizeof(n)) == -1) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): set SO_BROADCAST failed: %s", __func__, strerror(errno)); goto bad; } #endif /* SO_BROADCAST */ #if (__linux__) if(l->device != NULL) if(setsockopt(l->fd, SOL_SOCKET, SO_BINDTODEVICE, l->device, strlen(l->device)) == -1) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): set SO_BINDTODEVICE failed: %s", __func__, strerror(errno)); goto bad; } #endif /* __linux__ */ return 0; bad: return (-1); } int libnet_open_raw4(libnet_t *l) { #if !(__WIN32__) int n = 1; #if (__svr4__) void *nptr = &n; #else int *nptr = &n; #endif /* __svr4__ */ #else BOOL n; #endif if (l == NULL) { return (-1); } l->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (l->fd == -1) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): SOCK_RAW allocation failed: %s", __func__, strerror(errno)); goto bad; } #ifdef IP_HDRINCL /* * man raw * * The IPv4 layer generates an IP header when sending a packet unless * the IP_HDRINCL socket option is enabled on the socket. When it * is enabled, the packet must contain an IP header. For * receiving the IP header is always included in the packet. */ #if !(__WIN32__) if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, nptr, sizeof(n)) == -1) #else n = TRUE; if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, &n, sizeof(n)) == -1) #endif { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): set IP_HDRINCL failed: %s", __func__, strerror(errno)); goto bad; } #endif /* IP_HDRINCL */ if (libnet_finish_setup_socket(l) == -1) goto bad; return (l->fd); bad: return (-1); } int libnet_close_raw4(libnet_t *l) { if (l == NULL) { return (-1); } return (close(l->fd)); } #if ((defined HAVE_SOLARIS && !defined HAVE_SOLARIS_IPV6) || defined (__WIN32__)) int libnet_open_raw6(libnet_t *l) { return (-1); } #else int libnet_open_raw6(libnet_t *l) { if (l == NULL) { return (-1); } l->fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW); if (l->fd == -1) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): SOCK_RAW allocation failed: %s", __func__, strerror(errno)); goto bad; } if (libnet_finish_setup_socket(l) == -1) goto bad; return (l->fd); bad: return (-1); } #endif int libnet_close_raw6(libnet_t *l) { if (l == NULL) { return (-1); } return (close(l->fd)); } #endif /** * Local Variables: * indent-tabs-mode: nil * c-file-style: "stroustrup" * End: */