Blame src/libnet_link_pf.c

Packit 03b34a
/*
Packit 03b34a
 *  $Id: libnet_link_pf.c,v 1.3 2004/01/03 20:31:02 mike Exp $
Packit 03b34a
 *
Packit 03b34a
 *  libnet
Packit 03b34a
 *  libnet_pf.c - pf routines
Packit 03b34a
 *
Packit 03b34a
 *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
Packit 03b34a
 *  All rights reserved.
Packit 03b34a
 *
Packit 03b34a
 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
Packit 03b34a
 *	The Regents of the University of California.  All rights reserved.
Packit 03b34a
 *
Packit 03b34a
 * Redistribution and use in source and binary forms, with or without
Packit 03b34a
 * modification, are permitted provided that: (1) source code distributions
Packit 03b34a
 * retain the above copyright notice and this paragraph in its entirety, (2)
Packit 03b34a
 * distributions including binary code include the above copyright notice and
Packit 03b34a
 * this paragraph in its entirety in the documentation or other materials
Packit 03b34a
 * provided with the distribution, and (3) all advertising materials mentioning
Packit 03b34a
 * features or use of this software display the following acknowledgement:
Packit 03b34a
 * ``This product includes software developed by the University of California,
Packit 03b34a
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
Packit 03b34a
 * the University nor the names of its contributors may be used to endorse
Packit 03b34a
 * or promote products derived from this software without specific prior
Packit 03b34a
 * written permission.
Packit 03b34a
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
Packit 03b34a
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
Packit 03b34a
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Packit 03b34a
 *
Packit 03b34a
 * packet filter subroutines for tcpdump
Packit 03b34a
 *	Extraction/creation by Jeffrey Mogul, DECWRL
Packit 03b34a
 */
