|
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 |
}
|