Пример #1
0
int
libnet_open_link(libnet_t *l)
{
    struct ifreq ifr;
    struct bpf_version bv;
    uint v;

#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__)
    uint spoof_eth_src = 1;
#endif

    if (l == NULL)
    { 
        return (-1);
    } 

    if (l->device == NULL)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): NULL device", 
                __func__);
        goto bad;
    }

    l->fd = libnet_bpf_open((char*)l->err_buf);
    if (l->fd == -1)
    {
        goto bad;
    }

    /*
     *  Get bpf version.
     */
    if (ioctl(l->fd, BIOCVERSION, (caddr_t)&bv) < 0)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCVERSION: %s",
                __func__, strerror(errno));
        goto bad;
    }

    if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): kernel bpf filter out of date", __func__);
        goto bad;
    }

    /*
     *  Attach network interface to bpf device.
     */
	strncpy(ifr.ifr_name, l->device, sizeof(ifr.ifr_name) - 1);
    ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';

    if (ioctl(l->fd, BIOCSETIF, (caddr_t)&ifr) == -1)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCSETIF: (%s): %s",
                __func__, l->device, strerror(errno));
        goto bad;
    }

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

    /*
     *  NetBSD and FreeBSD BPF have an ioctl for enabling/disabling
     *  automatic filling of the link level source address.
     */
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__)
    if (ioctl(l->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCSHDRCMPLT: %s",
                __func__, strerror(errno));
        goto bad;
    }
#endif

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

    return (1);

bad:
    if (l->fd > 0)
    {
        close(l->fd);      /* this can fail ok */
    }
    return (-1);
}
Пример #2
0
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);
}