Exemple #1
0
struct libnet_link_int *
libnet_open_link_interface(char *device, char *ebuf)
{
    struct sockaddr_nit snit;
    register struct libnet_link_int *l;

    l = (struct libnet_link_int *)malloc(sizeof(*p));
    if (l == NULL)
    {
        strcpy(ebuf, ll_strerror(errno));
        return (NULL);
    }

    memset(l, 0, sizeof(*l));

    l->fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
    if (l->fd < 0)
    {
        sprintf(ebuf, "socket: %s", ll_strerror(errno));
        goto bad;
    }
    snit.snit_family = AF_NIT;
    strncpy(snit.snit_ifname, device, NITIFSIZ);

    if (bind(l->fd, (struct sockaddr *)&snit, sizeof(snit)))
    {
        sprintf(ebuf, "bind: %s: %s", snit.snit_ifname, ll_strerror(errno));
        goto bad;
    }

    /*
     * NIT supports only ethernets.
     */
    l->linktype = DLT_EN10MB;

    return (l);

bad:
    if (l->fd >= 0)
    {
        close(l->fd);
    }
    free(l);
    return (NULL);
}
struct libnet_link_int *
libnet_open_link_interface(char *device, char *ebuf)
{
    register struct libnet_link_int *l;
    short enmode;
    int backlog = -1;   /* request the most */
    struct enfilter Filter;
    struct endevp devparams;

    l = (struct libnet_link_int *)malloc(sizeof(*l));
    if (l == NULL)
    {
        sprintf(ebuf, "libnet_open_link_int: %s", ll_strerror(errno));
        return (0);
    }
    memset(l, 0, sizeof(*l));
    l->fd = pfopen(device, O_RDWR);
    if (l->fd < 0)
    {
        sprintf(ebuf, "pf open: %s: %s\n\your system may not be properly configured; see \"man packetfilter(4)\"\n",
            device, ll_strerror(errno));
        goto bad;
    }
int
libnet_bpf_open(char *errbuf)
{
    int i, fd;
    char device[sizeof "/dev/bpf000"];

    /*
     *  Go through all the minors and find one that isn't in use.
     */
    for (i = 0;;i++)
    {
        sprintf(device, "/dev/bpf%d", i);

        fd = open(device, O_RDWR);
        if (fd == -1 && errno == EBUSY)
        {
            /*
             *  Device is busy.
             */
            continue;
        }
        else
        {
            /*
             *  Either we've got a valid file descriptor, or errno is not
             *  EBUSY meaning we've probably run out of devices.
             */
            break;
        }
    }

    if (fd == -1)
    {
        sprintf(errbuf, "%s: %s", device, ll_strerror(errno));
    }
    return (fd);
}
struct libnet_link_int *
libnet_open_link_interface(char *device, char *ebuf)
{
    int fd;
    struct sockaddr_raw sr;
    u_int v;
    struct libnet_link_int *l;

    l = (struct libnet_link_int *)malloc(sizeof(*l));
    if (l == NULL)
    {
        sprintf(ebuf, "malloc: %s", ll_strerror(errno));
        return (NULL);
    }
    memset(l, 0, sizeof(*l));
    l->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN);
    if (l->fd < 0)
    {
        sprintf(ebuf, "drain socket: %s", ll_strerror(errno));
        goto bad;
    }

    memset(&sr, 0, sizeof(sr));
    sr.sr_family = AF_RAW;
    strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));

    if (bind(l->fd, (struct sockaddr *)&sr, sizeof(sr)))
    {
        sprintf(ebuf, "drain bind: %s", ll_strerror(errno));
        goto bad;
    }

    /*
     * XXX hack - map device name to link layer type
     */
    if (strncmp("et", device, 2) == 0      ||    /* Challenge 10 Mbit */
	    strncmp("ec", device, 2) == 0  ||    /* Indigo/Indy 10 Mbit, O2 10/100 */
            strncmp("ef", device, 2) == 0 ||    /* O200/2000 10/100 Mbit */
            strncmp("gfe", device, 3) == 0 ||   /* GIO 100 Mbit */
            strncmp("fxp", device, 3) == 0 ||   /* Challenge VME Enet */
            strncmp("ep", device, 2) == 0 ||    /* Challenge 8x10 Mbit EPLEX */
            strncmp("vfe", device, 3) == 0 ||   /* Challenge VME 100Mbit */
            strncmp("fa", device, 2) == 0 ||
            strncmp("qaa", device, 3) == 0)
    {
        l->linktype = DLT_EN10MB;
    }
    else if (strncmp("ipg", device, 3) == 0 ||
            strncmp("rns", device, 3) == 0 ||	/* O2/200/2000 FDDI */
            strncmp("xpi", device, 3) == 0)
        {
            l->linktype = DLT_FDDI;
	}
    else if (strncmp("ppp", device, 3) == 0) {
		l->linktype = DLT_RAW;
	} else if (strncmp("lo", device, 2) == 0) {
		l->linktype = DLT_NULL;
	} else {
		sprintf(ebuf, "drain: unknown physical layer type");
		goto bad;
	}

	return (l);
 bad:
	close(fd);
	free(l);
	return (NULL);
}
struct libnet_link_int *
libnet_open_link_interface(char *device, char *ebuf)
{
    register struct libnet_link_int *l;
    struct ifreq ifr;
#if (HAVE_PF_PACKET)
    struct packet_mreq mr;
    struct sockaddr_ll sa;
#endif

    l = (struct libnet_link_int *)malloc(sizeof (*l));
    if (l == NULL)
    {
        sprintf(ebuf, "malloc: %s", ll_strerror(errno));
        return (NULL);
    }
    memset(l, 0, sizeof (*l));

#if (HAVE_PF_PACKET)
    l->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
#else
    l->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
#endif
    if (l->fd == -1)
    {
        sprintf(ebuf, "socket: %s", ll_strerror(errno));
        goto bad;
    }

#if (HAVE_PF_PACKET)
    strcpy(ifr.ifr_name, device);
    if (ioctl(l->fd, SIOCGIFINDEX, &ifr) < 0)
    {
        sprintf(ebuf, "ioctl: SIOCGIFINDEX: %s", ll_strerror(errno));
        goto bad;
    }
    memset(&sa, 0, sizeof(sa));
    sa.sll_family = AF_PACKET;
    sa.sll_ifindex = ifr.ifr_ifindex;
    sa.sll_protocol = htons(ETH_P_ALL);

    memset(&mr, 0, sizeof (mr));
    mr.mr_ifindex = ifr.ifr_ifindex;
    mr.mr_type = PACKET_MR_ALLMULTI;

    if (setsockopt(l->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, (char *)&mr,
        sizeof (mr)) < 0)
    {
        sprintf(ebuf, "setsockopt %s: %s", device, ll_strerror(errno));
        goto bad;
    }
#endif

    memset(&ifr, 0, sizeof (ifr));
    strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name));
    if (ioctl(l->fd, SIOCGIFHWADDR, &ifr) < 0 )
    {
        sprintf(ebuf, "SIOCGIFHWADDR: %s", ll_strerror(errno));
        goto bad;
    }

    switch (ifr.ifr_hwaddr.sa_family)
    {
        case ARPHRD_ETHER:
        case ARPHRD_METRICOM:
            l->linktype = DLT_EN10MB;
            l->linkoffset = 0xe;
            break;
        case ARPHRD_SLIP:
        case ARPHRD_CSLIP:
        case ARPHRD_SLIP6:
        case ARPHRD_CSLIP6:
        case ARPHRD_PPP:
            l->linktype = DLT_RAW;
            break;
        default:
            sprintf(ebuf, "unknown physical layer type 0x%x",
                ifr.ifr_hwaddr.sa_family);
        goto bad;
    }
    return (l);

