File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_raw.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:11:38 2023 UTC (12 months, 3 weeks ago) by misho
Branches: libnet, MAIN
CVS tags: v1_2p1, HEAD
Version 1.2p1

    1: /*
    2:  *  $Id: libnet_raw.c,v 1.1.1.3 2023/09/27 11:11:38 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: #include "common.h"
   34: 
   35: #ifndef HAVE_SOCKLEN_T
   36: typedef int socklen_t;
   37: #endif
   38: 
   39: /* TODO this doesn't make any sense, the code in the #else branch is littered
   40:    with conditionals on __WIN32__ that are never reachable, what happened?
   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: 
   68: static int libnet_finish_setup_socket(libnet_t *l)
   69: {
   70: #if !(__WIN32__)
   71:      int n = 1;
   72: #if (__svr4__)
   73:      void *nptr = &n;
   74: #else
   75:     int *nptr = &n;
   76: #endif  /* __svr4__ */
   77: #else
   78: 	BOOL n;
   79: #endif
   80:     unsigned len;
   81: 
   82: #ifdef SO_SNDBUF
   83: 
   84: /*
   85:  * man 7 socket 
   86:  *
   87:  * Sets and  gets  the  maximum  socket  send buffer in bytes. 
   88:  *
   89:  * Taken from libdnet by Dug Song
   90:  */
   91:     len = sizeof(n);
   92:     if (getsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, &len) < 0)
   93:     {
   94:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
   95: 		 "%s(): get SO_SNDBUF failed: %s",
   96: 		 __func__, strerror(errno));
   97:         goto bad;
   98:     }
   99:     
  100:     for (n += 128; n < 1048576; n += 128)
  101:     {
  102:         if (setsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, len) < 0)
  103:         {
  104:             if (errno == ENOBUFS)
  105:             {
  106:                 break;
  107:             }
  108:              snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  109:                      "%s(): set SO_SNDBUF failed: %s",
  110:                      __func__, strerror(errno));
  111:              goto bad;
  112:         }
  113:     }
  114: #endif
  115: 
  116: #ifdef SO_BROADCAST
  117: /*
  118:  * man 7 socket
  119:  *
  120:  * Set or get the broadcast flag. When  enabled,  datagram  sockets
  121:  * receive packets sent to a broadcast address and they are allowed
  122:  * to send packets to a broadcast  address.   This  option  has  no
  123:  * effect on stream-oriented sockets.
  124:  */
  125:     if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, nptr, sizeof(n)) == -1)
  126:     {
  127:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  128:                 "%s(): set SO_BROADCAST failed: %s",
  129:                 __func__, strerror(errno));
  130:         goto bad;
  131:     }
  132: #endif  /*  SO_BROADCAST  */
  133: 
  134: #if (__linux__)
  135:     if(l->device != NULL)
  136:         if(setsockopt(l->fd, SOL_SOCKET, SO_BINDTODEVICE, l->device, strlen(l->device)) == -1) {
  137:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  138:                 "%s(): set SO_BINDTODEVICE failed: %s", __func__, strerror(errno));
  139:             goto bad;
  140:         }
  141: #endif  /* __linux__ */
  142: 
  143:     return 0;
  144: 
  145: bad:
  146:     return (-1);
  147: }
  148: 
  149: 
  150: 
  151: 
  152: int
  153: libnet_open_raw4(libnet_t *l)
  154: {
  155: #if !(__WIN32__)
  156:      int n = 1;
  157: #if (__svr4__)
  158:      void *nptr = &n;
  159: #else
  160:     int *nptr = &n;
  161: #endif  /* __svr4__ */
  162: #else
  163: 	BOOL n;
  164: #endif
  165: 
  166:     if (l == NULL)
  167:     {
  168:         return (-1);
  169:     }
  170: 
  171:     l->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  172:     if (l->fd == -1)
  173:     {
  174:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  175:                 "%s(): SOCK_RAW allocation failed: %s",
  176: 		 __func__, strerror(errno));
  177:         goto bad;
  178:     }
  179: 
  180: #ifdef IP_HDRINCL
  181: /*
  182:  * man raw
  183:  *
  184:  * The IPv4 layer generates an IP header when sending a packet unless
  185:  * the IP_HDRINCL socket option is enabled on the socket.  When it
  186:  * is enabled, the packet must contain an IP header.  For
  187:  * receiving the IP header is always included in the packet.
  188:  */
  189: #if !(__WIN32__)
  190:     if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, nptr, sizeof(n)) == -1)
  191: #else
  192:     n = TRUE;
  193:     if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, &n, sizeof(n)) == -1)
  194: #endif
  195: 
  196:     {
  197:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  198:                 "%s(): set IP_HDRINCL failed: %s",
  199:                 __func__, strerror(errno));
  200:         goto bad;
  201:     }
  202: #endif /*  IP_HDRINCL  */
  203: 
  204: 
  205:     if (libnet_finish_setup_socket(l) == -1)
  206:         goto bad;
  207: 
  208:     return (l->fd);
  209: 
  210: bad:
  211:     return (-1);
  212: }
  213: 
  214: 
  215: int
  216: libnet_close_raw4(libnet_t *l)
  217: {
  218:     if (l == NULL)
  219:     { 
  220:         return (-1);
  221:     }
  222: 
  223:     return (close(l->fd));
  224: }
  225: 
  226: #if ((defined HAVE_SOLARIS && !defined HAVE_SOLARIS_IPV6) || defined (__WIN32__))
  227: int libnet_open_raw6(libnet_t *l)
  228: {
  229: 	return (-1);
  230: }
  231: 
  232: #else
  233: int
  234: libnet_open_raw6(libnet_t *l)
  235: {
  236:     if (l == NULL)
  237:     { 
  238:         return (-1);
  239:     } 
  240: 
  241:     l->fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
  242:     if (l->fd == -1)
  243:     {
  244:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
  245:                 "%s(): SOCK_RAW allocation failed: %s", __func__,
  246:                 strerror(errno));
  247:         goto bad;
  248:     }
  249: 
  250: 
  251:     if (libnet_finish_setup_socket(l) == -1)
  252:         goto bad;
  253: 
  254:     return (l->fd);
  255: 
  256: bad:
  257:     return (-1);    
  258: }
  259: #endif
  260: 
  261: int
  262: libnet_close_raw6(libnet_t *l)
  263: {
  264:     if (l == NULL)
  265:     { 
  266:          return (-1);
  267:     }
  268:     return (close(l->fd));
  269: }
  270: #endif
  271: 
  272: /**
  273:  * Local Variables:
  274:  *  indent-tabs-mode: nil
  275:  *  c-file-style: "stroustrup"
  276:  * End:
  277:  */

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