Annotation of embedaddon/libnet/src/libnet_raw.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:  *  $Id: libnet_raw.c,v 1.9 2004/02/18 18:19:00 mike 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: 
1.1.1.3 ! misho      33: #include "common.h"
        !            34: 
        !            35: #ifndef HAVE_SOCKLEN_T
        !            36: typedef int socklen_t;
1.1       misho      37: #endif
                     38: 
1.1.1.3 ! misho      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:    */
1.1       misho      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: 
1.1.1.3 ! misho      68: static int libnet_finish_setup_socket(libnet_t *l)
        !            69: {
1.1       misho      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
1.1.1.3 ! misho      78:        BOOL n;
1.1       misho      79: #endif
1.1.1.3 ! misho      80:     unsigned len;
1.1       misho      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:     {
1.1.1.3 ! misho      94:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
        !            95:                 "%s(): get SO_SNDBUF failed: %s",
1.1       misho      96:                 __func__, strerror(errno));
                     97:         goto bad;
                     98:     }
                     99:     
                    100:     for (n += 128; n < 1048576; n += 128)
                    101:     {
1.1.1.3 ! misho     102:         if (setsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, len) < 0)
1.1       misho     103:         {
                    104:             if (errno == ENOBUFS)
                    105:             {
                    106:                 break;
                    107:             }
1.1.1.3 ! misho     108:              snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
        !           109:                      "%s(): set SO_SNDBUF failed: %s",
1.1       misho     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,
1.1.1.3 ! misho     128:                 "%s(): set SO_BROADCAST failed: %s",
1.1       misho     129:                 __func__, strerror(errno));
                    130:         goto bad;
                    131:     }
                    132: #endif  /*  SO_BROADCAST  */
1.1.1.3 ! misho     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: 
1.1       misho     208:     return (l->fd);
                    209: 
                    210: bad:
1.1.1.3 ! misho     211:     return (-1);
1.1       misho     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: 
1.1.1.2   misho     241:     l->fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
1.1       misho     242:     if (l->fd == -1)
                    243:     {
                    244:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, 
1.1.1.3 ! misho     245:                 "%s(): SOCK_RAW allocation failed: %s", __func__,
1.1       misho     246:                 strerror(errno));
                    247:         goto bad;
                    248:     }
                    249: 
1.1.1.3 ! misho     250: 
        !           251:     if (libnet_finish_setup_socket(l) == -1)
1.1       misho     252:         goto bad;
1.1.1.2   misho     253: 
1.1       misho     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
1.1.1.3 ! misho     271: 
        !           272: /**
        !           273:  * Local Variables:
        !           274:  *  indent-tabs-mode: nil
        !           275:  *  c-file-style: "stroustrup"
        !           276:  * End:
        !           277:  */

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