bad:
    if (l->fd >= 0)
    {
        close(l->fd);
    }
    free(l);
    return (NULL);
}
struct libnet_link_int *
libnet_open_link_interface(char *device, char *ebuf)
{
    struct strioctl si;	    /* struct for ioctl() */
    struct ifreq ifr;       /* interface request struct */
    static char dev[] = "/dev/nit";
    register struct libnet_link_int *l;

    l = (struct libnet_link_int *)malloc(sizeof(*l));
    if (l == NULL)
    {
        strcpy(ebuf, ll_strerror(errno));
        return (NULL);
    }

    memset(l, 0, sizeof(*l));

    l->fd  = open(dev, O_RDWR);
    if (l->fd < 0)
    {
        sprintf(ebuf, "%s: %s", dev, ll_strerror(errno));
        goto bad;
    }

    /*
     *  arrange to get discrete messages from the STREAM and use NIT_BUF
     */
    if (ioctl(l->fd, I_SRDOPT, (char *)RMSGD) < 0)
    {
        sprintf(ebuf, "I_SRDOPT: %s", ll_strerror(errno));
        goto bad;
    }
    if (ioctl(l->fd, I_PUSH, "nbuf") < 0)
    {
        sprintf(ebuf, "push nbuf: %s", ll_strerror(errno));
        goto bad;
    }
    /*
     *  request the interface
     */
    strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
    si.ic_cmd = NIOCBIND;
    si.ic_len = sizeof(ifr);
    si.ic_dp = (char *)&ifr;
    if (ioctl(l->fd, I_STR, (char *)&si) < 0)
    {
        sprintf(ebuf, "NIOCBIND: %s: %s", ifr.ifr_name, ll_strerror(errno));
        goto bad;
    }

    ioctl(l->fd, I_FLUSH, (char *)FLUSHR);
    /*
     * NIT supports only ethernets.
     */
    l->linktype = DLT_EN10MB;

    return (l);
bad:
    if (l->fd >= 0)
    {
        close(l->fd);
    }
    free(l);
    return (NULL);
}
struct libnet_link_int *
libnet_open_link_interface(char *device, char *ebuf)
{
    struct ifreq ifr;
    struct bpf_version bv;
    u_int v;
    struct libnet_link_int *l;

    l = (struct libnet_link_int *)malloc(sizeof(*l));
    if (!l)
    {
        sprintf(ebuf, "malloc: %s", ll_strerror(errno));
#if (__DEBUG)
        libnet_error(LN_ERR_CRITICAL, "bpf libnet_open_link_interface: malloc %s",
                ll_strerror(errno));
#endif
        return (NULL);
    }

    memset(l, 0, sizeof(*l));

    l->fd = libnet_bpf_open(ebuf);
    if (l->fd == -1)
    {
        goto bad;
    }

    /*
     *  Get bpf version.
     */
    if (ioctl(l->fd, BIOCVERSION, (caddr_t)&bv) < 0)
    {
        sprintf(ebuf, "BIOCVERSION: %s", ll_strerror(errno));
        goto bad;
    }

    if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION)
    {
        sprintf(ebuf, "kernel bpf filter out of date");
        goto bad;
    }

    /*
     *  Attach network interface to bpf device.
     */
    strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
    if (ioctl(l->fd, BIOCSETIF, (caddr_t)&ifr) == -1)
    {
        sprintf(ebuf, "%s: %s", device, ll_strerror(errno));
        goto bad;
    }

    /*
     *  Get the data link layer type.
     */
    if (ioctl(l->fd, BIOCGDLT, (caddr_t)&v) == -1)
    {
        sprintf(ebuf, "BIOCGDLT: %s", ll_strerror(errno));
        goto bad;
    }

    /*
     *  Assign link type and offset.
     */
    switch (v)
    {
        case DLT_SLIP:
            l->linkoffset = 0x10;
            break;
        case DLT_RAW:
            l->linkoffset = 0x0;
            break;
        case DLT_PPP:
            l->linkoffset = 0x04;
            break;
        case DLT_EN10MB:
        default:
            l->linkoffset = 0xe;     /* default to ethernet */
            break;
    }
#if _BSDI_VERSION - 0 >= 199510
    switch (v)
    {
        case DLT_SLIP:
            v = DLT_SLIP_BSDOS;
            l->linkoffset = 0x10;
            break;
        case DLT_PPP:
            v = DLT_PPP_BSDOS;
            l->linkoffset = 0x04;
            break;
    }
#endif
    l->linktype = v;

    return (l);

bad:
    close(l->fd);      /* this can fail ok */
    free(l);
    return (NULL);
}