File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_raw.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 11:54:42 2013 UTC (11 years ago) by misho
Branches: libnet, MAIN
CVS tags: v1_1_6p5, v1_1_6p4, v1_1_6p0, v1_1_6, HEAD
1.1.6

    1: /*
    2:  *  $Id: libnet_raw.c,v 1.1.1.2 2013/07/22 11:54:42 misho Exp $
    3:  *
    4:  *  libnet
    5:  *  libnet_raw.c - raw sockets routines
    6:  *
    7:  *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
    8:  *  All rights reserved.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  *
   19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29:  * SUCH DAMAGE.
   30:  *
   31:  */
   32: 
   33: #if (HAVE_CONFIG_H)
   34: #include "../include/config.h"
   35: #endif
   36: #if (!(_WIN32) || (__CYGWIN__)) 
   37: #include "../include/libnet.h"
   38: #else
   39: #include "../include/win32/libnet.h"
   40: #endif
   41: 
   42: #if defined (__WIN32__)
   43: int
   44: libnet_open_raw4(libnet_t *l)
   45: {
   46:     return (libnet_open_link(l));
   47: }
   48: 
   49: int
   50: libnet_open_raw6(libnet_t *l)
   51: {
   52:     return (libnet_open_link(l));
   53: }
   54: 
   55: int
   56: libnet_close_raw4(libnet_t *l)
   57: {
   58:     return (libnet_close_link_interface(l));
   59: }
   60: 
   61: int
   62: libnet_close_raw6(libnet_t *l)
   63: {
   64:     return (libnet_close_link_interface(l));
   65: }
   66: #else
   67: int
   68: libnet_open_raw4(libnet_t *l)
   69: {
   70:     int len; /* now supposed to be socklen_t, but maybe old systems used int? */
   71: 
   72: #if !(__WIN32__)
   73:      int n = 1;
   74: #if (__svr4__)
   75:      void *nptr = &n;
   76: #else
   77:     int *nptr = &n;
   78: #endif  /* __svr4__ */
   79: #else 
   80: 	BOOL n;
   81: #endif
   82: 
   83:     if (l == NULL)
   84:     { 
   85:         return (-1);
   86:     } 
   87: 
   88:     l->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
   89:     if (l->fd == -1)
   90:     {
   91:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
   92:                 "%s(): SOCK_RAW allocation failed: %s\n",
   93: 		 __func__, strerror(errno));
   94:         goto bad;
   95:     }
   96: 
   97: #ifdef IP_HDRINCL
   98: /* 
   99:  * man raw
  100:  *
  101:  * The IPv4 layer generates an IP header when sending a packet unless
  102:  * the IP_HDRINCL socket option is enabled on the socket.  When it
  103:  * is enabled, the packet must contain an IP header.  For
  104:  * receiving the IP header is always included in the packet.
  105:  */
  106: #if !(__WIN32__)
  107:     if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, nptr, sizeof(n)) == -1)
  108: #else
  109:     n = TRUE;
  110:     if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, &n, sizeof(n)) == -1)
  111: #endif
  112: 
  113:     {
  114:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
  115:                 "%s(): set IP_HDRINCL failed: %s\n",
  116:                 __func__, strerror(errno));
  117:         goto bad;
  118:     }
  119: #endif /*  IP_HDRINCL  */
  120: 
  121: #ifdef SO_SNDBUF
  122: 
  123: /*
  124:  * man 7 socket 
  125:  *
  126:  * Sets and  gets  the  maximum  socket  send buffer in bytes. 
  127:  *
  128:  * Taken from libdnet by Dug Song
  129:  */
  130:     len = sizeof(n);
  131:     if (getsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, &len) < 0)
  132:     {
  133:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
  134: 		 "%s(): get SO_SNDBUF failed: %s\n",
  135: 		 __func__, strerror(errno));
  136:         goto bad;
  137:     }
  138:     
  139:     for (n += 128; n < 1048576; n += 128)
  140:     {
  141:         if (setsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, len) < 0) 
  142:         {
  143:             if (errno == ENOBUFS)
  144:             {
  145:                 break;
  146:             }
  147:              snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
  148:                      "%s(): set SO_SNDBUF failed: %s\n",
  149:                      __func__, strerror(errno));
  150:              goto bad;
  151:         }
  152:     }
  153: #endif
  154: 
  155: #ifdef SO_BROADCAST
  156: /*
  157:  * man 7 socket
  158:  *
  159:  * Set or get the broadcast flag. When  enabled,  datagram  sockets
  160:  * receive packets sent to a broadcast address and they are allowed
  161:  * to send packets to a broadcast  address.   This  option  has  no
  162:  * effect on stream-oriented sockets.
  163:  */
  164:     if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, nptr, sizeof(n)) == -1)
  165:     {
  166:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  167:                 "%s(): set SO_BROADCAST failed: %s\n",
  168:                 __func__, strerror(errno));
  169:         goto bad;
  170:     }
  171: #endif  /*  SO_BROADCAST  */
  172:     return (l->fd);
  173: 
  174: bad:
  175:     return (-1);    
  176: }
  177: 
  178: 
  179: int
  180: libnet_close_raw4(libnet_t *l)
  181: {
  182:     if (l == NULL)
  183:     { 
  184:         return (-1);
  185:     }
  186: 
  187:     return (close(l->fd));
  188: }
  189: 
  190: #if ((defined HAVE_SOLARIS && !defined HAVE_SOLARIS_IPV6) || defined (__WIN32__))
  191: int libnet_open_raw6(libnet_t *l)
  192: {
  193: 	return (-1);
  194: }
  195: 
  196: #else
  197: int
  198: libnet_open_raw6(libnet_t *l)
  199: {
  200: #if !(__WIN32__)
  201: #if (__svr4__)
  202:      int one = 1;
  203:      void *oneptr = &one;
  204: #else
  205: #if (__linux__)
  206:     int one = 1;
  207:     int *oneptr = &one;
  208: #endif
  209: #endif  /* __svr4__ */
  210: #else
  211:     BOOL one;
  212: #endif
  213: 
  214: /* Solaris IPv6 stuff */
  215:     
  216:     if (l == NULL)
  217:     { 
  218:         return (-1);
  219:     } 
  220: 
  221:     l->fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
  222:     if (l->fd == -1)
  223:     {
  224:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
  225:                 "%s(): SOCK_RAW allocation failed: %s\n", __func__,
  226:                 strerror(errno));
  227:         goto bad;
  228:     }
  229: 
  230: #if (__linux__)
  231:     if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, oneptr, sizeof(one)) == -1)
  232:     {
  233:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  234:                 "%s(): set SO_BROADCAST failed: %s\n", __func__,
  235:                 strerror(errno));
  236:         goto bad;
  237:     }
  238:     if(l->device != NULL)
  239:         if(setsockopt(l->fd, SOL_SOCKET, SO_BINDTODEVICE, l->device, strlen(l->device)) == -1) {
  240:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  241:                 "%s(): set SO_BINDTODEVICE failed: %s\n", __func__, strerror(errno));
  242:             goto bad;
  243:         }
  244: 
  245: #endif  /* __linux__ */
  246:     return (l->fd);
  247: 
  248: bad:
  249:     return (-1);    
  250: }
  251: #endif
  252: 
  253: int
  254: libnet_close_raw6(libnet_t *l)
  255: {
  256:     if (l == NULL)
  257:     { 
  258:          return (-1);
  259:     }
  260:     return (close(l->fd));
  261: }
  262: #endif
  263: /* EOF */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>