File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / src / libnet_link_snoop.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 (9 months, 1 week ago) by misho
Branches: libnet, MAIN
CVS tags: v1_2p1, HEAD
Version 1.2p1

    1: /*
    2:  *  $Id: libnet_link_snoop.c,v 1.1.1.3 2023/09/27 11:11:38 misho Exp $
    3:  *
    4:  *  libnet
    5:  *  libnet_snoop.c - snoop routines
    6:  *
    7:  *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
    8:  *  All rights reserved.
    9:  *
   10:  * Copyright (c) 1993, 1994, 1995, 1996, 1997
   11:  * The Regents of the University of California.  All rights reserved.
   12:  *
   13:  * Redistribution and use in source and binary forms, with or without
   14:  * modification, are permitted provided that: (1) source code distributions
   15:  * retain the above copyright notice and this paragraph in its entirety, (2)
   16:  * distributions including binary code include the above copyright notice and
   17:  * this paragraph in its entirety in the documentation or other materials
   18:  * provided with the distribution, and (3) all advertising materials mentioning
   19:  * features or use of this software display the following acknowledgement:
   20:  * ``This product includes software developed by the University of California,
   21:  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
   22:  * the University nor the names of its contributors may be used to endorse
   23:  * or promote products derived from this software without specific prior
   24:  * written permission.
   25:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
   26:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   27:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   28:  */
   29: 
   30: #include "common.h"
   31: 
   32: #include <sys/param.h>
   33: #include <sys/file.h>
   34: #include <netinet/in.h>
   35: #include <netinet/udp.h>
   36: #include <netinet/tcp.h>
   37: 
   38: #include <net/raw.h>
   39: #include <net/if.h>
   40: 
   41: #include <netinet/ip_var.h>
   42: #include <netinet/if_ether.h>
   43: #include <netinet/udp_var.h>
   44: 
   45: #include "../include/gnuc.h"
   46: #include "../include/bpf.h"
   47: #ifdef HAVE_OS_PROTO_H
   48: #include "../include/os-proto.h"
   49: #endif
   50: 
   51: 
   52: /**
   53:  *
   54:  */
   55: int
   56: libnet_open_link(libnet_t *l)
   57: {
   58:     int fd;
   59:     struct sockaddr_raw sr;
   60:     uint v;
   61: 
   62:     if (l == NULL)
   63:     {
   64:         return -1;
   65:     }
   66: 
   67:     l->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN);
   68: 
   69:     if (l->fd < 0)
   70:     {
   71:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
   72:                  "drain socket: %s", strerror(errno));
   73:         goto bad;
   74:     }
   75: 
   76:     memset(&sr, 0, sizeof(sr));
   77:     sr.sr_family = AF_RAW;
   78:     strncpy(sr.sr_ifname, l->device, sizeof(sr.sr_ifname) - 1);
   79:     sr.sr_ifname[sizeof(sr.sr_ifname) - 1] = '\0';
   80: 
   81:     if (bind(l->fd, (struct sockaddr *)&sr, sizeof(sr)))
   82:     {
   83:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
   84:                  "drain bind: %s", strerror(errno));
   85:         goto bad;
   86:     }
   87: 
   88:     /*
   89:      * XXX hack - map device name to link layer type
   90:      */
   91:     if (strncmp("et", l->device, 2) == 0      ||   /* Challenge 10 Mbit */
   92:             strncmp("ec", l->device, 2) == 0  ||   /* Indigo/Indy 10 Mbit, O2 10/100 */
   93:             strncmp("ef", l->device, 2) == 0  ||   /* O200/2000 10/100 Mbit */
   94:             strncmp("gfe", l->device, 3) == 0 ||   /* GIO 100 Mbit */
   95:             strncmp("fxp", l->device, 3) == 0 ||   /* Challenge VME Enet */
   96:             strncmp("ep", l->device, 2) == 0  ||   /* Challenge 8x10 Mbit EPLEX */
   97:             strncmp("vfe", l->device, 3) == 0 ||   /* Challenge VME 100Mbit */
   98:             strncmp("fa", l->device, 2) == 0  ||
   99:             strncmp("qaa", l->device, 3) == 0)
  100:     {
  101:         l->link_type = DLT_EN10MB;
  102:     }
  103:     else if (strncmp("ipg", l->device, 3) == 0 ||
  104:             strncmp("rns", l->device, 3) == 0 ||        /* O2/200/2000 FDDI */
  105:             strncmp("xpi", l->device, 3) == 0)
  106:     {
  107:         l->link_type = DLT_FDDI;
  108:     }
  109:     else if (strncmp("ppp", l->device, 3) == 0)
  110:     {
  111:         l->link_type = DLT_RAW;
  112:     }
  113:     else if (strncmp("lo", l->device, 2) == 0)
  114:     {
  115:         l->link_type = DLT_NULL;
  116:     }
  117:     else
  118:     {
  119:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  120:                  "drain: unknown physical layer type");
  121:         goto bad;
  122:     }
  123: 
  124:     return 1;
  125: bad:
  126:     close(fd);
  127:     free(l);
  128:     return -1;
  129: }
  130: 
  131: 
  132: int
  133: libnet_close_link(libnet_t *l)
  134: {
  135:     if (close(l->fd) == 0)
  136:     {
  137:         return (1);
  138:     }
  139:     else
  140:     {
  141:         return (-1);
  142:     }
  143: }
  144: 
  145: 
  146: int
  147: libnet_write_link(libnet_t *l, const uint8_t *buf, uint32_t len)
  148: {
  149:     int c;
  150:     struct ifreq ifr;
  151:     struct ether_header *eh = (struct ether_header *)buf;
  152: 
  153:     memset(&ifr, 0, sizeof(ifr));
  154:     strncpy(ifr.ifr_name, l->device, sizeof(ifr.ifr_name));
  155: 
  156:     if (ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
  157:     {
  158:         perror("ioctl SIOCGIFADDR");
  159:         return (-1);
  160:     }
  161: 
  162:     memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost));
  163: 
  164:     if (write(l->fd, buf, len) == -1)
  165:     {
  166:         /* err */
  167:         return (-1);
  168:     }
  169: 
  170:     return (len);
  171: }
  172: 
  173: struct libnet_ether_addr *
  174: libnet_get_hwaddr(libnet_t *l)
  175: {
  176:     struct ifreq ifdat;
  177:     int s = -1;
  178: 
  179:     if (-1 == (s = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP)))
  180:     {
  181:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  182:                 "socket(): %s", strerror(errno));
  183:         goto errout;
  184:     }
  185: 
  186:     memset(&ifdat, 0, sizeof(struct ifreq));
  187:     strncpy(ifdat.ifr_name, l->device, IFNAMSIZ);
  188:     if (ioctl(s, SIOCGIFADDR, &ifdat) < 0)
  189:     {
  190:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  191:                 "SIOCGIFADDR: %s", strerror(errno));
  192:         goto errout;
  193:     }
  194:     close(s);
  195: 
  196:     return memcpy(l->link_addr.ether_addr_octet, &ifdat.ifr_addr.sa_data,
  197:                   ETHER_ADDR_LEN);
  198: 
  199:  errout:
  200:     if (s > 0)
  201:     {
  202:         close(s);
  203:     }
  204:     if (ea)
  205:     {
  206:         free(ea);
  207:         ea = 0;
  208:     }
  209: 
  210:     return NULL;
  211: }
  212: 
  213: /**
  214:  * Local Variables:
  215:  *  indent-tabs-mode: nil
  216:  *  c-file-style: "stroustrup"
  217:  * End:
  218:  */

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