Packit 03b34a
Packit 03b34a
#if (HAVE_CONFIG_H)
Packit 03b34a
#include "../include/config.h"
Packit 03b34a
#endif
Packit 03b34a
#include "../include/low_libnet.h"
Packit 03b34a
Packit 03b34a
#include "../include/gnuc.h"
Packit 03b34a
#ifdef HAVE_OS_PROTO_H
Packit 03b34a
#include "../include/os-proto.h"
Packit 03b34a
#endif
Packit 03b34a
Packit 03b34a
struct libnet_link_int *
Packit 03b34a
libnet_open_link_interface(int8_t *device, int8_t *ebuf)
Packit 03b34a
{
Packit 03b34a
    register struct libnet_link_int *l;
Packit 03b34a
    int16_t enmode;
Packit 03b34a
    int backlog = -1;   /* request the most */
Packit 03b34a
    struct enfilter Filter;
Packit 03b34a
    struct endevp devparams;
Packit 03b34a
Packit 03b34a
    l = (struct libnet_link_int *)malloc(sizeof(*l));
Packit 03b34a
    if (l == NULL)
Packit 03b34a
    {
Packit 03b34a
        sprintf(ebuf, "libnet_open_link_int: %s", strerror(errno));
Packit 03b34a
        return (0);
Packit 03b34a
    }
Packit 03b34a
    memset(l, 0, sizeof(*l));
Packit 03b34a
    l->fd = pfopen(device, O_RDWR);
Packit 03b34a
    if (l->fd < 0)
Packit 03b34a
    {
Packit 03b34a
        sprintf(ebuf, "pf open: %s: %s\n\your system may not be properly configured; see \"man packetfilter(4)\"\n",
Packit 03b34a
            device, strerror(errno));
Packit 03b34a
        goto bad;
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
Packit 03b34a
    if (ioctl(l->fd, EIOCMBIS, (caddr_t)&enmode) < 0)
Packit 03b34a
    {
Packit 03b34a
        sprintf(ebuf, "EIOCMBIS: %s", strerror(errno));
Packit 03b34a
        goto bad;
Packit 03b34a
    }
Packit 03b34a
#ifdef	ENCOPYALL
Packit 03b34a
    /* Try to set COPYALL mode so that we see packets to ourself */
Packit 03b34a
    enmode = ENCOPYALL;
Packit 03b34a
    ioctl(l->fd, EIOCMBIS, (caddr_t)&enmode);   /* OK if this fails */
Packit 03b34a
#endif
Packit 03b34a
	/* set the backlog */
Packit 03b34a
    if (ioctl(l->fd, EIOCSETW, (caddr_t)&backlog) < 0)
Packit 03b34a
    {
Packit 03b34a
        sprintf(ebuf, "EIOCSETW: %s", strerror(errno));
Packit 03b34a
        goto bad;
Packit 03b34a
    }
Packit 03b34a
    /*
Packit 03b34a
     *  discover interface type
Packit 03b34a
     */
Packit 03b34a
    if (ioctl(l->fd, EIOCDEVP, (caddr_t)&devparams) < 0)
Packit 03b34a
    {
Packit 03b34a
        sprintf(ebuf, "EIOCDEVP: %s", strerror(errno));
Packit 03b34a
        goto bad;
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    /* HACK: to compile prior to Ultrix 4.2 */
Packit 03b34a
#ifndef	ENDT_FDDI
Packit 03b34a
#define	ENDT_FDDI   4
Packit 03b34a
#endif
Packit 03b34a
    switch (devparams.end_dev_type)
Packit 03b34a
    {
Packit 03b34a
        case ENDT_10MB:
Packit 03b34a
            l->linktype = DLT_EN10MB;
Packit 03b34a
            break;
Packit 03b34a
        case ENDT_FDDI:
Packit 03b34a
            l->linktype = DLT_FDDI;
Packit 03b34a
            break;
Packit 03b34a
        default:
Packit 03b34a
            /*
Packit 03b34a
             * XXX
Packit 03b34a
             * Currently, the Ultrix packet filter supports only
Packit 03b34a
             * Ethernet and FDDI.  Eventually, support for SLIP and PPP
Packit 03b34a
             * (and possibly others: T1?) should be added.
Packit 03b34a
             */
Packit 03b34a
            l->linktype = DLT_EN10MB;
Packit 03b34a
            break;
Packit 03b34a
	}
Packit 03b34a
    /*
Packit 03b34a
     *  acceptag all packets
Packit 03b34a
     */
Packit 03b34a
    bzero((int8_t *)&Filter, sizeof(Filter));
Packit 03b34a
    Filter.enf_Priority = 37;	/* anything > 2 */
Packit 03b34a
    Filter.enf_FilterLen = 0;	/* means "always true" */
Packit 03b34a
    if (ioctl(l->fd, EIOCSETF, (caddr_t)&Filter) < 0)
Packit 03b34a
    {
Packit 03b34a
        sprintf(ebuf, "EIOCSETF: %s", strerror(errno));
Packit 03b34a
        goto bad;
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    return (l);
Packit 03b34a
bad:
Packit 03b34a
    free(l);
Packit 03b34a
    return (NULL);
Packit 03b34a
}
Packit 03b34a
Packit 03b34a
Packit 03b34a
int
Packit 03b34a
libnet_close_link_interface(struct libnet_link_int *l)
Packit 03b34a
{
Packit 03b34a
    if (close(l->fd) == 0)
Packit 03b34a
    {
Packit 03b34a
        free(l);
Packit 03b34a
        return (1);
Packit 03b34a
    }
Packit 03b34a
    else
Packit 03b34a
    {
Packit 03b34a
        free(l);
Packit 03b34a
        return (-1);
Packit 03b34a
    }
Packit 03b34a
}
Packit 03b34a
Packit 03b34a
Packit 03b34a
int
Packit 03b34a
libnet_write_link_layer(struct libnet_link_int *l, const int8_t *device,
Packit 03b34a
            const uint8_t *buf, int len)
Packit 03b34a
{
Packit 03b34a
    int c;
Packit 03b34a
Packit 03b34a
    c = write(l->fd, buf, len);
Packit 03b34a
    if (c != len)
Packit 03b34a
    {
Packit 03b34a
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
Packit 03b34a
            "libnet_write_link: %d bytes written (%s)\n", c,
Packit 03b34a
            strerror(errno));
Packit 03b34a
    }
Packit 03b34a
    return (c);
Packit 03b34a
}