Update tcpdump to 4.9.2

It contains many fixes, including bounds checking, buffer overflows (in
SLIP and bittok2str_internal), buffer over-reads, and infinite loops.

One other notable change:
  Do not use getprotobynumber() for protocol name resolution.
  Do not do any protocol name resolution if -n is specified.

Submitted by:	gordon
Reviewed by:	delphij, emaste, glebius
MFC after:	1 week
Relnotes:	Yes
Security:	CVE-2017-11108, CVE-2017-11541, CVE-2017-11542
Security:	CVE-2017-11543, CVE-2017-12893, CVE-2017-12894
Security:	CVE-2017-12895, CVE-2017-12896, CVE-2017-12897
Security:	CVE-2017-12898, CVE-2017-12899, CVE-2017-12900
Security:	CVE-2017-12901, CVE-2017-12902, CVE-2017-12985
Security:	CVE-2017-12986, CVE-2017-12987, CVE-2017-12988
Security:	CVE-2017-12989, CVE-2017-12990, CVE-2017-12991
Security:	CVE-2017-12992, CVE-2017-12993, CVE-2017-12994
Security:	CVE-2017-12995, CVE-2017-12996, CVE-2017-12997
Security:	CVE-2017-12998, CVE-2017-12999, CVE-2017-13000
Security:	CVE-2017-13001, CVE-2017-13002, CVE-2017-13003
Security:	CVE-2017-13004, CVE-2017-13005, CVE-2017-13006
Security:	CVE-2017-13007, CVE-2017-13008, CVE-2017-13009
Security:	CVE-2017-13010, CVE-2017-13011, CVE-2017-13012
Security:	CVE-2017-13013, CVE-2017-13014, CVE-2017-13015
Security:	CVE-2017-13016, CVE-2017-13017, CVE-2017-13018
Security:	CVE-2017-13019, CVE-2017-13020, CVE-2017-13021
Security:	CVE-2017-13022, CVE-2017-13023, CVE-2017-13024
Security:	CVE-2017-13025, CVE-2017-13026, CVE-2017-13027
Security:	CVE-2017-13028, CVE-2017-13029, CVE-2017-13030
Security:	CVE-2017-13031, CVE-2017-13032, CVE-2017-13033
Security:	CVE-2017-13034, CVE-2017-13035, CVE-2017-13036
Security:	CVE-2017-13037, CVE-2017-13038, CVE-2017-13039
Security:	CVE-2017-13040, CVE-2017-13041, CVE-2017-13042
Security:	CVE-2017-13043, CVE-2017-13044, CVE-2017-13045
Security:	CVE-2017-13046, CVE-2017-13047, CVE-2017-13048
Security:	CVE-2017-13049, CVE-2017-13050, CVE-2017-13051
Security:	CVE-2017-13052, CVE-2017-13053, CVE-2017-13054
Security:	CVE-2017-13055, CVE-2017-13687, CVE-2017-13688
Security:	CVE-2017-13689, CVE-2017-13690, CVE-2017-13725
Differential Revision:	https://reviews.freebsd.org/D12404
This commit is contained in:
Ed Maste 2017-12-06 02:21:11 +00:00
commit 0bff6a5af8
107 changed files with 3518 additions and 1680 deletions

View File

@ -1,10 +1,119 @@
Sunday September 3, 2017 denis@ovsienko.info
Summary for 4.9.2 tcpdump release
Do not use getprotobynumber() for protocol name resolution. Do not do
any protocol name resolution if -n is specified.
Improve errors detection in the test scripts.
Fix a segfault with OpenSSL 1.1 and improve OpenSSL usage.
Clean up IS-IS printing.
Fix buffer overflow vulnerabilities:
CVE-2017-11543 (SLIP)
CVE-2017-13011 (bittok2str_internal)
Fix infinite loop vulnerabilities:
CVE-2017-12989 (RESP)
CVE-2017-12990 (ISAKMP)
CVE-2017-12995 (DNS)
CVE-2017-12997 (LLDP)
Fix buffer over-read vulnerabilities:
CVE-2017-11541 (safeputs)
CVE-2017-11542 (PIMv1)
CVE-2017-12893 (SMB/CIFS)
CVE-2017-12894 (lookup_bytestring)
CVE-2017-12895 (ICMP)
CVE-2017-12896 (ISAKMP)
CVE-2017-12897 (ISO CLNS)
CVE-2017-12898 (NFS)
CVE-2017-12899 (DECnet)
CVE-2017-12900 (tok2strbuf)
CVE-2017-12901 (EIGRP)
CVE-2017-12902 (Zephyr)
CVE-2017-12985 (IPv6)
CVE-2017-12986 (IPv6 routing headers)
CVE-2017-12987 (IEEE 802.11)
CVE-2017-12988 (telnet)
CVE-2017-12991 (BGP)
CVE-2017-12992 (RIPng)
CVE-2017-12993 (Juniper)
CVE-2017-11542 (PIMv1)
CVE-2017-11541 (safeputs)
CVE-2017-12994 (BGP)
CVE-2017-12996 (PIMv2)
CVE-2017-12998 (ISO IS-IS)
CVE-2017-12999 (ISO IS-IS)
CVE-2017-13000 (IEEE 802.15.4)
CVE-2017-13001 (NFS)
CVE-2017-13002 (AODV)
CVE-2017-13003 (LMP)
CVE-2017-13004 (Juniper)
CVE-2017-13005 (NFS)
CVE-2017-13006 (L2TP)
CVE-2017-13007 (Apple PKTAP)
CVE-2017-13008 (IEEE 802.11)
CVE-2017-13009 (IPv6 mobility)
CVE-2017-13010 (BEEP)
CVE-2017-13012 (ICMP)
CVE-2017-13013 (ARP)
CVE-2017-13014 (White Board)
CVE-2017-13015 (EAP)
CVE-2017-11543 (SLIP)
CVE-2017-13016 (ISO ES-IS)
CVE-2017-13017 (DHCPv6)
CVE-2017-13018 (PGM)
CVE-2017-13019 (PGM)
CVE-2017-13020 (VTP)
CVE-2017-13021 (ICMPv6)
CVE-2017-13022 (IP)
CVE-2017-13023 (IPv6 mobility)
CVE-2017-13024 (IPv6 mobility)
CVE-2017-13025 (IPv6 mobility)
CVE-2017-13026 (ISO IS-IS)
CVE-2017-13027 (LLDP)
CVE-2017-13028 (BOOTP)
CVE-2017-13029 (PPP)
CVE-2017-13030 (PIM)
CVE-2017-13031 (IPv6 fragmentation header)
CVE-2017-13032 (RADIUS)
CVE-2017-13033 (VTP)
CVE-2017-13034 (PGM)
CVE-2017-13035 (ISO IS-IS)
CVE-2017-13036 (OSPFv3)
CVE-2017-13037 (IP)
CVE-2017-13038 (PPP)
CVE-2017-13039 (ISAKMP)
CVE-2017-13040 (MPTCP)
CVE-2017-13041 (ICMPv6)
CVE-2017-13042 (HNCP)
CVE-2017-13043 (BGP)
CVE-2017-13044 (HNCP)
CVE-2017-13045 (VQP)
CVE-2017-13046 (BGP)
CVE-2017-13047 (ISO ES-IS)
CVE-2017-13048 (RSVP)
CVE-2017-13049 (Rx)
CVE-2017-13050 (RPKI-Router)
CVE-2017-13051 (RSVP)
CVE-2017-13052 (CFM)
CVE-2017-13053 (BGP)
CVE-2017-13054 (LLDP)
CVE-2017-13055 (ISO IS-IS)
CVE-2017-13687 (Cisco HDLC)
CVE-2017-13688 (OLSR)
CVE-2017-13689 (IKEv1)
CVE-2017-13690 (IKEv2)
CVE-2017-13725 (IPv6 routing headers)
Sunday July 23, 2017 denis@ovsienko.info
Summary for 4.9.1 tcpdump release
CVE-2017-11108/Fix bounds checking for STP.
Make assorted documentation updates and fix a few typos in tcpdump output.
Fixup -C for file size >2GB (GH #488).
Show AddressSanitizer presence in version output.
Fix a bug in test scripts (exposed in GH #613).
On FreeBSD adjust Capsicum capabilities for netmap.
On Linux fix a use-after-free when the requested interface does not exist.
Wednesday January 18, 2017 devel.fx.lebail@orange.fr
Summary for 4.9.0 tcpdump release
General updates:
Improve separation frontend/backend (tcpdump/libnetdissect)
Don't require IPv6 library support in order to support IPv6 addresses
Introduce data types to use for integral values in packet structures
Fix display of timestamps with -tt, -ttt and -ttttt options
Fix some heap overflows found with American Fuzzy Lop by Hanno Boeck and others
(More information in the log with CVE-2016-* and CVE-2017-*)
Change the way protocols print link-layer addresses (Fix heap overflows
@ -35,14 +144,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
Don't drop CAP_SYS_CHROOT before chrooting
Fixes issue where statistics not reported when -G and -W options used
New printers supporting:
Generic Protocol Extension for VXLAN (VXLAN-GPE)
Home Networking Control Protocol (HNCP), RFCs 7787 and 7788
Locator/Identifier Separation Protocol (LISP), type 3 and type 4 packets
Marvell Extended Distributed Switch Architecture header (MEDSA)
Network Service Header (NSH)
REdis Serialization Protocol (RESP)
Updated printers:
802.11: Beginnings of 11ac radiotap support
802.11: Check the Protected bit for management frames
@ -61,7 +162,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
ATM: Fix an incorrect bounds check
BFD: Update specification from draft to RFC 5880
BFD: Update to print optional authentication field
BGP: Add decoding of ADD-PATH capability
BGP: Add support for the AIGP attribute (RFC7311)
BGP: Print LARGE_COMMUNITY Path Attribute
BGP: Update BGP numbers from IANA; Print minor values for FSM notification
@ -78,7 +178,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
DTP: Improve packet integrity checks
EGP: Fix bounds checks
ESP: Don't use OpenSSL_add_all_algorithms() in OpenSSL 1.1.0 or later
ESP: Handle OpenSSL 1.1.x
Ethernet: Add some bounds checking before calling isoclns_print (Fix a heap overflow)
Ethernet: Print the Length/Type field as length when needed
FDDI: Fix -e output for FDDI
@ -87,7 +186,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
Geneve: Fix error message with invalid option length; Update list option classes
HNCP: Fix incorrect time interval format. Fix handling of IPv4 prefixes
ICMP6: Fetch a 32-bit big-endian quantity with EXTRACT_32BITS()
ICMP6: dagid is always an IPv6 address, not an opaque 128-bit string
IGMP: Add a length check
IP: Add a bounds check (Fix a heap overflow)
IP: Check before fetching the protocol version (Fix a heap overflow)
@ -115,7 +213,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
MPLS LSP ping: Update printing for RFC 4379, bug fixes, more bounds checks
MPLS: "length" is now the *remaining* packet length
MPLS: Add bounds and length checks (Fix a heap overflow)
NFS: Add a test that makes unaligned accesses
NFS: Don't assume the ONC RPC header is nicely aligned
NFS: Don't overflow the Opaque_Handle buffer (Fix a segmentation fault)
NFS: Don't run past the end of an NFSv3 file handle
@ -130,7 +227,6 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
PGM: Print the formatted IP address, not the raw binary address, as a string
PIM: Add some bounds checking (Fix a heap overflow)
PIMv2: Fix checksumming of Register messages
PPI: Pass an adjusted struct pcap_pkthdr to the sub-printer
PPP: Add some bounds checks (Fix a heap overflow)
PPP: Report invalid PAP AACK/ANAK packets
Q.933: Add a missing bounds check
@ -171,16 +267,46 @@ Wednesday January 18, 2017 devel.fx.lebail@orange.fr
UDLD: Fix an infinite loop
UDP: Add a bounds check (Fix a heap overflow)
UDP: Check against the packet length first
UDP: Don't do the DDP-over-UDP heuristic check up front
VAT: Add some bounds checks
VTP: Add a test on Mgmt Domain Name length
VTP: Add bounds checks and filter out non-printable characters
VXLAN: Add a bound check and a test case
ZeroMQ: Fix an infinite loop
Tuesday April 14, 2015 guy@alum.mit.edu
Summary for 4.8.0 tcpdump release
Tuesday October 25, 2016 mcr@sandelman.ca
Summary for 4.8.1 tcpdump release
Fix "-x" for Apple PKTAP and PPI packets
Improve separation frontend/backend (tcpdump/libnetdissect)
Fix display of timestamps with -tt, -ttt and -ttttt options
Add support for the Marvell Extended Distributed Switch Architecture header
Use PRIx64 to print a 64-bit number in hex.
Printer for HNCP (RFCs 7787 and 7788).
dagid is always an IPv6 address, not an opaque 128-bit string, and other fixes to RPL printer.
RSVP: Add bounds and length checks
OSPF: Do more bounds checking
Handle OpenSSL 1.1.x.
Initial support for the REdis Serialization Protocol known as RESP.
Add printing function for Generic Protocol Extension for VXLAN
draft-ietf-nvo3-vxlan-gpe-01
Network Service Header: draft-ietf-sfc-nsh-01
Don't recompile the filter if the new file has the same DLT.
Pass an adjusted struct pcap_pkthdr to the sub-printer.
Add three test cases for already fixed CVEs
CVE-2014-8767: OLSR
CVE-2014-8768: Geonet
CVE-2014-8769: AODV
Don't do the DDP-over-UDP heuristic first: GitHub issue #499.
Use the new debugging routines in libpcap.
Harmonize TCP source or destination ports tests with UDP ones
Introduce data types to use for integral values in packet structures.
RSVP: Fix an infinite loop
Support of Type 3 and Type 4 LISP packets.
Don't require IPv6 library support in order to support IPv6 addresses.
Many many changes to support libnetdissect usage.
Add a test that makes unaligned accesses: GitHub issue #478.
add a DNSSEC test case: GH #445 and GH #467.
BGP: add decoding of ADD-PATH capability
fixes to LLC header printing, and RFC948-style IP packets
Friday April 10, 2015 guy@alum.mit.edu
Summary for 4.7.4 tcpdump release

View File

@ -3,6 +3,44 @@ Some Information for Contributors
You want to contribute to Tcpdump, Thanks!
Please, read these lines.
How to report bugs and other problems
-------------------------------------
To report a security issue (segfault, buffer overflow, infinite loop, arbitrary
code execution etc) please send an e-mail to security@tcpdump.org, do not use
the bug tracker!
To report a non-security problem (failure to compile, incorrect output in the
protocol printout, missing support for a particular protocol etc) please check
first that it reproduces with the latest stable release of tcpdump and the latest
stable release of libpcap. If it does, please check that the problem reproduces
with the current git master branch of tcpdump and the current git master branch of
libpcap. If it does (and it is not a security-related problem, otherwise see
above), please navigate to https://github.com/the-tcpdump-group/tcpdump/issues
and check if the problem has already been reported. If it has not, please open
a new issue and provide the following details:
* tcpdump and libpcap version (tcpdump --version)
* operating system name and version and any other details that may be relevant
(uname -a, compiler name and version, CPU type etc.)
* configure flags if any were used
* statement of the problem
* steps to reproduce
Please note that if you know exactly how to solve the problem and the solution
would not be too intrusive, it would be best to contribute some development time
and open a pull request instead as discussed below.
Still not sure how to do? Feel free to [subscribe](http://www.tcpdump.org/#mailing-lists)
to the mailing list tcpdump-workers@lists.tcpdump.org and ask!
How to add new code and to update existing code
-----------------------------------------------
0) Check that there isn't a pull request already opened for the changes you
intend to make.
1) Fork the Tcpdump repository on GitHub from
https://github.com/the-tcpdump-group/tcpdump
(See https://help.github.com/articles/fork-a-repo/)
@ -12,8 +50,11 @@ Please, read these lines.
on Linux and OSX before sending pull requests.
(See http://docs.travis-ci.com/user/getting-started/)
3) Clone your repository
3) Setup your git working copy
git clone https://github.com/<username>/tcpdump.git
cd tcpdump
git remote add upstream https://github.com/the-tcpdump-group/tcpdump
git fetch upstream
4) Do a 'touch .devel' in your working directory.
Currently, the effect is
@ -47,19 +88,26 @@ Please, read these lines.
7) Test with 'make check'
Don't send a pull request if 'make check' gives failed tests.
8) Rebase your commits against upstream/master
(To keep linearity)
8) Try to rebase your commits to keep the history simple.
git rebase upstream/master
(If the rebase fails and you cannot resolve, issue "git rebase --abort"
and ask for help in the pull request comment.)
9) Initiate and send a pull request
9) Once 100% happy, put your work into your forked repository.
git push
10) Initiate and send a pull request
(See https://help.github.com/articles/using-pull-requests/)
Some remarks
------------
Code style and generic remarks
------------------------------
a) A thorough reading of some other printers code is useful.
b) Put the normative reference if any as comments (RFC, etc.).
c) Put the format of packets/headers/options as comments.
c) Put the format of packets/headers/options as comments if there is no
published normative reference.
d) The printer may receive incomplete packet in the buffer, truncated at any
random position, for example by capturing with '-s size' option.

View File

@ -5,7 +5,7 @@ The current maintainers:
Denis Ovsienko <denis at ovsienko dot info>
Fulvio Risso <risso at polito dot it>
Guy Harris <guy at alum dot mit dot edu>
Hannes Gredler <hannes at juniper dot net>
Hannes Gredler <hannes at gredler dot at>
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
Francois-Xavier Le Bail <fx dot lebail at yahoo dot com>
@ -39,6 +39,7 @@ Additional people who have contributed patches:
Bjoern A. Zeeb <bzeeb at Zabbadoz dot NeT>
Bram <tcpdump at mail dot wizbit dot be>
Brent L. Bates <blbates at vigyan dot com>
Brian Carpenter <brian dot carpenter at gmail dot com>
Brian Ginsbach <ginsbach at cray dot com>
Bruce M. Simpson <bms at spc dot org>
Carles Kishimoto Bisbe <ckishimo at ac dot upc dot es>
@ -54,6 +55,7 @@ Additional people who have contributed patches:
Craig Rodrigues <rodrigc at mediaone dot net>
Crist J. Clark <cjclark at alum dot mit dot edu>
Daniel Hagerty <hag at ai dot mit dot edu>
Daniel Lee <Longinus00 at gmail dot com>
Darren Reed <darrenr at reed dot wattle dot id dot au>
David Binderman <d dot binderman at virgin dot net>
David Horn <dhorn2000 at gmail dot com>
@ -85,6 +87,7 @@ Additional people who have contributed patches:
Greg Stark <gsstark at mit dot edu>
Hank Leininger <tcpdump-workers at progressive-comp dot com>
Hannes Viertel <hviertel at juniper dot net>
Hanno Böck <hanno at hboeck dot de>
Harry Raaymakers <harryr at connect dot com dot au>
Heinz-Ado Arnolds <Ado dot Arnolds at dhm-systems dot de>
Hendrik Scholz <hendrik at scholz dot net>
@ -111,6 +114,7 @@ Additional people who have contributed patches:
Juliusz Chroboczek <jch at pps dot jussieu dot fr>
Kaarthik Sivakumar <kaarthik at torrentnet dot com>
Kaladhar Musunuru <kaladharm at sourceforge dot net>
Kamil Frankowicz <kontakt at frankowicz dot me>
Karl Norby <karl-norby at sourceforge dot net>
Kazushi Sugyo <sugyo at pb dot jp dot nec dot com>
Kelly Carmichael <kcarmich at ipapp dot com>
@ -123,7 +127,6 @@ Additional people who have contributed patches:
Larry Lile <lile at stdio dot com>
Lennert Buytenhek <buytenh at gnu dot org>
Loganaden Velvindron <logan at elandsys dot com>
Daniel Lee <Longinus00 at gmail dot com>
Loris Degioanni <loris at netgroup-serv dot polito dot it>
Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
Lucas C. Villa Real <lucasvr at us dot ibm dot com>
@ -166,6 +169,7 @@ Additional people who have contributed patches:
Paolo Abeni <paolo dot abeni at email dot it>
Pascal Hennequin <pascal dot hennequin at int-evry dot fr>
Pasvorn Boonmark <boonmark at juniper dot net>
Patrik Lundquist <patrik dot lundquist at gmail dot com>
Paul Ferrell <pflarr at sourceforge dot net>
Paul Mundt <lethal at linux-sh dot org>
Paul S. Traina <pst at freebsd dot org>

View File

@ -37,6 +37,7 @@ Please see "PLATFORMS" for notes about tested platforms.
FILES
-----
CHANGES - description of differences between releases
CONTRIBUTING - guidelines for contributing
CREDITS - people that have helped tcpdump along
INSTALL.txt - this file
LICENSE - the license under which tcpdump is distributed

View File

@ -263,6 +263,7 @@ HDR = \
ether.h \
ethertype.h \
extract.h \
funcattrs.h \
getopt_long.h \
gmpls.h \
gmt2local.h \

View File

@ -1,9 +1,16 @@
== Tested platforms ==
NetBSD 5.1/i386 (mcr - 2012/4/1)
Debian Linux (squeeze/i386) (mcr - 2012/4/1)
---
RedHat Linux 6.1/i386 (assar)
FreeBSD 2.2.8/i386 (itojun)
In many operating systems tcpdump is available as a native package or port,
which simplifies installation of updates and long-term maintenance. However,
the native packages are sometimes a few versions behind and to try a more
recent snapshot it will take to compile tcpdump from the source code.
tcpdump compiles and works on at least the following platforms:
* AIX
* FreeBSD
* HP-UX 11i
* Linux (any) with glibc (usually just works)
* Linux (any) with musl libc (sometimes fails to compile, please report any bugs)
* Mac OS X / macOS
* NetBSD
* OpenWrt
* Solaris

View File

@ -3,25 +3,21 @@
[![Build
Status](https://travis-ci.org/the-tcpdump-group/tcpdump.png)](https://travis-ci.org/the-tcpdump-group/tcpdump)
TCPDUMP 4.x.y
Now maintained by "The Tcpdump Group"
See www.tcpdump.org
To report a security issue please send an e-mail to security@tcpdump.org.
Please send inquiries/comments/reports to:
To report bugs and other problems, contribute patches, request a
feature, provide generic feedback etc please see the file
CONTRIBUTING in the tcpdump source tree root.
* tcpdump-workers@lists.tcpdump.org
TCPDUMP 4.x.y
Now maintained by "The Tcpdump Group"
See www.tcpdump.org
Anonymous Git is available via:
git clone git://bpf.tcpdump.org/tcpdump
Please submit patches by forking the branch on GitHub at:
* http://github.com/the-tcpdump-group/tcpdump/tree/master
and issuing a pull request.
formerly from Lawrence Berkeley National Laboratory
formerly from Lawrence Berkeley National Laboratory
Network Research Group <tcpdump@ee.lbl.gov>
ftp://ftp.ee.lbl.gov/old/tcpdump.tar.Z (3.4)
@ -71,20 +67,6 @@ It is a program that can be used to extract portions of tcpdump binary
trace files. See the above distribution for further details and
documentation.
Problems, bugs, questions, desirable enhancements, etc. should be sent
to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support
requests, and feature requests may also be submitted on the GitHub issue
tracker for tcpdump at:
* https://github.com/the-tcpdump-group/tcpdump/issues
Source code contributions, etc. should be sent to the email address
above or submitted by forking the branch on GitHub at:
* http://github.com/the-tcpdump-group/tcpdump/tree/master
and issuing a pull request.
Current versions can be found at www.tcpdump.org.
- The TCPdump team

View File

@ -1 +1 @@
4.9.0
4.9.2

View File

@ -150,13 +150,23 @@ struct enamemem {
u_short e_addr2;
const char *e_name;
u_char *e_nsap; /* used only for nsaptable[] */
#define e_bs e_nsap /* for bytestringtable */
struct enamemem *e_nxt;
};
static struct enamemem enametable[HASHNAMESIZE];
static struct enamemem nsaptable[HASHNAMESIZE];
static struct enamemem bytestringtable[HASHNAMESIZE];
struct bsnamemem {
u_short bs_addr0;
u_short bs_addr1;
u_short bs_addr2;
const char *bs_name;
u_char *bs_bytes;
unsigned int bs_nbytes;
struct bsnamemem *bs_nxt;
};
static struct bsnamemem bytestringtable[HASHNAMESIZE];
struct protoidmem {
uint32_t p_oui;
@ -342,7 +352,7 @@ getname6(netdissect_options *ndo, const u_char *ap)
return (p->name);
}
static const char hex[] = "0123456789abcdef";
static const char hex[16] = "0123456789abcdef";
/* Find the hash node that corresponds the ether address 'ep' */
@ -380,11 +390,11 @@ lookup_emem(netdissect_options *ndo, const u_char *ep)
* with length 'nlen'
*/
static inline struct enamemem *
static inline struct bsnamemem *
lookup_bytestring(netdissect_options *ndo, register const u_char *bs,
const unsigned int nlen)
{
struct enamemem *tp;
struct bsnamemem *tp;
register u_int i, j, k;
if (nlen >= 6) {
@ -399,26 +409,28 @@ lookup_bytestring(netdissect_options *ndo, register const u_char *bs,
i = j = k = 0;
tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
while (tp->e_nxt)
if (tp->e_addr0 == i &&
tp->e_addr1 == j &&
tp->e_addr2 == k &&
memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0)
while (tp->bs_nxt)
if (nlen == tp->bs_nbytes &&
tp->bs_addr0 == i &&
tp->bs_addr1 == j &&
tp->bs_addr2 == k &&
memcmp((const char *)bs, (const char *)(tp->bs_bytes), nlen) == 0)
return tp;
else
tp = tp->e_nxt;
tp = tp->bs_nxt;
tp->e_addr0 = i;
tp->e_addr1 = j;
tp->e_addr2 = k;
tp->bs_addr0 = i;
tp->bs_addr1 = j;
tp->bs_addr2 = k;
tp->e_bs = (u_char *) calloc(1, nlen + 1);
if (tp->e_bs == NULL)
tp->bs_bytes = (u_char *) calloc(1, nlen);
if (tp->bs_bytes == NULL)
(*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
memcpy(tp->e_bs, bs, nlen);
tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
if (tp->e_nxt == NULL)
memcpy(tp->bs_bytes, bs, nlen);
tp->bs_nbytes = nlen;
tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp));
if (tp->bs_nxt == NULL)
(*ndo->ndo_error)(ndo, "lookup_bytestring: calloc");
return tp;
@ -445,11 +457,11 @@ lookup_nsap(netdissect_options *ndo, register const u_char *nsap,
tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
while (tp->e_nxt)
if (tp->e_addr0 == i &&
if (nsap_length == tp->e_nsap[0] &&
tp->e_addr0 == i &&
tp->e_addr1 == j &&
tp->e_addr2 == k &&
tp->e_nsap[0] == nsap_length &&
memcmp((const char *)&(nsap[1]),
memcmp((const char *)nsap,
(char *)&(tp->e_nsap[1]), nsap_length) == 0)
return tp;
else
@ -549,12 +561,12 @@ le64addr_string(netdissect_options *ndo, const u_char *ep)
const unsigned int len = 8;
register u_int i;
register char *cp;
register struct enamemem *tp;
register struct bsnamemem *tp;
char buf[BUFSIZE];
tp = lookup_bytestring(ndo, ep, len);
if (tp->e_name)
return (tp->e_name);
if (tp->bs_name)
return (tp->bs_name);
cp = buf;
for (i = len; i > 0 ; --i) {
@ -566,11 +578,11 @@ le64addr_string(netdissect_options *ndo, const u_char *ep)
*cp = '\0';
tp->e_name = strdup(buf);
if (tp->e_name == NULL)
tp->bs_name = strdup(buf);
if (tp->bs_name == NULL)
(*ndo->ndo_error)(ndo, "le64addr_string: strdup(buf)");
return (tp->e_name);
return (tp->bs_name);
}
const char *
@ -579,7 +591,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
{
register u_int i;
register char *cp;
register struct enamemem *tp;
register struct bsnamemem *tp;
if (len == 0)
return ("<empty>");
@ -591,11 +603,11 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
return (q922_string(ndo, ep, len));
tp = lookup_bytestring(ndo, ep, len);
if (tp->e_name)
return (tp->e_name);
if (tp->bs_name)
return (tp->bs_name);
tp->e_name = cp = (char *)malloc(len*3);
if (tp->e_name == NULL)
tp->bs_name = cp = (char *)malloc(len*3);
if (tp->bs_name == NULL)
(*ndo->ndo_error)(ndo, "linkaddr_string: malloc");
*cp++ = hex[*ep >> 4];
*cp++ = hex[*ep++ & 0xf];
@ -605,7 +617,7 @@ linkaddr_string(netdissect_options *ndo, const u_char *ep,
*cp++ = hex[*ep++ & 0xf];
}
*cp = '\0';
return (tp->e_name);
return (tp->bs_name);
}
const char *

View File

@ -33,7 +33,8 @@ enum {
LINKADDR_ETHER,
LINKADDR_FRELAY,
LINKADDR_IEEE1394,
LINKADDR_ATM
LINKADDR_ATM,
LINKADDR_OTHER
};
#define BUFSIZE 128

View File

@ -110,25 +110,24 @@ addrtostr6 (const void *src, char *dst, size_t size)
size_t space_left, added_space;
int snprintfed;
struct {
long base;
long len;
int base;
int len;
} best, cur;
u_long words [IN6ADDRSZ / INT16SZ];
uint16_t words [IN6ADDRSZ / INT16SZ];
int i;
/* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset (words, 0, sizeof(words));
for (i = 0; i < IN6ADDRSZ; i++)
words[i/2] |= (srcaddr[i] << ((1 - (i % 2)) << 3));
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
words[i] = (srcaddr[2*i] << 8) | srcaddr[2*i + 1];
best.len = 0;
best.base = -1;
cur.len = 0;
cur.base = -1;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++)
{
if (words[i] == 0)
{
@ -161,7 +160,7 @@ addrtostr6 (const void *src, char *dst, size_t size)
*dp++ = c; \
space_left--; \
}
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++)
{
/* Are we inside the best run of 0x00's?
*/
@ -192,7 +191,7 @@ addrtostr6 (const void *src, char *dst, size_t size)
space_left -= added_space;
break;
}
snprintfed = snprintf (dp, space_left, "%lx", words[i]);
snprintfed = snprintf (dp, space_left, "%x", words[i]);
if (snprintfed < 0)
return (NULL);
if ((size_t) snprintfed >= space_left)

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok af_values[];

View File

@ -14,7 +14,7 @@
*
* miscellaneous checksumming routines
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H

View File

@ -34,6 +34,9 @@
/* Define to 1 if you have the `ether_ntohost' function. */
#undef HAVE_ETHER_NTOHOST
/* Define to 1 if you have the `EVP_CipherInit_ex' function. */
#undef HAVE_EVP_CIPHERINIT_EX
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
#undef HAVE_EVP_CIPHER_CTX_NEW

View File

@ -5801,7 +5801,7 @@ if test "x$ac_cv_func_pcap_loop" = xyes; then :
else
as_fn_error $? "Report this to tcpdump-workers@lists.tcpdump.org, and include the
as_fn_error $? "This is a bug, please follow the guidelines in CONTRIBUTING and include the
config.log file in your report. If you have downloaded libpcap from
tcpdump.org, and built it yourself, please also include the config.log
file from the libpcap source directory, the Makefile from the libpcap
@ -8116,17 +8116,32 @@ fi
done
#
# OK, do we have EVP_CIPHER_CTX_new?
# OK, then:
#
# 1) do we have EVP_CIPHER_CTX_new?
# If so, we use it to allocate an
# EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be
# opaque; otherwise, we allocate it ourselves.
#
for ac_func in EVP_CIPHER_CTX_new
# 2) do we have EVP_CipherInit_ex()?
# If so, we use it, because we need to be
# able to make two "initialize the cipher"
# calls, one with the cipher and key, and
# one with the IV, and, as of OpenSSL 1.1,
# You Can't Do That with EVP_CipherInit(),
# because a call to EVP_CipherInit() will
# unconditionally clear the context, and
# if you don't supply a cipher, it'll
# clear the cipher, rendering the context
# unusable and causing a crash.
#
for ac_func in EVP_CIPHER_CTX_new EVP_CipherInit_ex
do :
ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_new" "ac_cv_func_EVP_CIPHER_CTX_new"
if test "x$ac_cv_func_EVP_CIPHER_CTX_new" = xyes; then :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_EVP_CIPHER_CTX_NEW 1
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi

View File

@ -935,12 +935,26 @@ if test "$want_libcrypto" != "no"; then
if test "$ac_cv_lib_crypto_DES_cbc_encrypt" = "yes"; then
AC_CHECK_HEADERS(openssl/evp.h)
#
# OK, do we have EVP_CIPHER_CTX_new?
# OK, then:
#
# 1) do we have EVP_CIPHER_CTX_new?
# If so, we use it to allocate an
# EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be
# opaque; otherwise, we allocate it ourselves.
#
AC_CHECK_FUNCS(EVP_CIPHER_CTX_new)
# 2) do we have EVP_CipherInit_ex()?
# If so, we use it, because we need to be
# able to make two "initialize the cipher"
# calls, one with the cipher and key, and
# one with the IV, and, as of OpenSSL 1.1,
# You Can't Do That with EVP_CipherInit(),
# because a call to EVP_CipherInit() will
# unconditionally clear the context, and
# if you don't supply a cipher, it'll
# clear the cipher, rendering the context
# unusable and causing a crash.
#
AC_CHECK_FUNCS(EVP_CIPHER_CTX_new EVP_CipherInit_ex)
fi
])
fi

View File

@ -20,8 +20,48 @@
*/
/*
* Macros to extract possibly-unaligned big-endian integral values.
* For 8-bit values; provided for the sake of completeness. Byte order
* isn't relevant, and alignment isn't an issue.
*/
#define EXTRACT_8BITS(p) (*(p))
#define EXTRACT_LE_8BITS(p) (*(p))
/*
* Inline functions or macros to extract possibly-unaligned big-endian
* integral values.
*/
#include "funcattrs.h"
/*
* If we have versions of GCC or Clang that support an __attribute__
* to say "if we're building with unsigned behavior sanitization,
* don't complain about undefined behavior in this function", we
* label these functions with that attribute - we *know* it's undefined
* in the C standard, but we *also* know it does what we want with
* the ISA we're targeting and the compiler we're using.
*
* For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined));
* pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether
* GCC or Clang first had __attribute__((no_sanitize(XXX)).
*
* For Clang, we check for __attribute__((no_sanitize(XXX)) with
* __has_attribute, as there are versions of Clang that support
* __attribute__((no_sanitize("undefined")) but don't support
* __attribute__((no_sanitize_undefined)).
*
* We define this here, rather than in funcattrs.h, because we
* only want it used here, we don't want it to be broadly used.
* (Any printer will get this defined, but this should at least
* make it harder for people to find.)
*/
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409)
#define UNALIGNED_OK __attribute__((no_sanitize_undefined))
#elif __has_attribute(no_sanitize)
#define UNALIGNED_OK __attribute__((no_sanitize("undefined")))
#else
#define UNALIGNED_OK
#endif
#ifdef LBL_ALIGN
/*
* The processor doesn't natively handle unaligned loads.
@ -31,7 +71,7 @@
defined(__mips) || defined(__mips__))
/*
* This is a GCC-compatible compiler and we have __attribute__, which
* This is a GCC-compatible compiler and we have __attribute__, which
* we assume that mean we have __attribute__((packed)), and this is
* MIPS or Alpha, which has instructions that can help when doing
* unaligned loads.
@ -88,19 +128,19 @@ typedef struct {
uint32_t val;
} __attribute__((packed)) unaligned_uint32_t;
static inline uint16_t
UNALIGNED_OK static inline uint16_t
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val));
}
static inline uint32_t
UNALIGNED_OK static inline uint32_t
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val));
}
static inline uint64_t
UNALIGNED_OK static inline uint64_t
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 |
@ -138,19 +178,19 @@ EXTRACT_64BITS(const void *p)
* The processor natively handles unaligned loads, so we can just
* cast the pointer and fetch through it.
*/
static inline uint16_t
static inline uint16_t UNALIGNED_OK
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(*(const uint16_t *)(p)));
}
static inline uint32_t
static inline uint32_t UNALIGNED_OK
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
}
static inline uint64_t
static inline uint64_t UNALIGNED_OK
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
@ -193,7 +233,6 @@ EXTRACT_64BITS(const void *p)
* Macros to extract possibly-unaligned little-endian integral values.
* XXX - do loads on little-endian machines that support unaligned loads?
*/
#define EXTRACT_LE_8BITS(p) (*(p))
#define EXTRACT_LE_16BITS(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
@ -242,3 +281,6 @@ EXTRACT_64BITS(const void *p)
#define ND_TTEST_64BITS(p) ND_TTEST2(*(p), 8)
#define ND_TCHECK_64BITS(p) ND_TCHECK2(*(p), 8)
#define ND_TTEST_128BITS(p) ND_TTEST2(*(p), 16)
#define ND_TCHECK_128BITS(p) ND_TCHECK2(*(p), 16)

122
contrib/tcpdump/funcattrs.h Normal file
View File

@ -0,0 +1,122 @@
/* -*- 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.
*/
#ifndef lib_funcattrs_h
#define lib_funcattrs_h
/*
* Attributes to apply to functions and their arguments, using various
* compiler-specific extensions.
*/
/*
* This was introduced by Clang:
*
* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
*
* in some version (which version?); it has been picked up by GCC 5.0.
*/
#ifndef __has_attribute
/*
* It's a macro, so you can check whether it's defined to check
* whether it's supported.
*
* If it's not, define it to always return 0, so that we move on to
* the fallback checks.
*/
#define __has_attribute(x) 0
#endif
/*
* NORETURN, before a function declaration, means "this function
* never returns". (It must go before the function declaration, e.g.
* "extern NORETURN func(...)" rather than after the function
* declaration, as the MSVC version has to go before the declaration.)
*/
#if __has_attribute(noreturn) \
|| (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
|| (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
|| (defined(__xlC__) && __xlC__ >= 0x0A01) \
|| (defined(__HP_aCC) && __HP_aCC >= 61000)
/*
* Compiler with support for __attribute((noreturn)), or GCC 2.5 and
* later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
* and later (do any earlier versions of XL C support this?), or
* HP aCC A.06.10 and later.
*/
#define NORETURN __attribute((noreturn))
#elif defined(_MSC_VER)
/*
* MSVC.
*/
#define NORETURN __declspec(noreturn)
#else
#define NORETURN
#endif
/*
* PRINTFLIKE(x,y), after a function declaration, means "this function
* does printf-style formatting, with the xth argument being the format
* string and the yth argument being the first argument for the format
* string".
*/
#if __has_attribute(__format__) \
|| (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
|| (defined(__xlC__) && __xlC__ >= 0x0A01) \
|| (defined(__HP_aCC) && __HP_aCC >= 61000)
/*
* Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
* and later (do any earlier versions of XL C support this?),
* or HP aCC A.06.10 and later.
*/
#define PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
#else
#define PRINTFLIKE(x,y)
#endif
/*
* For flagging arguments as format strings in MSVC.
*/
#if _MSC_VER >= 1400
#include <sal.h>
#if _MSC_VER > 1400
#define FORMAT_STRING(p) _Printf_format_string_ p
#else
#define FORMAT_STRING(p) __format_string p
#endif
#else
#define FORMAT_STRING(p) p
#endif
#endif /* lib_funcattrs_h */

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#define GMPLS_PSC1 1

View File

@ -178,14 +178,13 @@ struct ip6_rthdr {
/* Type 0 Routing header */
/* Also used for Type 2 */
struct ip6_rthdr0 {
uint8_t ip6r0_nxt; /* next header */
uint8_t ip6r0_len; /* length in units of 8 octets */
uint8_t ip6r0_type; /* always zero */
uint8_t ip6r0_segleft; /* segments left */
uint8_t ip6r0_reserved; /* reserved field */
uint8_t ip6r0_slmap[3]; /* strict/loose bit map */
nd_uint8_t ip6r0_nxt; /* next header */
nd_uint8_t ip6r0_len; /* length in units of 8 octets */
nd_uint8_t ip6r0_type; /* always zero */
nd_uint8_t ip6r0_segleft; /* segments left */
nd_uint32_t ip6r0_reserved; /* reserved field */
struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
} UNALIGNED;
};
/* Fragment header */
struct ip6_frag {

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H
@ -55,3 +55,309 @@ const struct tok ipproto_values[] = {
{ 0, NULL }
};
/*
* For completeness the number space in the array below comes from IANA:
* https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
* However, the spelling tries to match that of /etc/protocols to achieve as
* much consistency as possible with the previously implemented behaviour,
* which was based on getprotobynumber (3).
*/
static const char *netdb_protocol_names[256] = {
"hopopt", /* 0 (IPPROTO_HOPOPTS, IPv6 Hop-by-Hop Option) */
"icmp", /* 1 (IPPROTO_ICMP, Internet Control Message) */
"igmp", /* 2 (IPPROTO_IGMP, Internet Group Management) */
"ggp", /* 3 (Gateway-to-Gateway) */
"ipencap", /* 4 (IPPROTO_IPV4, IPv4 encapsulation) */
"st", /* 5 (Stream, ST datagram mode) */
"tcp", /* 6 (IPPROTO_TCP, Transmission Control) */
"cbt", /* 7 (CBT) */
"egp", /* 8 (IPPROTO_EGP, Exterior Gateway Protocol) */
"igp", /* 9 (IPPROTO_PIGP, "any private interior gateway
* (used by Cisco for their IGRP)")
*/
"bbn-rcc-mon", /* 10 (BBN RCC Monitoring) */
"nvp-ii", /* 11 (Network Voice Protocol) */
"pup", /* 12 (PARC universal packet protocol) */
"argus", /* 13 (ARGUS) */
"emcon", /* 14 (EMCON) */
"xnet", /* 15 (Cross Net Debugger) */
"chaos", /* 16 (Chaos) */
"udp", /* 17 (IPPROTO_UDP, User Datagram) */
"mux", /* 18 (Multiplexing) */
"dcn-meas", /* 19 (DCN Measurement Subsystems) */
"hmp", /* 20 (Host Monitoring) */
"prm", /* 21 (Packet Radio Measurement) */
"xns-idp", /* 22 (XEROX NS IDP) */
"trunk-1", /* 23 (Trunk-1) */
"trunk-2", /* 24 (Trunk-2) */
"leaf-1", /* 25 (Leaf-1) */
"leaf-2", /* 26 (Leaf-2) */
"rdp", /* 27 (Reliable Data Protocol) */
"irtp", /* 28 (Internet Reliable Transaction) */
"iso-tp4", /* 29 (ISO Transport Protocol Class 4) */
"netblt", /* 30 (Bulk Data Transfer Protocol) */
"mfe-nsp", /* 31 (MFE Network Services Protocol) */
"merit-inp", /* 32 (MERIT Internodal Protocol) */
"dccp", /* 33 (IPPROTO_DCCP, Datagram Congestion
* Control Protocol)
*/
"3pc", /* 34 (Third Party Connect Protocol) */
"idpr", /* 35 (Inter-Domain Policy Routing Protocol) */
"xtp", /* 36 (Xpress Transfer Protocol) */
"ddp", /* 37 (Datagram Delivery Protocol) */
"idpr-cmtp", /* 38 (IDPR Control Message Transport Proto) */
"tp++", /* 39 (TP++ Transport Protocol) */
"il", /* 40 (IL Transport Protocol) */
"ipv6", /* 41 (IPPROTO_IPV6, IPv6 encapsulation) */
"sdrp", /* 42 (Source Demand Routing Protocol) */
"ipv6-route", /* 43 (IPPROTO_ROUTING, Routing Header for IPv6) */
"ipv6-frag", /* 44 (IPPROTO_FRAGMENT, Fragment Header for
* IPv6)
*/
"idrp", /* 45 (Inter-Domain Routing Protocol) */
"rsvp", /* 46 (IPPROTO_RSVP, Reservation Protocol) */
"gre", /* 47 (IPPROTO_GRE, Generic Routing
* Encapsulation)
*/
"dsr", /* 48 (Dynamic Source Routing Protocol) */
"bna", /* 49 (BNA) */
"esp", /* 50 (IPPROTO_ESP, Encap Security Payload) */
"ah", /* 51 (IPPROTO_AH, Authentication Header) */
"i-nlsp", /* 52 (Integrated Net Layer Security TUBA) */
"swipe", /* 53 (IP with Encryption) */
"narp", /* 54 (NBMA Address Resolution Protocol) */
"mobile", /* 55 (IPPROTO_MOBILE, IP Mobility) */
"tlsp", /* 56 (Transport Layer Security Protocol using
* Kryptonet key management)
*/
"skip", /* 57 (SKIP) */
"ipv6-icmp", /* 58 (IPPROTO_ICMPV6, ICMP for IPv6) */
"ipv6-nonxt", /* 59 (IPPROTO_NONE, No Next Header for IPv6) */
"ipv6-opts", /* 60 (IPPROTO_DSTOPTS, Destination Options for
* IPv6)
*/
NULL, /* 61 (any host internal protocol) */
"cftp", /* 62 (IPPROTO_MOBILITY_OLD, CFTP, see the note
* in ipproto.h)
*/
NULL, /* 63 (any local network) */
"sat-expak", /* 64 (SATNET and Backroom EXPAK) */
"kryptolan", /* 65 (Kryptolan) */
"rvd", /* 66 (MIT Remote Virtual Disk Protocol) */
"ippc", /* 67 (Internet Pluribus Packet Core) */
NULL, /* 68 (any distributed file system) */
"sat-mon", /* 69 (SATNET Monitoring) */
"visa", /* 70 (VISA Protocol) */
"ipcv", /* 71 (Internet Packet Core Utility) */
"cpnx", /* 72 (Computer Protocol Network Executive) */
"rspf", /* 73 (Radio Shortest Path First, CPHB -- Computer
* Protocol Heart Beat -- in IANA)
*/
"wsn", /* 74 (Wang Span Network) */
"pvp", /* 75 (Packet Video Protocol) */
"br-sat-mon", /* 76 (Backroom SATNET Monitoring) */
"sun-nd", /* 77 (IPPROTO_ND, SUN ND PROTOCOL-Temporary) */
"wb-mon", /* 78 (WIDEBAND Monitoring) */
"wb-expak", /* 79 (WIDEBAND EXPAK) */
"iso-ip", /* 80 (ISO Internet Protocol) */
"vmtp", /* 81 (Versatile Message Transport) */
"secure-vmtp", /* 82 (Secure VMTP) */
"vines", /* 83 (VINES) */
"ttp", /* 84 (Transaction Transport Protocol, also IPTM --
* Internet Protocol Traffic Manager)
*/
"nsfnet-igp", /* 85 (NSFNET-IGP) */
"dgp", /* 86 (Dissimilar Gateway Protocol) */
"tcf", /* 87 (TCF) */
"eigrp", /* 88 (IPPROTO_EIGRP, Cisco EIGRP) */
"ospf", /* 89 (IPPROTO_OSPF, Open Shortest Path First
* IGP)
*/
"sprite-rpc", /* 90 (Sprite RPC Protocol) */
"larp", /* 91 (Locus Address Resolution Protocol) */
"mtp", /* 92 (Multicast Transport Protocol) */
"ax.25", /* 93 (AX.25 Frames) */
"ipip", /* 94 (IP-within-IP Encapsulation Protocol) */
"micp", /* 95 (Mobile Internetworking Control Pro.) */
"scc-sp", /* 96 (Semaphore Communications Sec. Pro.) */
"etherip", /* 97 (Ethernet-within-IP Encapsulation) */
"encap", /* 98 (Encapsulation Header) */
NULL, /* 99 (any private encryption scheme) */
"gmtp", /* 100 (GMTP) */
"ifmp", /* 101 (Ipsilon Flow Management Protocol) */
"pnni", /* 102 (PNNI over IP) */
"pim", /* 103 (IPPROTO_PIM, Protocol Independent
* Multicast)
*/
"aris", /* 104 (ARIS) */
"scps", /* 105 (SCPS) */
"qnx", /* 106 (QNX) */
"a/n", /* 107 (Active Networks) */
"ipcomp", /* 108 (IPPROTO_IPCOMP, IP Payload Compression
* Protocol)
*/
"snp", /* 109 (Sitara Networks Protocol) */
"compaq-peer", /* 110 (Compaq Peer Protocol) */
"ipx-in-ip", /* 111 (IPX in IP) */
"vrrp", /* 112 (IPPROTO_VRRP, Virtual Router Redundancy
* Protocol)
*/
"pgm", /* 113 (IPPROTO_PGM, PGM Reliable Transport
* Protocol)
*/
NULL, /* 114 (any 0-hop protocol) */
"l2tp", /* 115 (Layer Two Tunneling Protocol) */
"ddx", /* 116 (D-II Data Exchange (DDX)) */
"iatp", /* 117 (Interactive Agent Transfer Protocol) */
"stp", /* 118 (Schedule Transfer Protocol) */
"srp", /* 119 (SpectraLink Radio Protocol) */
"uti", /* 120 (UTI) */
"smp", /* 121 (Simple Message Protocol) */
"sm", /* 122 (Simple Multicast Protocol) */
"ptp", /* 123 (Performance Transparency Protocol) */
"isis", /* 124 (ISIS over IPv4) */
"fire", /* 125 (FIRE) */
"crtp", /* 126 (Combat Radio Transport Protocol) */
"crudp", /* 127 (Combat Radio User Datagram) */
"sscopmce", /* 128 (SSCOPMCE) */
"iplt", /* 129 (IPLT) */
"sps", /* 130 (Secure Packet Shield) */
"pipe", /* 131 (Private IP Encapsulation within IP) */
"sctp", /* 132 (IPPROTO_SCTP, Stream Control Transmission
* Protocol)
*/
"fc", /* 133 (Fibre Channel) */
"rsvp-e2e-ignore", /* 134 (RSVP-E2E-IGNORE) */
"mobility-header", /* 135 (IPPROTO_MOBILITY, Mobility Header) */
"udplite", /* 136 (UDPLite) */
"mpls-in-ip", /* 137 (MPLS-in-IP) */
"manet", /* 138 (MANET Protocols) */
"hip", /* 139 (Host Identity Protocol) */
"shim6", /* 140 (Shim6 Protocol) */
"wesp", /* 141 (Wrapped Encapsulating Security Payload) */
"rohc", /* 142 (Robust Header Compression) */
NULL, /* 143 (unassigned) */
NULL, /* 144 (unassigned) */
NULL, /* 145 (unassigned) */
NULL, /* 146 (unassigned) */
NULL, /* 147 (unassigned) */
NULL, /* 148 (unassigned) */
NULL, /* 149 (unassigned) */
NULL, /* 150 (unassigned) */
NULL, /* 151 (unassigned) */
NULL, /* 152 (unassigned) */
NULL, /* 153 (unassigned) */
NULL, /* 154 (unassigned) */
NULL, /* 155 (unassigned) */
NULL, /* 156 (unassigned) */
NULL, /* 157 (unassigned) */
NULL, /* 158 (unassigned) */
NULL, /* 159 (unassigned) */
NULL, /* 160 (unassigned) */
NULL, /* 161 (unassigned) */
NULL, /* 162 (unassigned) */
NULL, /* 163 (unassigned) */
NULL, /* 164 (unassigned) */
NULL, /* 165 (unassigned) */
NULL, /* 166 (unassigned) */
NULL, /* 167 (unassigned) */
NULL, /* 168 (unassigned) */
NULL, /* 169 (unassigned) */
NULL, /* 170 (unassigned) */
NULL, /* 171 (unassigned) */
NULL, /* 172 (unassigned) */
NULL, /* 173 (unassigned) */
NULL, /* 174 (unassigned) */
NULL, /* 175 (unassigned) */
NULL, /* 176 (unassigned) */
NULL, /* 177 (unassigned) */
NULL, /* 178 (unassigned) */
NULL, /* 179 (unassigned) */
NULL, /* 180 (unassigned) */
NULL, /* 181 (unassigned) */
NULL, /* 182 (unassigned) */
NULL, /* 183 (unassigned) */
NULL, /* 184 (unassigned) */
NULL, /* 185 (unassigned) */
NULL, /* 186 (unassigned) */
NULL, /* 187 (unassigned) */
NULL, /* 188 (unassigned) */
NULL, /* 189 (unassigned) */
NULL, /* 190 (unassigned) */
NULL, /* 191 (unassigned) */
NULL, /* 192 (unassigned) */
NULL, /* 193 (unassigned) */
NULL, /* 194 (unassigned) */
NULL, /* 195 (unassigned) */
NULL, /* 196 (unassigned) */
NULL, /* 197 (unassigned) */
NULL, /* 198 (unassigned) */
NULL, /* 199 (unassigned) */
NULL, /* 200 (unassigned) */
NULL, /* 201 (unassigned) */
NULL, /* 202 (unassigned) */
NULL, /* 203 (unassigned) */
NULL, /* 204 (unassigned) */
NULL, /* 205 (unassigned) */
NULL, /* 206 (unassigned) */
NULL, /* 207 (unassigned) */
NULL, /* 208 (unassigned) */
NULL, /* 209 (unassigned) */
NULL, /* 210 (unassigned) */
NULL, /* 211 (unassigned) */
NULL, /* 212 (unassigned) */
NULL, /* 213 (unassigned) */
NULL, /* 214 (unassigned) */
NULL, /* 215 (unassigned) */
NULL, /* 216 (unassigned) */
NULL, /* 217 (unassigned) */
NULL, /* 218 (unassigned) */
NULL, /* 219 (unassigned) */
NULL, /* 220 (unassigned) */
NULL, /* 221 (unassigned) */
NULL, /* 222 (unassigned) */
NULL, /* 223 (unassigned) */
NULL, /* 224 (unassigned) */
NULL, /* 225 (unassigned) */
NULL, /* 226 (unassigned) */
NULL, /* 227 (unassigned) */
NULL, /* 228 (unassigned) */
NULL, /* 229 (unassigned) */
NULL, /* 230 (unassigned) */
NULL, /* 231 (unassigned) */
NULL, /* 232 (unassigned) */
NULL, /* 233 (unassigned) */
NULL, /* 234 (unassigned) */
NULL, /* 235 (unassigned) */
NULL, /* 236 (unassigned) */
NULL, /* 237 (unassigned) */
NULL, /* 238 (unassigned) */
NULL, /* 239 (unassigned) */
NULL, /* 240 (unassigned) */
NULL, /* 241 (unassigned) */
NULL, /* 242 (unassigned) */
NULL, /* 243 (unassigned) */
NULL, /* 244 (unassigned) */
NULL, /* 245 (unassigned) */
NULL, /* 246 (unassigned) */
NULL, /* 247 (unassigned) */
NULL, /* 248 (unassigned) */
NULL, /* 249 (unassigned) */
NULL, /* 250 (unassigned) */
NULL, /* 251 (unassigned) */
NULL, /* 252 (unassigned) */
"exptest-253", /* 253 (Use for experimentation and testing,
* RFC 3692)
*/
"exptest-254", /* 254 (Use for experimentation and testing,
* RFC 3692)
*/
"reserved", /* 255 (reserved) */
};
/* The function enforces the array index to be 8-bit. */
const char *
netdb_protoname (const nd_uint8_t protoid)
{
return netdb_protocol_names[protoid];
}

View File

@ -36,6 +36,7 @@
*/
extern const struct tok ipproto_values[];
extern const char *netdb_protoname (const nd_uint8_t);
#ifndef IPPROTO_IP
#define IPPROTO_IP 0 /* dummy for IP */
@ -109,7 +110,7 @@ extern const struct tok ipproto_values[];
* It appears that 62 used to be used, even though that's assigned to
* a protocol called CFTP; however, the only reference for CFTP is a
* Network Message from BBN back in 1982, so, for now, we support 62,
* aas well as 135, as a protocol number for mobility headers.
* as well as 135, as a protocol number for mobility headers.
*/
#define IPPROTO_MOBILITY_OLD 62
#endif

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok l2vpn_encaps_values[];

View File

@ -394,6 +394,11 @@ struct in6_addr {
* end of Apple deprecation workaround macros
*/
/*
* Function attributes, for various compilers.
*/
#include "funcattrs.h"
#ifndef min
#define min(a,b) ((a)>(b)?(b):(a))
#endif

View File

@ -82,19 +82,13 @@ extern int32_t thiszone; /* seconds offset from gmt to local time */
extern const char istr[];
#if !defined(HAVE_SNPRINTF)
int snprintf (char *str, size_t sz, const char *format, ...)
#ifdef __ATTRIBUTE___FORMAT_OK
__attribute__((format (printf, 3, 4)))
#endif /* __ATTRIBUTE___FORMAT_OK */
;
int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...)
PRINTFLIKE(3, 4);
#endif /* !defined(HAVE_SNPRINTF) */
#if !defined(HAVE_VSNPRINTF)
int vsnprintf (char *str, size_t sz, const char *format, va_list ap)
#ifdef __ATTRIBUTE___FORMAT_OK
__attribute__((format (printf, 3, 0)))
#endif /* __ATTRIBUTE___FORMAT_OK */
;
int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format),
va_list ap) PRINTFLIKE(3, 0);
#endif /* !defined(HAVE_VSNPRINTF) */
#ifndef HAVE_STRLCAT
@ -531,7 +525,7 @@ extern void ipx_netbios_print(netdissect_options *, const u_char *, u_int);
extern void ipx_print(netdissect_options *, const u_char *, u_int);
extern void isakmp_print(netdissect_options *, const u_char *, u_int, const u_char *);
extern void isakmp_rfc3948_print(netdissect_options *, const u_char *, u_int, const u_char *);
extern void isoclns_print(netdissect_options *, const u_char *, u_int, u_int);
extern void isoclns_print(netdissect_options *, const u_char *, u_int);
extern void krb_print(netdissect_options *, const u_char *);
extern void l2tp_print(netdissect_options *, const u_char *, u_int);
extern void lane_print(netdissect_options *, const u_char *, u_int, u_int);

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok nlpid_values[];

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
#ifdef HAVE_CONFIG_H

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
extern const struct tok oui_values[];

View File

@ -1039,10 +1039,6 @@ parse_elements(netdissect_options *ndo,
if (ssid.length != 0) {
if (ssid.length > sizeof(ssid.ssid) - 1)
return 0;
if (!ND_TTEST2(*(p + offset), ssid.length))
return 0;
if (length < ssid.length)
return 0;
memcpy(&ssid.ssid, p + offset, ssid.length);
offset += ssid.length;
length -= ssid.length;
@ -1068,10 +1064,6 @@ parse_elements(netdissect_options *ndo,
if (challenge.length >
sizeof(challenge.text) - 1)
return 0;
if (!ND_TTEST2(*(p + offset), challenge.length))
return 0;
if (length < challenge.length)
return 0;
memcpy(&challenge.text, p + offset,
challenge.length);
offset += challenge.length;
@ -1097,10 +1089,6 @@ parse_elements(netdissect_options *ndo,
if (rates.length != 0) {
if (rates.length > sizeof rates.rate)
return 0;
if (!ND_TTEST2(*(p + offset), rates.length))
return 0;
if (length < rates.length)
return 0;
memcpy(&rates.rate, p + offset, rates.length);
offset += rates.length;
length -= rates.length;
@ -1189,8 +1177,7 @@ parse_elements(netdissect_options *ndo,
offset += 3;
length -= 3;
memcpy(tim.bitmap, p + (tim.length - 3),
(tim.length - 3));
memcpy(tim.bitmap, p + offset, tim.length - 3);
offset += tim.length - 3;
length -= tim.length - 3;
/*

View File

@ -38,144 +38,186 @@ static const char *ftypes[] = {
"Data", /* 1 */
"ACK", /* 2 */
"Command", /* 3 */
"Reserved", /* 4 */
"Reserved", /* 5 */
"Reserved", /* 6 */
"Reserved", /* 7 */
"Reserved (0x4)", /* 4 */
"Reserved (0x5)", /* 5 */
"Reserved (0x6)", /* 6 */
"Reserved (0x7)", /* 7 */
};
static int
extract_header_length(uint16_t fc)
{
int len = 0;
switch ((fc >> 10) & 0x3) {
case 0x00:
if (fc & (1 << 6)) /* intra-PAN with none dest addr */
return -1;
break;
case 0x01:
return -1;
case 0x02:
len += 4;
break;
case 0x03:
len += 10;
break;
}
switch ((fc >> 14) & 0x3) {
case 0x00:
break;
case 0x01:
return -1;
case 0x02:
len += 4;
break;
case 0x03:
len += 10;
break;
}
if (fc & (1 << 6)) {
if (len < 2)
return -1;
len -= 2;
}
return len;
}
/*
* Frame Control subfields.
*/
#define FC_FRAME_TYPE(fc) ((fc) & 0x7)
#define FC_SECURITY_ENABLED 0x0008
#define FC_FRAME_PENDING 0x0010
#define FC_ACK_REQUEST 0x0020
#define FC_PAN_ID_COMPRESSION 0x0040
#define FC_DEST_ADDRESSING_MODE(fc) (((fc) >> 10) & 0x3)
#define FC_FRAME_VERSION(fc) (((fc) >> 12) & 0x3)
#define FC_SRC_ADDRESSING_MODE(fc) (((fc) >> 14) & 0x3)
#define FC_ADDRESSING_MODE_NONE 0x00
#define FC_ADDRESSING_MODE_RESERVED 0x01
#define FC_ADDRESSING_MODE_SHORT 0x02
#define FC_ADDRESSING_MODE_LONG 0x03
u_int
ieee802_15_4_if_print(netdissect_options *ndo,
const struct pcap_pkthdr *h, const u_char *p)
{
u_int caplen = h->caplen;
int hdrlen;
u_int hdrlen;
uint16_t fc;
uint8_t seq;
uint16_t panid = 0;
if (caplen < 3) {
ND_PRINT((ndo, "[|802.15.4] %x", caplen));
ND_PRINT((ndo, "[|802.15.4]"));
return caplen;
}
hdrlen = 3;
fc = EXTRACT_LE_16BITS(p);
hdrlen = extract_header_length(fc);
seq = EXTRACT_LE_8BITS(p + 2);
p += 3;
caplen -= 3;
ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7]));
ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[FC_FRAME_TYPE(fc)]));
if (ndo->ndo_vflag)
ND_PRINT((ndo,"seq %02x ", seq));
if (hdrlen == -1) {
ND_PRINT((ndo,"invalid! "));
return caplen;
}
if (!ndo->ndo_vflag) {
p+= hdrlen;
caplen -= hdrlen;
} else {
uint16_t panid = 0;
switch ((fc >> 10) & 0x3) {
case 0x00:
ND_PRINT((ndo,"none "));
break;
case 0x01:
ND_PRINT((ndo,"reserved destination addressing mode"));
return 0;
case 0x02:
panid = EXTRACT_LE_16BITS(p);
p += 2;
ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
p += 2;
break;
case 0x03:
panid = EXTRACT_LE_16BITS(p);
p += 2;
ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
p += 8;
break;
/*
* Destination address and PAN ID, if present.
*/
switch (FC_DEST_ADDRESSING_MODE(fc)) {
case FC_ADDRESSING_MODE_NONE:
if (fc & FC_PAN_ID_COMPRESSION) {
/*
* PAN ID compression; this requires that both
* the source and destination addresses be present,
* but the destination address is missing.
*/
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
if (ndo->ndo_vflag)
ND_PRINT((ndo,"none "));
break;
case FC_ADDRESSING_MODE_RESERVED:
if (ndo->ndo_vflag)
ND_PRINT((ndo,"reserved destination addressing mode"));
return hdrlen;
case FC_ADDRESSING_MODE_SHORT:
if (caplen < 2) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
panid = EXTRACT_LE_16BITS(p);
p += 2;
caplen -= 2;
hdrlen += 2;
if (caplen < 2) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
if (ndo->ndo_vflag)
ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
p += 2;
caplen -= 2;
hdrlen += 2;
break;
case FC_ADDRESSING_MODE_LONG:
if (caplen < 2) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
panid = EXTRACT_LE_16BITS(p);
p += 2;
caplen -= 2;
hdrlen += 2;
if (caplen < 8) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
if (ndo->ndo_vflag)
ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
p += 8;
caplen -= 8;
hdrlen += 8;
break;
}
if (ndo->ndo_vflag)
ND_PRINT((ndo,"< "));
switch ((fc >> 14) & 0x3) {
case 0x00:
/*
* Source address and PAN ID, if present.
*/
switch (FC_SRC_ADDRESSING_MODE(fc)) {
case FC_ADDRESSING_MODE_NONE:
if (ndo->ndo_vflag)
ND_PRINT((ndo,"none "));
break;
case 0x01:
break;
case FC_ADDRESSING_MODE_RESERVED:
if (ndo->ndo_vflag)
ND_PRINT((ndo,"reserved source addressing mode"));
return 0;
case 0x02:
if (!(fc & (1 << 6))) {
panid = EXTRACT_LE_16BITS(p);
p += 2;
return 0;
case FC_ADDRESSING_MODE_SHORT:
if (!(fc & FC_PAN_ID_COMPRESSION)) {
/*
* The source PAN ID is not compressed out, so
* fetch it. (Otherwise, we'll use the destination
* PAN ID, fetched above.)
*/
if (caplen < 2) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
panid = EXTRACT_LE_16BITS(p);
p += 2;
break;
case 0x03:
if (!(fc & (1 << 6))) {
panid = EXTRACT_LE_16BITS(p);
p += 2;
}
ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
p += 8;
break;
caplen -= 2;
hdrlen += 2;
}
caplen -= hdrlen;
if (caplen < 2) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
if (ndo->ndo_vflag)
ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
p += 2;
caplen -= 2;
hdrlen += 2;
break;
case FC_ADDRESSING_MODE_LONG:
if (!(fc & FC_PAN_ID_COMPRESSION)) {
/*
* The source PAN ID is not compressed out, so
* fetch it. (Otherwise, we'll use the destination
* PAN ID, fetched above.)
*/
if (caplen < 2) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
panid = EXTRACT_LE_16BITS(p);
p += 2;
caplen -= 2;
hdrlen += 2;
}
if (caplen < 8) {
ND_PRINT((ndo, "[|802.15.4]"));
return hdrlen;
}
if (ndo->ndo_vflag)
ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(ndo, p)));
p += 8;
caplen -= 8;
hdrlen += 8;
break;
}
if (!ndo->ndo_suppress_default_print)
ND_DEFAULTPRINT(p, caplen);
return 0;
return hdrlen;
}

View File

@ -42,7 +42,9 @@
#include "addrtoname.h"
#include "extract.h"
/*
* RFC 3561
*/
struct aodv_rreq {
uint8_t rreq_type; /* AODV message type (1) */
uint8_t rreq_flags; /* various flags */
@ -178,12 +180,17 @@ aodv_extension(netdissect_options *ndo,
{
const struct aodv_hello *ah;
ND_TCHECK(*ep);
switch (ep->type) {
case AODV_EXT_HELLO:
ah = (const struct aodv_hello *)(const void *)ep;
ND_TCHECK(*ah);
if (length < sizeof(struct aodv_hello))
goto trunc;
if (ep->length < 4) {
ND_PRINT((ndo, "\n\text HELLO - bad length %u", ep->length));
break;
}
ND_PRINT((ndo, "\n\text HELLO %ld ms",
(unsigned long)EXTRACT_32BITS(&ah->interval)));
break;

View File

@ -78,7 +78,7 @@ struct arp_pkthdr {
u_char ar_tha[]; /* target hardware address */
u_char ar_tpa[]; /* target protocol address */
#endif
#define ar_sha(ap) (((const u_char *)((ap)+1))+0)
#define ar_sha(ap) (((const u_char *)((ap)+1))+ 0)
#define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln)
#define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln)
#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln)
@ -189,6 +189,30 @@ isnonzero(const u_char *a, size_t len)
return (0);
}
static void
tpaddr_print_ip(netdissect_options *ndo,
const struct arp_pkthdr *ap, u_short pro)
{
if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
ND_PRINT((ndo, "<wrong proto type>"));
else if (PROTO_LEN(ap) != 4)
ND_PRINT((ndo, "<wrong len>"));
else
ND_PRINT((ndo, "%s", ipaddr_string(ndo, TPA(ap))));
}
static void
spaddr_print_ip(netdissect_options *ndo,
const struct arp_pkthdr *ap, u_short pro)
{
if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
ND_PRINT((ndo, "<wrong proto type>"));
else if (PROTO_LEN(ap) != 4)
ND_PRINT((ndo, "<wrong len>"));
else
ND_PRINT((ndo, "%s", ipaddr_string(ndo, SPA(ap))));
}
static void
atmarp_addr_print(netdissect_options *ndo,
const u_char *ha, u_int ha_len, const u_char *srca,
@ -204,6 +228,30 @@ atmarp_addr_print(netdissect_options *ndo,
}
}
static void
atmarp_tpaddr_print(netdissect_options *ndo,
const struct atmarp_pkthdr *ap, u_short pro)
{
if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
ND_PRINT((ndo, "<wrong proto type>"));
else if (ATMTPROTO_LEN(ap) != 4)
ND_PRINT((ndo, "<wrong tplen>"));
else
ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMTPA(ap))));
}
static void
atmarp_spaddr_print(netdissect_options *ndo,
const struct atmarp_pkthdr *ap, u_short pro)
{
if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
ND_PRINT((ndo, "<wrong proto type>"));
else if (ATMSPROTO_LEN(ap) != 4)
ND_PRINT((ndo, "<wrong splen>"));
else
ND_PRINT((ndo, "%s", ipaddr_string(ndo, ATMSPA(ap))));
}
static void
atmarp_print(netdissect_options *ndo,
const u_char *bp, u_int length, u_int caplen)
@ -252,18 +300,21 @@ atmarp_print(netdissect_options *ndo,
switch (op) {
case ARPOP_REQUEST:
ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, ATMTPA(ap))));
ND_PRINT((ndo, "who-has "));
atmarp_tpaddr_print(ndo, ap, pro);
if (ATMTHRD_LEN(ap) != 0) {
ND_PRINT((ndo, " ("));
atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap),
ATMTSA(ap), ATMTSLN(ap));
ND_PRINT((ndo, ")"));
}
ND_PRINT((ndo, "tell %s", ipaddr_string(ndo, ATMSPA(ap))));
ND_PRINT((ndo, " tell "));
atmarp_spaddr_print(ndo, ap, pro);
break;
case ARPOP_REPLY:
ND_PRINT((ndo, "%s is-at ", ipaddr_string(ndo, ATMSPA(ap))));
atmarp_spaddr_print(ndo, ap, pro);
ND_PRINT((ndo, " is-at "));
atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
ATMSSLN(ap));
break;
@ -280,11 +331,13 @@ atmarp_print(netdissect_options *ndo,
case ARPOP_INVREPLY:
atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
ATMSSLN(ap));
ND_PRINT((ndo, "at %s", ipaddr_string(ndo, ATMSPA(ap))));
ND_PRINT((ndo, "at "));
atmarp_spaddr_print(ndo, ap, pro);
break;
case ARPOP_NAK:
ND_PRINT((ndo, "for %s", ipaddr_string(ndo, ATMSPA(ap))));
ND_PRINT((ndo, "for "));
atmarp_spaddr_print(ndo, ap, pro);
break;
default:
@ -332,7 +385,7 @@ arp_print(netdissect_options *ndo,
break;
}
if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) {
if (!ND_TTEST2(*TPA(ap), PROTO_LEN(ap))) {
ND_PRINT((ndo, "%s", tstr));
ND_DEFAULTPRINT((const u_char *)ap, length);
return;
@ -367,16 +420,18 @@ arp_print(netdissect_options *ndo,
switch (op) {
case ARPOP_REQUEST:
ND_PRINT((ndo, "who-has %s", ipaddr_string(ndo, TPA(ap))));
ND_PRINT((ndo, "who-has "));
tpaddr_print_ip(ndo, ap, pro);
if (isnonzero((const u_char *)THA(ap), HRD_LEN(ap)))
ND_PRINT((ndo, " (%s)",
linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap))));
ND_PRINT((ndo, " tell %s", ipaddr_string(ndo, SPA(ap))));
ND_PRINT((ndo, " tell "));
spaddr_print_ip(ndo, ap, pro);
break;
case ARPOP_REPLY:
ND_PRINT((ndo, "%s is-at %s",
ipaddr_string(ndo, SPA(ap)),
spaddr_print_ip(ndo, ap, pro);
ND_PRINT((ndo, " is-at %s",
linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap))));
break;
@ -387,9 +442,9 @@ arp_print(netdissect_options *ndo,
break;
case ARPOP_REVREPLY:
ND_PRINT((ndo, "%s at %s",
linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap)),
ipaddr_string(ndo, TPA(ap))));
ND_PRINT((ndo, "%s at ",
linkaddr_string(ndo, THA(ap), linkaddr, HRD_LEN(ap))));
tpaddr_print_ip(ndo, ap, pro);
break;
case ARPOP_INVREQUEST:
@ -399,9 +454,9 @@ arp_print(netdissect_options *ndo,
break;
case ARPOP_INVREPLY:
ND_PRINT((ndo,"%s at %s",
linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap)),
ipaddr_string(ndo, SPA(ap))));
ND_PRINT((ndo,"%s at ",
linkaddr_string(ndo, SHA(ap), linkaddr, HRD_LEN(ap))));
spaddr_print_ip(ndo, ap, pro);
break;
default:

View File

@ -262,7 +262,7 @@ atm_if_print(netdissect_options *ndo,
if (*p == LLC_UI) {
if (ndo->ndo_eflag)
ND_PRINT((ndo, "CNLPID "));
isoclns_print(ndo, p + 1, length - 1, caplen - 1);
isoclns_print(ndo, p + 1, length - 1);
return hdrlen;
}

View File

@ -28,9 +28,17 @@
*/
static int
l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2)
l_strnstart(netdissect_options *ndo, const char *tstr1, u_int tl1,
const char *str2, u_int l2)
{
if (!ND_TTEST2(*str2, tl1)) {
/*
* We don't have tl1 bytes worth of captured data
* for the string, so we can't check for this
* string.
*/
return 0;
}
if (tl1 > l2)
return 0;
@ -41,19 +49,19 @@ void
beep_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */
if (l_strnstart(ndo, "MSG", 4, (const char *)bp, length)) /* A REQuest */
ND_PRINT((ndo, " BEEP MSG"));
else if (l_strnstart("RPY ", 4, (const char *)bp, length))
else if (l_strnstart(ndo, "RPY ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP RPY"));
else if (l_strnstart("ERR ", 4, (const char *)bp, length))
else if (l_strnstart(ndo, "ERR ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP ERR"));
else if (l_strnstart("ANS ", 4, (const char *)bp, length))
else if (l_strnstart(ndo, "ANS ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP ANS"));
else if (l_strnstart("NUL ", 4, (const char *)bp, length))
else if (l_strnstart(ndo, "NUL ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP NUL"));
else if (l_strnstart("SEQ ", 4, (const char *)bp, length))
else if (l_strnstart(ndo, "SEQ ", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP SEQ"));
else if (l_strnstart("END", 4, (const char *)bp, length))
else if (l_strnstart(ndo, "END", 4, (const char *)bp, length))
ND_PRINT((ndo, " BEEP END"));
else
ND_PRINT((ndo, " BEEP (payload or undecoded)"));

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Bidirectional Forwarding Detection (BFD) printer */

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Extensively modified by Hannes Gredler (hannes@juniper.net) for more
* Extensively modified by Hannes Gredler (hannes@gredler.at) for more
* complete BGP support.
*/
@ -756,11 +756,18 @@ decode_rt_routing_info(netdissect_options *ndo,
{
uint8_t route_target[8];
u_int plen;
char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */
/* NLRI "prefix length" from RFC 2858 Section 4. */
ND_TCHECK(pptr[0]);
plen = pptr[0]; /* get prefix length */
/* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits.
* RFC 4684 Section 4 defines the layout of "origin AS" and "route
* target" fields inside the "prefix" depending on its length.
*/
if (0 == plen) {
/* Without "origin AS", without "route target". */
snprintf(buf, buflen, "default route target");
return 1;
}
@ -768,20 +775,29 @@ decode_rt_routing_info(netdissect_options *ndo,
if (32 > plen)
return -1;
/* With at least "origin AS", possibly with "route target". */
ND_TCHECK_32BITS(pptr + 1);
as_printf(ndo, asbuf, sizeof(asbuf), EXTRACT_32BITS(pptr + 1));
plen-=32; /* adjust prefix length */
if (64 < plen)
return -1;
/* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 }
* and gives the number of octets in the variable-length "route
* target" field inside this NLRI "prefix". Look for it.
*/
memset(&route_target, 0, sizeof(route_target));
ND_TCHECK2(pptr[1], (plen + 7) / 8);
memcpy(&route_target, &pptr[1], (plen + 7) / 8);
ND_TCHECK2(pptr[5], (plen + 7) / 8);
memcpy(&route_target, &pptr[5], (plen + 7) / 8);
/* Which specification says to do this? */
if (plen % 8) {
((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
((0xff00 >> (plen % 8)) & 0xff);
}
snprintf(buf, buflen, "origin AS: %s, route target %s",
as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)),
asbuf,
bgp_vpn_rd_print(ndo, (u_char *)&route_target));
return 5 + (plen + 7) / 8;
@ -895,6 +911,7 @@ static const struct tok bgp_multicast_vpn_route_type_values[] = {
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
{ BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
{ 0, NULL}
};
static int
@ -959,13 +976,13 @@ decode_multicast_vpn(netdissect_options *ndo,
case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
offset = strlen(buf);
snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
bgp_vpn_rd_print(ndo, pptr),
as_printf(ndo, astostr, sizeof(astostr),
EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
pptr += BGP_VPN_RD_LEN;
pptr += BGP_VPN_RD_LEN + 4;
bgp_vpn_sg_print(ndo, pptr, buf, buflen);
break;
@ -1400,6 +1417,7 @@ bgp_attr_print(netdissect_options *ndo,
ND_TCHECK(tptr[0]);
ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values,
"?", tptr[0])));
ND_TCHECK(tptr[1]);
for (i = 0; i < tptr[1] * as_size; i += as_size) {
ND_TCHECK2(tptr[2 + i], as_size);
ND_PRINT((ndo, "%s ",
@ -1719,7 +1737,7 @@ bgp_attr_print(netdissect_options *ndo,
ND_PRINT((ndo, ", no SNPA"));
}
while (len - (tptr - pptr) > 0) {
while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
@ -1887,7 +1905,7 @@ bgp_attr_print(netdissect_options *ndo,
tptr += 3;
while (len - (tptr - pptr) > 0) {
while (tptr < pptr + len) {
switch (af<<8 | safi) {
case (AFNUM_INET<<8 | SAFNUM_UNICAST):
case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
@ -2116,11 +2134,11 @@ bgp_attr_print(netdissect_options *ndo,
{
uint8_t tunnel_type, flags;
ND_TCHECK2(tptr[0], 5);
tunnel_type = *(tptr+1);
flags = *tptr;
tlen = len;
ND_TCHECK2(tptr[0], 5);
ND_PRINT((ndo, "\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type),
tunnel_type,
@ -2175,35 +2193,42 @@ bgp_attr_print(netdissect_options *ndo,
uint8_t type;
uint16_t length;
ND_TCHECK2(tptr[0], 3);
tlen = len;
while (tlen >= 3) {
ND_TCHECK2(tptr[0], 3);
type = *tptr;
length = EXTRACT_16BITS(tptr+1);
tptr += 3;
tlen -= 3;
ND_PRINT((ndo, "\n\t %s TLV (%u), length %u",
tok2str(bgp_aigp_values, "Unknown", type),
type, length));
if (length < 3)
goto trunc;
length -= 3;
/*
* Check if we can read the TLV data.
*/
ND_TCHECK2(tptr[3], length - 3);
ND_TCHECK2(tptr[3], length);
switch (type) {
case BGP_AIGP_TLV:
ND_TCHECK2(tptr[3], 8);
if (length < 8)
goto trunc;
ND_PRINT((ndo, ", metric %" PRIu64,
EXTRACT_64BITS(tptr+3)));
EXTRACT_64BITS(tptr)));
break;
default:
if (ndo->ndo_vflag <= 1) {
print_unknown_data(ndo, tptr+3,"\n\t ", length-3);
print_unknown_data(ndo, tptr,"\n\t ", length);
}
}

View File

@ -322,6 +322,7 @@ bootp_print(netdissect_options *ndo,
if (EXTRACT_16BITS(&bp->bp_secs))
ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs)));
ND_TCHECK(bp->bp_flags);
ND_PRINT((ndo, ", Flags [%s]",
bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))));
if (ndo->ndo_vflag > 1)

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE 802.1ag Connectivity Fault Management (CFM) protocols printer */
@ -217,7 +217,7 @@ static const struct tok cfm_tlv_senderid_chassisid_values[] = {
static int
cfm_network_addr_print(netdissect_options *ndo,
register const u_char *tptr)
register const u_char *tptr, const u_int length)
{
u_int network_addr_type;
u_int hexdump = FALSE;
@ -227,6 +227,11 @@ cfm_network_addr_print(netdissect_options *ndo,
* 802.1ab specifies that this field width
* is only once octet
*/
if (length < 1) {
ND_PRINT((ndo, "\n\t Network Address Type (invalid, no data"));
return hexdump;
}
/* The calling function must make any due ND_TCHECK calls. */
network_addr_type = *tptr;
ND_PRINT((ndo, "\n\t Network Address Type %s (%u)",
tok2str(af_values, "Unknown", network_addr_type),
@ -237,10 +242,20 @@ cfm_network_addr_print(netdissect_options *ndo,
*/
switch(network_addr_type) {
case AFNUM_INET:
if (length != 1 + 4) {
ND_PRINT((ndo, "(invalid IPv4 address length %u)", length - 1));
hexdump = TRUE;
break;
}
ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr + 1)));
break;
case AFNUM_INET6:
if (length != 1 + 16) {
ND_PRINT((ndo, "(invalid IPv6 address length %u)", length - 1));
hexdump = TRUE;
break;
}
ND_PRINT((ndo, ", %s", ip6addr_string(ndo, tptr + 1)));
break;
@ -368,8 +383,11 @@ cfm_print(netdissect_options *ndo,
md_nameformat,
md_namelength));
/* -2 for the MA short name format and length */
if (md_namelength > names_data_remaining - 2) {
/*
* -3 for the MA short name format and length and one byte
* of MA short name.
*/
if (md_namelength > names_data_remaining - 3) {
ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining - 2));
return;
}
@ -581,11 +599,12 @@ cfm_print(netdissect_options *ndo,
if (cfm_tlv_len < 1) {
ND_PRINT((ndo, " (too short, must be >= 1)"));
return;
goto next_tlv;
}
/*
* Get the Chassis ID length and check it.
* IEEE 802.1Q-2014 Section 21.5.3.1
*/
chassis_id_length = *tptr;
tptr++;
@ -593,9 +612,14 @@ cfm_print(netdissect_options *ndo,
cfm_tlv_len--;
if (chassis_id_length) {
/*
* IEEE 802.1Q-2014 Section 21.5.3.2: Chassis ID Subtype, references
* IEEE 802.1AB-2005 Section 9.5.2.2, subsequently
* IEEE 802.1AB-2016 Section 8.5.2.2: chassis ID subtype
*/
if (cfm_tlv_len < 1) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
return;
goto next_tlv;
}
chassis_id_type = *tptr;
cfm_tlv_len--;
@ -608,16 +632,22 @@ cfm_print(netdissect_options *ndo,
if (cfm_tlv_len < chassis_id_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
return;
goto next_tlv;
}
/* IEEE 802.1Q-2014 Section 21.5.3.3: Chassis ID */
switch (chassis_id_type) {
case CFM_CHASSIS_ID_MAC_ADDRESS:
if (chassis_id_length != ETHER_ADDR_LEN) {
ND_PRINT((ndo, " (invalid MAC address length)"));
hexdump = TRUE;
break;
}
ND_PRINT((ndo, "\n\t MAC %s", etheraddr_string(ndo, tptr + 1)));
break;
case CFM_CHASSIS_ID_NETWORK_ADDRESS:
hexdump |= cfm_network_addr_print(ndo, tptr);
hexdump |= cfm_network_addr_print(ndo, tptr + 1, chassis_id_length);
break;
case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */
@ -640,38 +670,53 @@ cfm_print(netdissect_options *ndo,
/*
* Check if there is a Management Address.
* IEEE 802.1Q-2014 Section 21.5.3.4: Management Address Domain Length
* This and all subsequent fields are not present if the TLV length
* allows only the above fields.
*/
if (cfm_tlv_len == 0) {
/* No, there isn't; we're done. */
return;
break;
}
/* Here mgmt_addr_length stands for the management domain length. */
mgmt_addr_length = *tptr;
tptr++;
tlen--;
cfm_tlv_len--;
ND_PRINT((ndo, "\n\t Management Address Domain Length %u", mgmt_addr_length));
if (mgmt_addr_length) {
/* IEEE 802.1Q-2014 Section 21.5.3.5: Management Address Domain */
if (cfm_tlv_len < mgmt_addr_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
return;
goto next_tlv;
}
cfm_tlv_len -= mgmt_addr_length;
/*
* XXX - this is an OID; print it as such.
*/
hex_print(ndo, "\n\t Management Address Domain: ", tptr, mgmt_addr_length);
tptr += mgmt_addr_length;
tlen -= mgmt_addr_length;
/*
* IEEE 802.1Q-2014 Section 21.5.3.6: Management Address Length
* This field is present if Management Address Domain Length is not 0.
*/
if (cfm_tlv_len < 1) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
return;
ND_PRINT((ndo, " (Management Address Length is missing)"));
hexdump = TRUE;
break;
}
/* Here mgmt_addr_length stands for the management address length. */
mgmt_addr_length = *tptr;
tptr++;
tlen--;
cfm_tlv_len--;
ND_PRINT((ndo, "\n\t Management Address Length %u", mgmt_addr_length));
if (mgmt_addr_length) {
/* IEEE 802.1Q-2014 Section 21.5.3.7: Management Address */
if (cfm_tlv_len < mgmt_addr_length) {
ND_PRINT((ndo, "\n\t (TLV too short)"));
return;
@ -680,6 +725,7 @@ cfm_print(netdissect_options *ndo,
/*
* XXX - this is a TransportDomain; print it as such.
*/
hex_print(ndo, "\n\t Management Address: ", tptr, mgmt_addr_length);
tptr += mgmt_addr_length;
tlen -= mgmt_addr_length;
}
@ -703,6 +749,7 @@ cfm_print(netdissect_options *ndo,
if (hexdump || ndo->ndo_vflag > 1)
print_unknown_data(ndo, tlv_ptr, "\n\t ", cfm_tlv_len);
next_tlv:
tptr+=cfm_tlv_len;
tlen-=cfm_tlv_len;
}

View File

@ -46,21 +46,18 @@ static const struct tok chdlc_cast_values[] = {
u_int
chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
{
register u_int length = h->len;
register u_int caplen = h->caplen;
if (caplen < CHDLC_HDRLEN) {
ND_PRINT((ndo, "[|chdlc]"));
return (caplen);
}
return (chdlc_print(ndo, p,length));
return chdlc_print(ndo, p, h->len);
}
u_int
chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
{
u_int proto;
const u_char *bp = p;
if (length < CHDLC_HDRLEN)
goto trunc;
ND_TCHECK2(*p, CHDLC_HDRLEN);
proto = EXTRACT_16BITS(&p[2]);
if (ndo->ndo_eflag) {
ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ",
@ -94,12 +91,15 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
break;
case ETHERTYPE_ISO:
/* is the fudge byte set ? lets verify by spotting ISO headers */
if (length < 2)
goto trunc;
ND_TCHECK_16BITS(p);
if (*(p+1) == 0x81 ||
*(p+1) == 0x82 ||
*(p+1) == 0x83)
isoclns_print(ndo, p + 1, length - 1, ndo->ndo_snapend - p - 1);
isoclns_print(ndo, p + 1, length - 1);
else
isoclns_print(ndo, p, length, ndo->ndo_snapend - p);
isoclns_print(ndo, p, length);
break;
default:
if (!ndo->ndo_eflag)
@ -108,6 +108,10 @@ chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
}
return (CHDLC_HDRLEN);
trunc:
ND_PRINT((ndo, "[|chdlc]"));
return ndo->ndo_snapend - bp;
}
/*

View File

@ -159,7 +159,7 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v1 *nh;
register const struct nfrec_v1 *nr;
struct protoent *pent;
const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@ -211,14 +211,13 @@ cnfp_v1_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
pent = getprotobynumber(nr->proto);
if (!pent || ndo->ndo_nflag)
ND_PRINT((ndo, "%u ", nr->proto));
if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
ND_PRINT((ndo, "%s ", p_name));
else
ND_PRINT((ndo, "%s ", pent->p_name));
ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
if (pent && pent->p_proto == IPPROTO_TCP) {
if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
@ -249,7 +248,7 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v5 *nh;
register const struct nfrec_v5 *nr;
struct protoent *pent;
const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@ -308,14 +307,13 @@ cnfp_v5_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
pent = getprotobynumber(nr->proto);
if (!pent || ndo->ndo_nflag)
ND_PRINT((ndo, "%u ", nr->proto));
if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
ND_PRINT((ndo, "%s ", p_name));
else
ND_PRINT((ndo, "%s ", pent->p_name));
ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
if (pent && pent->p_proto == IPPROTO_TCP) {
if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",
@ -346,7 +344,7 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp)
{
register const struct nfhdr_v6 *nh;
register const struct nfrec_v6 *nr;
struct protoent *pent;
const char *p_name;
int nrecs, ver;
#if 0
time_t t;
@ -405,14 +403,13 @@ cnfp_v6_print(netdissect_options *ndo, const u_char *cp)
ND_PRINT((ndo, ">> %s\n ", intoa(nr->nhop_ina.s_addr)));
pent = getprotobynumber(nr->proto);
if (!pent || ndo->ndo_nflag)
ND_PRINT((ndo, "%u ", nr->proto));
if (!ndo->ndo_nflag && (p_name = netdb_protoname(nr->proto)) != NULL)
ND_PRINT((ndo, "%s ", p_name));
else
ND_PRINT((ndo, "%s ", pent->p_name));
ND_PRINT((ndo, "%u ", nr->proto));
/* tcp flags for tcp only */
if (pent && pent->p_proto == IPPROTO_TCP) {
if (nr->proto == IPPROTO_TCP) {
int flags;
flags = nr->tcp_flags;
ND_PRINT((ndo, "%s%s%s%s%s%s%s",

View File

@ -542,6 +542,7 @@ decnet_print(netdissect_options *ndo,
length -= padlen;
caplen -= padlen;
rhp = (const union routehdr *)&(ap[sizeof(short)]);
ND_TCHECK(rhp->rh_short.sh_flags);
mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
}
@ -613,6 +614,7 @@ print_decnet_ctlmsg(netdissect_options *ndo,
register const union routehdr *rhp, u_int length,
u_int caplen)
{
/* Our caller has already checked for mflags */
int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
register const union controlmsg *cmp = (const union controlmsg *)rhp;
int src, dst, info, blksize, eco, ueco, hello, other, vers;

View File

@ -518,6 +518,10 @@ dhcp6opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "...)"));
break;
case DH6OPT_RECONF_MSG:
if (optlen != 1) {
ND_PRINT((ndo, " ?)"));
break;
}
tp = (const u_char *)(dh6o + 1);
switch (*tp) {
case DH6_RENEW:

View File

@ -151,15 +151,14 @@ ns_nprint(netdissect_options *ndo,
register u_int i, l;
register const u_char *rp = NULL;
register int compress = 0;
int chars_processed;
int elt;
int data_size = ndo->ndo_snapend - bp;
u_int offset, max_offset;
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
chars_processed = 1;
max_offset = (u_int)(cp - bp);
if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) {
compress = 0;
rp = cp + l;
@ -174,24 +173,28 @@ ns_nprint(netdissect_options *ndo,
}
if (!ND_TTEST2(*cp, 1))
return(NULL);
cp = bp + (((i << 8) | *cp) & 0x3fff);
offset = (((i << 8) | *cp) & 0x3fff);
/*
* This must move backwards in the packet.
* No RFC explicitly says that, but BIND's
* name decompression code requires it,
* as a way of preventing infinite loops
* and other bad behavior, and it's probably
* what was intended (compress by pointing
* to domain name suffixes already seen in
* the packet).
*/
if (offset >= max_offset) {
ND_PRINT((ndo, "<BAD PTR>"));
return(NULL);
}
max_offset = offset;
cp = bp + offset;
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
i = *cp++;
chars_processed++;
/*
* If we've looked at every character in
* the message, this pointer will make
* us look at some character again,
* which means we're looping.
*/
if (chars_processed >= data_size) {
ND_PRINT((ndo, "<LOOP>"));
return (NULL);
}
continue;
}
if ((i & INDIR_MASK) == EDNS0_MASK) {
@ -212,14 +215,12 @@ ns_nprint(netdissect_options *ndo,
}
cp += l;
chars_processed += l;
ND_PRINT((ndo, "."));
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
if (!ND_TTEST2(*cp, 1))
return(NULL);
i = *cp++;
chars_processed++;
if (!compress)
rp += l + 1;
}

View File

@ -182,7 +182,9 @@ eap_print(netdissect_options *ndo,
switch (eap->type) {
case EAP_FRAME_TYPE_PACKET:
ND_TCHECK_8BITS(tptr);
type = *(tptr);
ND_TCHECK_16BITS(tptr+2);
len = EXTRACT_16BITS(tptr+2);
ND_PRINT((ndo, ", %s (%u), id %u, len %u",
tok2str(eap_code_values, "unknown", type),
@ -193,10 +195,11 @@ eap_print(netdissect_options *ndo,
ND_TCHECK2(*tptr, len);
if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */
ND_TCHECK_8BITS(tptr+4);
subtype = *(tptr+4);
ND_PRINT((ndo, "\n\t\t Type %s (%u)",
tok2str(eap_type_values, "unknown", *(tptr+4)),
*(tptr + 4)));
tok2str(eap_type_values, "unknown", subtype),
subtype));
switch (subtype) {
case EAP_TYPE_IDENTITY:
@ -222,6 +225,7 @@ eap_print(netdissect_options *ndo,
* type one octet per type
*/
while (count < len) {
ND_TCHECK_8BITS(tptr+count);
ND_PRINT((ndo, " %s (%u),",
tok2str(eap_type_values, "unknown", *(tptr+count)),
*(tptr + count)));
@ -230,19 +234,23 @@ eap_print(netdissect_options *ndo,
break;
case EAP_TYPE_TTLS:
ND_PRINT((ndo, " TTLSv%u",
EAP_TTLS_VERSION(*(tptr + 5)))); /* fall through */
case EAP_TYPE_TLS:
ND_TCHECK_8BITS(tptr + 5);
if (subtype == EAP_TYPE_TTLS)
ND_PRINT((ndo, " TTLSv%u",
EAP_TTLS_VERSION(*(tptr + 5))));
ND_PRINT((ndo, " flags [%s] 0x%02x,",
bittok2str(eap_tls_flags_values, "none", *(tptr+5)),
*(tptr + 5)));
if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
ND_TCHECK_32BITS(tptr + 6);
ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
}
break;
case EAP_TYPE_FAST:
ND_TCHECK_8BITS(tptr + 5);
ND_PRINT((ndo, " FASTv%u",
EAP_TTLS_VERSION(*(tptr + 5))));
ND_PRINT((ndo, " flags [%s] 0x%02x,",
@ -250,6 +258,7 @@ eap_print(netdissect_options *ndo,
*(tptr + 5)));
if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
ND_TCHECK_32BITS(tptr + 6);
ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
}
@ -258,6 +267,7 @@ eap_print(netdissect_options *ndo,
case EAP_TYPE_AKA:
case EAP_TYPE_SIM:
ND_TCHECK_8BITS(tptr + 5);
ND_PRINT((ndo, " subtype [%s] 0x%02x,",
tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)),
*(tptr + 5)));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
* Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at>
* The TCPDUMP project
*
* Redistribution and use in source and binary forms, with or without
@ -31,6 +31,7 @@
/*
* packet format documented at
* http://www.rhyshaden.com/eigrp.htm
* RFC 7868
*/
struct eigrp_common_header {
@ -246,6 +247,12 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
/* ok they seem to want to know everything - lets fully decode it */
if (len < sizeof(struct eigrp_common_header)) {
ND_PRINT((ndo, "EIGRP %s, length: %u (too short, < %u)",
tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
len, (u_int) sizeof(struct eigrp_common_header)));
return;
}
tlen=len-sizeof(struct eigrp_common_header);
/* FIXME print other header info */
@ -286,6 +293,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
eigrp_tlv_type,
eigrp_tlv_len));
if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) sizeof(struct eigrp_tlv_header)));
break;
}
tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
@ -296,6 +308,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_GENERAL_PARM:
tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm))));
break;
}
ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
@ -308,6 +325,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_SW_VERSION:
tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version))));
break;
}
ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u",
tlv_ptr.eigrp_tlv_sw_version->ios_major,
@ -318,6 +340,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_IP_INT:
tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int))));
break;
}
bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
if (bit_length > 32) {
@ -347,6 +374,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_IP_EXT:
tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext))));
break;
}
bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
if (bit_length > 32) {
@ -384,6 +416,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_CABLE_SETUP:
tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup))));
break;
}
ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
@ -393,6 +430,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_INT:
tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int))));
break;
}
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
@ -416,6 +458,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
case EIGRP_TLV_AT_EXT:
tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) {
ND_PRINT((ndo, " (too short, < %u)",
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext))));
break;
}
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),

View File

@ -145,6 +145,39 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
}
#endif
#ifdef HAVE_EVP_CIPHERINIT_EX
/*
* Initialize the cipher by calling EVP_CipherInit_ex(), because
* calling EVP_CipherInit() will reset the cipher context, clearing
* the cipher, so calling it twice, with the second call having a
* null cipher, will clear the already-set cipher. EVP_CipherInit_ex(),
* however, won't reset the cipher context, so you can use it to specify
* the IV oin a second call after a first call to EVP_CipherInit_ex()
* to set the cipher and the key.
*
* XXX - is there some reason why we need to make two calls?
*/
static int
set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key,
const unsigned char *iv, int enc)
{
return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
}
#else
/*
* Initialize the cipher by calling EVP_CipherInit(), because we don't
* have EVP_CipherInit_ex(); we rely on it not trashing the context.
*/
static int
set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key,
const unsigned char *iv, int enc)
{
return EVP_CipherInit(ctx, cipher, key, iv, enc);
}
#endif
/*
* this will adjust ndo_packetp and ndo_snapend to new buffer!
*/
@ -156,8 +189,10 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
{
struct sa_list *sa;
const u_char *iv;
int len;
unsigned int len;
EVP_CIPHER_CTX *ctx;
unsigned int block_size, output_buffer_size;
u_char *output_buffer;
/* initiator arg is any non-zero value */
if(initiator) initiator=1;
@ -188,17 +223,36 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL)
return 0;
if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0)
if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
EVP_CipherInit(ctx, NULL, NULL, iv, 0);
EVP_Cipher(ctx, __DECONST(u_char *, buf), buf, len);
set_cipher_parameters(ctx, NULL, NULL, iv, 0);
/*
* Allocate a buffer for the decrypted data.
* The output buffer must be separate from the input buffer, and
* its size must be a multiple of the cipher block size.
*/
block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
output_buffer_size = len + (block_size - len % block_size);
output_buffer = (u_char *)malloc(output_buffer_size);
if (output_buffer == NULL) {
(*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
EVP_CIPHER_CTX_free(ctx);
return 0;
}
EVP_Cipher(ctx, output_buffer, buf, len);
EVP_CIPHER_CTX_free(ctx);
/*
* XXX - of course this is wrong, because buf is a const buffer,
* but changing this would require a more complicated fix.
*/
memcpy(__DECONST(u_char *, buf), output_buffer, len);
free(output_buffer);
ndo->ndo_packetp = buf;
ndo->ndo_snapend = end;
return 1;
}
USES_APPLE_RST
@ -606,6 +660,8 @@ esp_print(netdissect_options *ndo,
const u_char *ivoff;
const u_char *p;
EVP_CIPHER_CTX *ctx;
unsigned int block_size, output_buffer_size;
u_char *output_buffer;
#endif
esp = (const struct newesp *)bp;
@ -703,7 +759,9 @@ esp_print(netdissect_options *ndo,
ep = bp2 + len;
}
/* pointer to the IV, if there is one */
ivoff = (const u_char *)(esp + 1) + 0;
/* length of the IV, if there is one; 0, if there isn't */
ivlen = sa->ivlen;
secret = sa->secret;
ep = ep - sa->authlen;
@ -711,14 +769,37 @@ esp_print(netdissect_options *ndo,
if (sa->evp) {
ctx = EVP_CIPHER_CTX_new();
if (ctx != NULL) {
if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0)
if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
p = ivoff;
EVP_CipherInit(ctx, NULL, NULL, p, 0);
EVP_Cipher(ctx, __DECONST(u_char *, p + ivlen),
p + ivlen, ep - (p + ivlen));
set_cipher_parameters(ctx, NULL, NULL, p, 0);
len = ep - (p + ivlen);
/*
* Allocate a buffer for the decrypted data.
* The output buffer must be separate from the
* input buffer, and its size must be a multiple
* of the cipher block size.
*/
block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
output_buffer_size = len + (block_size - len % block_size);
output_buffer = (u_char *)malloc(output_buffer_size);
if (output_buffer == NULL) {
(*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
EVP_CIPHER_CTX_free(ctx);
return -1;
}
EVP_Cipher(ctx, output_buffer, p + ivlen, len);
EVP_CIPHER_CTX_free(ctx);
/*
* XXX - of course this is wrong, because buf is a
* const buffer, but changing this would require a
* more complicated fix.
*/
memcpy(__DECONST(u_char *, p + ivlen), output_buffer, len);
free(output_buffer);
advance = ivoff - (const u_char *)esp + ivlen;
} else
advance = sizeof(struct newesp);

View File

@ -366,7 +366,7 @@ ethertype_print(netdissect_options *ndo,
ND_PRINT((ndo, " [|osi]"));
return (1);
}
isoclns_print(ndo, p + 1, length - 1, caplen - 1);
isoclns_print(ndo, p + 1, length - 1);
return(1);
case ETHERTYPE_PPPOED:

View File

@ -329,7 +329,7 @@ fr_print(netdissect_options *ndo,
case NLPID_CLNP:
case NLPID_ESIS:
case NLPID_ISIS:
isoclns_print(ndo, p - 1, length + 1, ndo->ndo_snapend - p + 1); /* OSI printers need the NLPID field */
isoclns_print(ndo, p - 1, length + 1); /* OSI printers need the NLPID field */
break;
case NLPID_SNAP:

View File

@ -27,10 +27,11 @@
#include <netdissect-stdinc.h>
#include "ip6.h"
#include "netdissect.h"
#include "extract.h"
#include "ip6.h"
int
frag6_print(netdissect_options *ndo, register const u_char *bp, register const u_char *bp2)
{
@ -40,7 +41,7 @@ frag6_print(netdissect_options *ndo, register const u_char *bp, register const u
dp = (const struct ip6_frag *)bp;
ip6 = (const struct ip6_hdr *)bp2;
ND_TCHECK(dp->ip6f_offlg);
ND_TCHECK(*dp);
if (ndo->ndo_vflag) {
ND_PRINT((ndo, "frag (0x%08x:%d|%ld)",

View File

@ -226,7 +226,7 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
atalk_print(ndo, bp, len);
break;
case ETHERTYPE_GRE_ISO:
isoclns_print(ndo, bp, len, ndo->ndo_snapend - bp);
isoclns_print(ndo, bp, len);
break;
case ETHERTYPE_TEB:
ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL);

View File

@ -270,6 +270,8 @@ dhcpv4_print(netdissect_options *ndo,
i = 0;
while (i < length) {
if (i + 2 > length)
return -1;
tlv = cp + i;
type = (uint8_t)tlv[0];
optlen = (uint8_t)tlv[1];
@ -281,6 +283,8 @@ dhcpv4_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s", tok2str(dh4opt_str, "Unknown", type)));
ND_PRINT((ndo," (%u)", optlen + 2 ));
if (i + 2 + optlen > length)
return -1;
switch (type) {
case DH4OPT_DNS_SERVERS:
@ -318,6 +322,8 @@ dhcpv6_print(netdissect_options *ndo,
i = 0;
while (i < length) {
if (i + 4 > length)
return -1;
tlv = cp + i;
type = EXTRACT_16BITS(tlv);
optlen = EXTRACT_16BITS(tlv + 2);
@ -329,6 +335,8 @@ dhcpv6_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s", tok2str(dh6opt_str, "Unknown", type)));
ND_PRINT((ndo," (%u)", optlen + 4 ));
if (i + 4 + optlen > length)
return -1;
switch (type) {
case DH6OPT_DNS_SERVERS:

View File

@ -582,6 +582,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
ip = (const struct ip *)bp;
ndo->ndo_snaplen = ndo->ndo_snapend - bp;
snapend_save = ndo->ndo_snapend;
ND_TCHECK_16BITS(&ip->ip_len);
ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len));
ndo->ndo_snapend = snapend_save;
}
@ -599,7 +600,8 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
* to check if an extension header is present. This is expedient,
* however not all implementations set the length field proper.
*/
if (!ext_dp->icmp_length) {
if (!ext_dp->icmp_length &&
ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) {
vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
vec[0].len = plen - ICMP_EXTD_MINLEN;
if (in_cksum(vec, 1)) {
@ -620,12 +622,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
}
hlen = plen - ICMP_EXTD_MINLEN;
vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
vec[0].len = hlen;
ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
in_cksum(vec, 1) ? "in" : "",
hlen));
if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) {
vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res;
vec[0].len = hlen;
ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u",
EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
in_cksum(vec, 1) ? "in" : "",
hlen));
}
hlen -= 4; /* subtract common header size */
obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data;

View File

@ -1131,6 +1131,7 @@ icmp6_print(netdissect_options *ndo,
if (ndo->ndo_vflag) {
ND_TCHECK(dp->icmp6_data16[0]);
ND_PRINT((ndo,", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])));
ND_TCHECK(dp->icmp6_data16[1]);
if (dp->icmp6_data16[1] & 0xc0)
ND_PRINT((ndo," "));
if (dp->icmp6_data16[1] & 0x80)
@ -1698,6 +1699,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
needcomma = 0;
ND_TCHECK2(*dp, sizeof(*ni6));
ni6 = (const struct icmp6_nodeinfo *)dp;
ND_PRINT((ndo," node information reply"));
ND_PRINT((ndo," (")); /*)*/
@ -1752,6 +1754,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
ND_PRINT((ndo,", "));
ND_PRINT((ndo,"DNS name"));
cp = (const u_char *)(ni6 + 1) + 4;
ND_TCHECK(cp[0]);
if (cp[0] == ep - cp - 1) {
/* icmp-name-lookup-03, pascal string */
if (ndo->ndo_vflag)

View File

@ -54,7 +54,7 @@ static const struct tok ip_option_values[] = {
/*
* print the recorded route in an IP RR, LSRR or SSRR option.
*/
static void
static int
ip_printroute(netdissect_options *ndo,
register const u_char *cp, u_int length)
{
@ -63,19 +63,25 @@ ip_printroute(netdissect_options *ndo,
if (length < 3) {
ND_PRINT((ndo, " [bad length %u]", length));
return;
return (0);
}
if ((length + 1) & 3)
ND_PRINT((ndo, " [bad length %u]", length));
ND_TCHECK(cp[2]);
ptr = cp[2] - 1;
if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
ND_PRINT((ndo, " [bad ptr %u]", cp[2]));
for (len = 3; len < length; len += 4) {
ND_TCHECK2(cp[len], 4);
ND_PRINT((ndo, " %s", ipaddr_string(ndo, &cp[len])));
if (ptr > len)
ND_PRINT((ndo, ","));
}
return (0);
trunc:
return (-1);
}
/*
@ -162,7 +168,7 @@ nextproto4_cksum(netdissect_options *ndo,
return (in_cksum(vec, 2));
}
static void
static int
ip_printts(netdissect_options *ndo,
register const u_char *cp, u_int length)
{
@ -173,16 +179,18 @@ ip_printts(netdissect_options *ndo,
if (length < 4) {
ND_PRINT((ndo, "[bad length %u]", length));
return;
return (0);
}
ND_PRINT((ndo, " TS{"));
hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
if ((length - 4) & (hoplen-1))
ND_PRINT((ndo, "[bad length %u]", length));
ND_TCHECK(cp[2]);
ptr = cp[2] - 1;
len = 0;
if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
ND_PRINT((ndo, "[bad ptr %u]", cp[2]));
ND_TCHECK(cp[3]);
switch (cp[3]&0xF) {
case IPOPT_TS_TSONLY:
ND_PRINT((ndo, "TSONLY"));
@ -211,6 +219,7 @@ ip_printts(netdissect_options *ndo,
for (len = 4; len < length; len += hoplen) {
if (ptr == len)
type = " ^ ";
ND_TCHECK2(cp[len], hoplen);
ND_PRINT((ndo, "%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
hoplen!=8 ? "" : ipaddr_string(ndo, &cp[len])));
type = " ";
@ -223,6 +232,10 @@ ip_printts(netdissect_options *ndo,
ND_PRINT((ndo, " [%d hops not recorded]} ", cp[3]>>4));
else
ND_PRINT((ndo, "}"));
return (0);
trunc:
return (-1);
}
/*
@ -272,13 +285,15 @@ ip_optprint(netdissect_options *ndo,
return;
case IPOPT_TS:
ip_printts(ndo, cp, option_len);
if (ip_printts(ndo, cp, option_len) == -1)
goto trunc;
break;
case IPOPT_RR: /* fall through */
case IPOPT_SSRR:
case IPOPT_LSRR:
ip_printroute(ndo, cp, option_len);
if (ip_printroute(ndo, cp, option_len) == -1)
goto trunc;
break;
case IPOPT_RA:
@ -324,7 +339,7 @@ static void
ip_print_demux(netdissect_options *ndo,
struct ip_print_demux_state *ipds)
{
struct protoent *proto;
const char *p_name;
again:
switch (ipds->nh) {
@ -490,8 +505,8 @@ ip_print_demux(netdissect_options *ndo,
#endif
default:
if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
ND_PRINT((ndo, " %s", proto->p_name));
if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(ipds->nh)) != NULL)
ND_PRINT((ndo, " %s", p_name));
else
ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
ND_PRINT((ndo, " %d", ipds->len));
@ -532,7 +547,7 @@ ip_print(netdissect_options *ndo,
u_int hlen;
struct cksum_vec vec[1];
uint16_t sum, ip_sum;
struct protoent *proto;
const char *p_name;
ipds->ip = (const struct ip *)bp;
ND_TCHECK(ipds->ip->ip_vhl);
@ -677,8 +692,8 @@ ip_print(netdissect_options *ndo,
*/
ND_PRINT((ndo, "%s > %s:", ipaddr_string(ndo, &ipds->ip->ip_src),
ipaddr_string(ndo, &ipds->ip->ip_dst)));
if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
ND_PRINT((ndo, " %s", proto->p_name));
if (!ndo->ndo_nflag && (p_name = netdb_protoname(ipds->ip->ip_p)) != NULL)
ND_PRINT((ndo, " %s", p_name));
else
ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p));
}

View File

@ -280,6 +280,8 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
advance = sizeof(struct ip6_hdr);
nh = ip6->ip6_nxt;
while (cp < ndo->ndo_snapend && advance > 0) {
if (len < (u_int)advance)
goto trunc;
cp += advance;
len -= advance;
@ -322,10 +324,15 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
* mobility header.
*/
advance = mobility_print(ndo, cp, (const u_char *)ip6);
if (advance < 0)
return;
nh = *cp;
return;
case IPPROTO_ROUTING:
ND_TCHECK(*cp);
advance = rt6_print(ndo, cp, (const u_char *)ip6);
if (advance < 0)
return;
nh = *cp;
break;
case IPPROTO_SCTP:
@ -345,12 +352,16 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
return;
case IPPROTO_AH:
advance = ah_print(ndo, cp);
if (advance < 0)
return;
nh = *cp;
break;
case IPPROTO_ESP:
{
int enh, padlen;
advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
if (advance < 0)
return;
nh = enh & 0xff;
len -= padlen;
break;

View File

@ -35,12 +35,12 @@
#include <netdissect-stdinc.h>
#include "ip6.h"
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
#include "ip6.h"
static void
ip6_sopt_print(netdissect_options *ndo, const u_char *bp, int len)
{

View File

@ -51,6 +51,7 @@
#include "ip.h"
#include "ip6.h"
#include "ipproto.h"
/* refer to RFC 2408 */
@ -427,7 +428,7 @@ struct notify_messages {
char *msg;
};
/* 3.8 Notification Payload */
/* 3.8 Authentication Payload */
struct ikev2_auth {
struct isakmp_gen h;
uint8_t auth_method; /* Protocol-ID */
@ -911,21 +912,25 @@ struct attrmap {
static const u_char *
ikev1_attrmap_print(netdissect_options *ndo,
const u_char *p, const u_char *ep,
const u_char *p, const u_char *ep2,
const struct attrmap *map, size_t nmap)
{
int totlen;
uint32_t t, v;
ND_TCHECK(p[0]);
if (p[0] & 0x80)
totlen = 4;
else
else {
ND_TCHECK_16BITS(&p[2]);
totlen = 4 + EXTRACT_16BITS(&p[2]);
if (ep < p + totlen) {
}
if (ep2 < p + totlen) {
ND_PRINT((ndo,"[|attr]"));
return ep + 1;
return ep2 + 1;
}
ND_TCHECK_16BITS(&p[0]);
ND_PRINT((ndo,"("));
t = EXTRACT_16BITS(&p[0]) & 0x7fff;
if (map && t < nmap && map[t].type)
@ -934,47 +939,71 @@ ikev1_attrmap_print(netdissect_options *ndo,
ND_PRINT((ndo,"type=#%d ", t));
if (p[0] & 0x80) {
ND_PRINT((ndo,"value="));
ND_TCHECK_16BITS(&p[2]);
v = EXTRACT_16BITS(&p[2]);
if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
ND_PRINT((ndo,"%s", map[t].value[v]));
else
rawprint(ndo, (const uint8_t *)&p[2], 2);
else {
if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
ND_PRINT((ndo,")"));
goto trunc;
}
}
} else {
ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
ND_PRINT((ndo,"len=%d value=", totlen - 4));
if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
ND_PRINT((ndo,")"));
goto trunc;
}
}
ND_PRINT((ndo,")"));
return p + totlen;
trunc:
return NULL;
}
static const u_char *
ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep2)
{
int totlen;
uint32_t t;
ND_TCHECK(p[0]);
if (p[0] & 0x80)
totlen = 4;
else
else {
ND_TCHECK_16BITS(&p[2]);
totlen = 4 + EXTRACT_16BITS(&p[2]);
if (ep < p + totlen) {
}
if (ep2 < p + totlen) {
ND_PRINT((ndo,"[|attr]"));
return ep + 1;
return ep2 + 1;
}
ND_TCHECK_16BITS(&p[0]);
ND_PRINT((ndo,"("));
t = EXTRACT_16BITS(&p[0]) & 0x7fff;
ND_PRINT((ndo,"type=#%d ", t));
if (p[0] & 0x80) {
ND_PRINT((ndo,"value="));
t = p[2];
rawprint(ndo, (const uint8_t *)&p[2], 2);
if (!rawprint(ndo, (const uint8_t *)&p[2], 2)) {
ND_PRINT((ndo,")"));
goto trunc;
}
} else {
ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
ND_PRINT((ndo,"len=%d value=", totlen - 4));
if (!rawprint(ndo, (const uint8_t *)&p[4], totlen - 4)) {
ND_PRINT((ndo,")"));
goto trunc;
}
}
ND_PRINT((ndo,")"));
return p + totlen;
trunc:
return NULL;
}
static const u_char *
@ -1255,11 +1284,12 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
cp = (const u_char *)(p + 1);
ep2 = (const u_char *)p + item_len;
while (cp < ep && cp < ep2) {
if (map && nmap) {
cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
map, nmap);
} else
cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
if (map && nmap)
cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
else
cp = ikev1_attr_print(ndo, cp, ep2);
if (cp == NULL)
goto trunc;
}
if (ep < ep2)
ND_PRINT((ndo,"..."));
@ -1283,6 +1313,7 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@ -1346,16 +1377,15 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
{
const struct ipsecdoi_id *doi_p;
struct ipsecdoi_id doi_id;
struct protoent *pe;
const char *p_name;
doi_p = (const struct ipsecdoi_id *)ext;
ND_TCHECK(*doi_p);
UNALIGNED_MEMCPY(&doi_id, ext, sizeof(doi_id));
ND_PRINT((ndo," idtype=%s", STR_OR_ID(doi_id.type, ipsecidtypestr)));
/* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */
pe = doi_id.proto_id ? getprotobynumber(doi_id.proto_id) : NULL;
if (pe)
ND_PRINT((ndo," protoid=%s", pe->p_name));
if (!ndo->ndo_nflag && doi_id.proto_id && (p_name = netdb_protoname(doi_id.proto_id)) != NULL)
ND_PRINT((ndo," protoid=%s", p_name));
else
ND_PRINT((ndo," protoid=%u", doi_id.proto_id));
ND_PRINT((ndo," port=%d", ntohs(doi_id.port)));
@ -1406,8 +1436,8 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
case IPSECDOI_ID_IPV6_ADDR_SUBNET:
{
const u_char *mask;
if (len < 20)
ND_PRINT((ndo," len=%d [bad: < 20]", len));
if (len < 32)
ND_PRINT((ndo," len=%d [bad: < 32]", len));
else {
mask = (const u_char *)(data + sizeof(struct in6_addr));
/*XXX*/
@ -1486,6 +1516,7 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
ND_PRINT((ndo," len=%d", item_len - 4));
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
if (2 < ndo->ndo_vflag && 4 < item_len) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
goto trunc;
@ -1518,6 +1549,7 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
ND_PRINT((ndo," len=%d", item_len - 4));
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
if (2 < ndo->ndo_vflag && 4 < item_len) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
goto trunc;
@ -1542,6 +1574,7 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@ -1566,6 +1599,7 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@ -1590,15 +1624,20 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
ND_TCHECK(*ext);
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
} else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
ND_PRINT((ndo," "));
if (!ike_show_somedata(ndo, (const u_char *)(const uint8_t *)(ext + 1), ep))
goto trunc;
/*
* Our caller has ensured that the length is >= 4.
*/
ND_PRINT((ndo," n len=%u", ntohs(e.len) - 4));
if (ntohs(e.len) > 4) {
if (ndo->ndo_vflag > 2) {
ND_PRINT((ndo, " "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
} else if (ndo->ndo_vflag > 1) {
ND_PRINT((ndo, " "));
if (!ike_show_somedata(ndo, (const u_char *)(ext + 1), ep))
goto trunc;
}
}
return (const u_char *)ext + ntohs(e.len);
trunc:
@ -1609,8 +1648,8 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
static const u_char *
ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
const struct isakmp_gen *ext, u_int item_len,
const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
uint32_t proto0 _U_, int depth)
const u_char *ep, uint32_t phase _U_, uint32_t doi0 _U_,
uint32_t proto0 _U_, int depth _U_)
{
const struct ikev1_pl_n *p;
struct ikev1_pl_n n;
@ -1712,35 +1751,44 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
ep2 = (const u_char *)p + item_len;
if (cp < ep) {
ND_PRINT((ndo," orig=("));
switch (ntohs(n.type)) {
case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
{
const struct attrmap *map = oakley_t_map;
size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
ND_PRINT((ndo," attrs=("));
while (cp < ep && cp < ep2) {
cp = ikev1_attrmap_print(ndo, cp,
(ep < ep2) ? ep : ep2, map, nmap);
cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
if (cp == NULL) {
ND_PRINT((ndo,")"));
goto trunc;
}
}
ND_PRINT((ndo,")"));
break;
}
case IPSECDOI_NTYPE_REPLAY_STATUS:
ND_PRINT((ndo," status=("));
ND_PRINT((ndo,"replay detection %sabled",
EXTRACT_32BITS(cp) ? "en" : "dis"));
break;
case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
(const struct isakmp_gen *)cp, ep, phase, doi, proto,
depth) == NULL)
return NULL;
ND_PRINT((ndo,")"));
break;
default:
/* NULL is dummy */
isakmp_print(ndo, cp,
item_len - sizeof(*p) - n.spi_size,
NULL);
/*
* XXX - fill in more types here; see, for example,
* draft-ietf-ipsec-notifymsg-04.
*/
if (ndo->ndo_vflag > 3) {
ND_PRINT((ndo," data=("));
if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
goto trunc;
ND_PRINT((ndo,")"));
} else {
if (!ike_show_somedata(ndo, cp, ep))
goto trunc;
}
break;
}
ND_PRINT((ndo,")"));
}
return (const u_char *)ext + item_len;
trunc:
@ -1807,6 +1855,7 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@ -1841,6 +1890,7 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay,
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@ -1915,10 +1965,11 @@ ikev2_t_print(netdissect_options *ndo, int tcount,
ep2 = (const u_char *)p + item_len;
while (cp < ep && cp < ep2) {
if (map && nmap) {
cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
map, nmap);
cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
} else
cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
cp = ikev1_attr_print(ndo, cp, ep2);
if (cp == NULL)
goto trunc;
}
if (ep < ep2)
ND_PRINT((ndo,"..."));
@ -1978,7 +2029,6 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
if (prop_length < sizeof(*ext))
goto toolong;
ND_TCHECK(*ext);
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
/*
@ -2065,7 +2115,6 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
if (sa_length < sizeof(*ext))
goto toolong;
ND_TCHECK(*ext);
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
/*
@ -2126,7 +2175,7 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay,
const struct ikev2_ke *k;
k = (const struct ikev2_ke *)ext;
ND_TCHECK(*ext);
ND_TCHECK(*k);
UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
@ -2151,12 +2200,14 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
uint32_t phase _U_, uint32_t doi _U_,
uint32_t proto _U_, int depth _U_)
{
const struct ikev2_id *idp;
struct ikev2_id id;
int id_len, idtype_len, i;
unsigned int dumpascii, dumphex;
const unsigned char *typedata;
ND_TCHECK(*ext);
idp = (const struct ikev2_id *)ext;
ND_TCHECK(*idp);
UNALIGNED_MEMCPY(&id, ext, sizeof(id));
ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
@ -2164,6 +2215,7 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
ND_PRINT((ndo," len=%d", id_len - 4));
if (2 < ndo->ndo_vflag && 4 < id_len) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4))
goto trunc;
@ -2259,21 +2311,26 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay,
const u_char *authdata = (const u_char*)ext + sizeof(a);
unsigned int len;
ND_TCHECK(*ext);
ND_TCHECK2(*ext, sizeof(a));
UNALIGNED_MEMCPY(&a, ext, sizeof(a));
ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
len = ntohs(a.h.len);
ND_PRINT((ndo," len=%d method=%s", len-4,
/*
* Our caller has ensured that the length is >= 4.
*/
ND_PRINT((ndo," len=%u method=%s", len-4,
STR_OR_ID(a.auth_method, v2_auth)));
if (1 < ndo->ndo_vflag && 4 < len) {
ND_PRINT((ndo," authdata=("));
if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
goto trunc;
ND_PRINT((ndo,") "));
} else if(ndo->ndo_vflag && 4 < len) {
if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
if (len > 4) {
if (ndo->ndo_vflag > 1) {
ND_PRINT((ndo, " authdata=("));
if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
goto trunc;
ND_PRINT((ndo, ") "));
} else if (ndo->ndo_vflag) {
if (!ike_show_somedata(ndo, authdata, ep))
goto trunc;
}
}
return (const u_char *)ext + len;
@ -2322,7 +2379,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
const struct ikev2_n *p;
struct ikev2_n n;
const u_char *cp;
u_char showspi, showdata, showsomedata;
u_char showspi, showsomedata;
const char *notify_name;
uint32_t type;
@ -2332,7 +2389,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
showspi = 1;
showdata = 0;
showsomedata=0;
notify_name=NULL;
@ -2446,7 +2502,6 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
notify_name = "cookie";
showspi = 1;
showsomedata= 1;
showdata= 0;
break;
case IV2_NOTIFY_USE_TRANSPORT_MODE:
@ -2499,19 +2554,17 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
cp = (const u_char *)(p + 1) + n.spi_size;
if(3 < ndo->ndo_vflag) {
showdata = 1;
}
if (cp < ep) {
if (ndo->ndo_vflag > 3 || (showsomedata && ep-cp < 30)) {
ND_PRINT((ndo," data=("));
if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
goto trunc;
if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
ND_PRINT((ndo," data=("));
if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
goto trunc;
ND_PRINT((ndo,")"));
} else if(showsomedata && cp < ep) {
if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
ND_PRINT((ndo,")"));
} else if (showsomedata) {
if (!ike_show_somedata(ndo, cp, ep))
goto trunc;
}
}
return (const u_char *)ext + item_len;
@ -2554,6 +2607,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay,
else ND_PRINT((ndo, "."));
}
if (2 < ndo->ndo_vflag && 4 < len) {
/* Print the entire payload in hex */
ND_PRINT((ndo," "));
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
goto trunc;
@ -2719,7 +2773,6 @@ ikev1_sub_print(netdissect_options *ndo,
while (np) {
ND_TCHECK(*ext);
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_TCHECK2(*ext, ntohs(e.len));
@ -2887,7 +2940,6 @@ ikev2_sub_print(netdissect_options *ndo,
cp = (const u_char *)ext;
while (np) {
ND_TCHECK(*ext);
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
ND_TCHECK2(*ext, ntohs(e.len));
@ -3041,7 +3093,7 @@ isakmp_rfc3948_print(netdissect_options *ndo,
const u_char *bp, u_int length,
const u_char *bp2)
{
ND_TCHECK(bp[0]);
if(length == 1 && bp[0]==0xff) {
ND_PRINT((ndo, "isakmp-nat-keep-alive"));
return;
@ -3050,6 +3102,7 @@ isakmp_rfc3948_print(netdissect_options *ndo,
if(length < 4) {
goto trunc;
}
ND_TCHECK(bp[3]);
/*
* see if this is an IKE packet
@ -3090,7 +3143,3 @@ isakmp_rfc3948_print(netdissect_options *ndo,
* c-basic-offset: 8
* End:
*/

View File

@ -20,7 +20,7 @@
*
* Original code by Matt Thomas, Digital Equipment Corporation
*
* Extensively modified by Hannes Gredler (hannes@juniper.net) for more
* Extensively modified by Hannes Gredler (hannes@gredler.at) for more
* complete IS-IS & CLNP support.
*/
@ -564,8 +564,8 @@ struct isis_tlv_ptp_adj {
uint8_t neighbor_extd_local_circuit_id[4];
};
static int osi_print_cksum(netdissect_options *, const uint8_t *pptr,
uint16_t checksum, int checksum_offset, int length);
static void osi_print_cksum(netdissect_options *, const uint8_t *pptr,
uint16_t checksum, int checksum_offset, u_int length);
static int clnp_print(netdissect_options *, const uint8_t *, u_int);
static void esis_print(netdissect_options *, const uint8_t *, u_int);
static int isis_print(netdissect_options *, const uint8_t *, u_int);
@ -670,10 +670,9 @@ struct isis_tlv_lsp {
#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
void
isoclns_print(netdissect_options *ndo,
const uint8_t *p, u_int length, u_int caplen)
isoclns_print(netdissect_options *ndo, const uint8_t *p, u_int length)
{
if (caplen <= 1) { /* enough bytes on the wire ? */
if (!ND_TTEST(*p)) { /* enough bytes on the wire ? */
ND_PRINT((ndo, "|OSI"));
return;
}
@ -685,7 +684,7 @@ isoclns_print(netdissect_options *ndo,
case NLPID_CLNP:
if (!clnp_print(ndo, p, length))
print_unknown_data(ndo, p, "\n\t", caplen);
print_unknown_data(ndo, p, "\n\t", length);
break;
case NLPID_ESIS:
@ -694,7 +693,7 @@ isoclns_print(netdissect_options *ndo,
case NLPID_ISIS:
if (!isis_print(ndo, p, length))
print_unknown_data(ndo, p, "\n\t", caplen);
print_unknown_data(ndo, p, "\n\t", length);
break;
case NLPID_NULLNS:
@ -721,8 +720,8 @@ isoclns_print(netdissect_options *ndo,
if (!ndo->ndo_eflag)
ND_PRINT((ndo, "OSI NLPID 0x%02x unknown", *p));
ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length));
if (caplen > 1)
print_unknown_data(ndo, p, "\n\t", caplen);
if (length > 1)
print_unknown_data(ndo, p, "\n\t", length);
break;
}
}
@ -865,9 +864,8 @@ clnp_print(netdissect_options *ndo,
EXTRACT_16BITS(clnp_header->segment_length),
EXTRACT_16BITS(clnp_header->cksum)));
if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
clnp_header->length_indicator) == 0)
goto trunc;
osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
clnp_header->length_indicator);
ND_PRINT((ndo, "\n\tFlags [%s]",
bittok2str(clnp_flag_values, "none", clnp_flags)));
@ -1153,8 +1151,7 @@ esis_print(netdissect_options *ndo,
ND_PRINT((ndo, ", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ));
ND_PRINT((ndo, ", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum)));
if (osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li) == 0)
goto trunc;
osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li);
ND_PRINT((ndo, ", holding time: %us, length indicator: %u",
EXTRACT_16BITS(esis_header->holdtime), li));
@ -1220,10 +1217,18 @@ esis_print(netdissect_options *ndo,
pptr += netal;
li -= netal;
if (netal == 0)
ND_PRINT((ndo, "\n\t %s", etheraddr_string(ndo, snpa)));
if (snpal == 6)
ND_PRINT((ndo, "\n\t SNPA (length: %u): %s",
snpal,
etheraddr_string(ndo, snpa)));
else
ND_PRINT((ndo, "\n\t %s", isonsap_string(ndo, neta, netal)));
ND_PRINT((ndo, "\n\t SNPA (length: %u): %s",
snpal,
linkaddr_string(ndo, snpa, LINKADDR_OTHER, snpal)));
if (netal != 0)
ND_PRINT((ndo, "\n\t NET (length: %u) %s",
netal,
isonsap_string(ndo, neta, netal)));
break;
}
@ -1329,7 +1334,7 @@ esis_print(netdissect_options *ndo,
case ESIS_OPTION_PROTOCOLS:
while (opli>0) {
ND_TCHECK(*pptr);
ND_TCHECK(*tptr);
ND_PRINT((ndo, "%s (0x%02x)",
tok2str(nlpid_values,
"unknown",
@ -1362,7 +1367,7 @@ esis_print(netdissect_options *ndo,
pptr += opli;
}
trunc:
return;
ND_PRINT((ndo, "[|esis]"));
}
static void
@ -1398,6 +1403,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
while (len > 2)
{
ND_TCHECK2(*tptr, 2);
stlv_type = *(tptr++);
stlv_len = *(tptr++);
@ -1410,11 +1416,18 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
/*len -= TLV_TYPE_LEN_OFFSET;*/
len = len -2;
/* Make sure the subTLV fits within the space left */
if (len < stlv_len)
goto trunc;
/* Make sure the entire subTLV is in the captured data */
ND_TCHECK2(*(tptr), stlv_len);
switch (stlv_type)
{
case ISIS_SUBTLV_SPB_MCID:
{
ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN);
if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN)
goto trunc;
subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr;
@ -1429,15 +1442,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
/*tptr += SPB_MCID_MIN_LEN;
len -= SPB_MCID_MIN_LEN; */
tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
len = len - sizeof(struct isis_subtlv_spb_mcid);
tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN;
len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
break;
}
case ISIS_SUBTLV_SPB_DIGEST:
{
ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN);
if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)
goto trunc;
ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d",
(*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
@ -1456,18 +1471,15 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
}
len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
break;
}
case ISIS_SUBTLV_SPB_BVID:
{
ND_TCHECK2(*(tptr), stlv_len);
while (len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
{
ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN);
ND_PRINT((ndo, "\n\t ECT: %08x",
EXTRACT_32BITS(tptr)));
@ -1480,14 +1492,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
tptr = tptr + 2;
len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
}
break;
}
default:
break;
break;
}
tptr += stlv_len;
len -= stlv_len;
}
return 0;
@ -1506,6 +1521,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
while (len > 2)
{
ND_TCHECK2(*tptr, 2);
stlv_type = *(tptr++);
stlv_len = *(tptr++);
@ -1517,11 +1533,17 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
len = len - 2;
/* Make sure the subTLV fits within the space left */
if (len < stlv_len)
goto trunc;
/* Make sure the entire subTLV is in the captured data */
ND_TCHECK2(*(tptr), stlv_len);
switch (stlv_type)
{
case ISIS_SUBTLV_SPB_INSTANCE:
ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN);
if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)
goto trunc;
ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr)));
tptr = tptr+4;
@ -1543,10 +1565,12 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
tmp = *(tptr++);
len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
while (tmp)
{
ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN);
if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)
goto trunc;
ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d",
*(tptr) >> 7, (*(tptr) >> 6) & 0x01,
@ -1564,14 +1588,15 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
tptr = tptr + 3;
len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
tmp--;
}
break;
case ISIS_SUBTLV_SPBM_SI:
ND_TCHECK2(*tptr, 8);
if (stlv_len < 8)
goto trunc;
ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr)));
tptr = tptr+4;
@ -1603,6 +1628,8 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
default:
break;
}
tptr += stlv_len;
len -= stlv_len;
}
return 0;
@ -1619,8 +1646,12 @@ isis_print_id(const uint8_t *cp, int id_len)
int i;
static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
char *pos = id;
int sysid_len;
for (i = 1; i <= SYSTEM_ID_LEN; i++) {
sysid_len = SYSTEM_ID_LEN;
if (sysid_len > id_len)
sysid_len = id_len;
for (i = 1; i <= sysid_len; i++) {
snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++);
pos += strlen(pos);
if (i == 2 || i == 4)
@ -1830,6 +1861,8 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
break;
case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */
case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD:
if (subl == 0)
break;
ND_PRINT((ndo, "%sBandwidth Constraints Model ID: %s (%u)",
ident,
tok2str(diffserv_te_bc_values, "unknown", *tptr),
@ -1837,7 +1870,6 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
tptr++;
/* decode BCs until the subTLV ends */
for (te_class = 0; te_class < (subl-1)/4; te_class++) {
ND_TCHECK2(*tptr, 4);
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Bandwidth constraint CT%u: %.3f Mbps",
ident,
@ -1899,13 +1931,15 @@ isis_print_is_reach_subtlv(netdissect_options *ndo,
case GMPLS_PSC2:
case GMPLS_PSC3:
case GMPLS_PSC4:
ND_TCHECK2(*tptr, 6);
if (subl < 6)
break;
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
ND_PRINT((ndo, "%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr + 4)));
break;
case GMPLS_TSC:
ND_TCHECK2(*tptr, 8);
if (subl < 8)
break;
bw.i = EXTRACT_32BITS(tptr);
ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
ND_PRINT((ndo, "%s Indication %s", ident,
@ -2041,7 +2075,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo,
}
processed++;
} else if (afi == AF_INET6) {
if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
if (!ND_TTEST2(*tptr, 2)) /* fetch status & prefix_len byte */
return (0);
status_byte=*(tptr++);
bit_length=*(tptr++);
@ -2164,6 +2198,8 @@ isis_print(netdissect_options *ndo,
TLV verification */
isis_header = (const struct isis_common_header *)p;
ND_TCHECK(*isis_header);
if (length < ISIS_COMMON_HEADER_SIZE)
goto trunc;
pptr = p+(ISIS_COMMON_HEADER_SIZE);
header_iih_lan = (const struct isis_iih_lan_header *)pptr;
header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
@ -2194,6 +2230,16 @@ isis_print(netdissect_options *ndo,
return (0);
}
if (length < isis_header->fixed_len) {
ND_PRINT((ndo, "fixed header length %u > packet length %u", isis_header->fixed_len, length));
return (0);
}
if (isis_header->fixed_len < ISIS_COMMON_HEADER_SIZE) {
ND_PRINT((ndo, "fixed header length %u < minimum header size %u", isis_header->fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE));
return (0);
}
max_area = isis_header->max_area;
switch(max_area) {
case 0:
@ -2236,254 +2282,255 @@ isis_print(netdissect_options *ndo,
pdu_type=isis_header->pdu_type;
/* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
if (ndo->ndo_vflag < 1) {
if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, "%s%s",
ndo->ndo_eflag ? "" : ", ",
tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type)));
} else {
/* ok they seem to want to know everything - lets fully decode it */
ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
switch (pdu_type) {
ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
tok2str(isis_pdu_values,
"unknown, type %u",
pdu_type),
isis_header->fixed_len,
isis_header->version,
isis_header->pdu_version,
id_length,
isis_header->id_length,
max_area,
isis_header->max_area));
case ISIS_PDU_L1_LAN_IIH:
case ISIS_PDU_L2_LAN_IIH:
ND_TCHECK(*header_iih_lan);
ND_PRINT((ndo, ", src-id %s",
isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
ND_PRINT((ndo, ", lan-id %s, prio %u",
isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
header_iih_lan->priority));
break;
case ISIS_PDU_PTP_IIH:
ND_TCHECK(*header_iih_ptp);
ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
break;
case ISIS_PDU_L1_LSP:
case ISIS_PDU_L2_LSP:
ND_TCHECK(*header_lsp);
ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
EXTRACT_32BITS(header_lsp->sequence_number),
EXTRACT_16BITS(header_lsp->remaining_lifetime)));
break;
case ISIS_PDU_L1_CSNP:
case ISIS_PDU_L2_CSNP:
ND_TCHECK(*header_csnp);
ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
break;
case ISIS_PDU_L1_PSNP:
case ISIS_PDU_L2_PSNP:
ND_TCHECK(*header_psnp);
ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
break;
}
ND_PRINT((ndo, ", length %u", length));
return(1);
}
/* ok they seem to want to know everything - lets fully decode it */
ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
tok2str(isis_pdu_values,
"unknown, type %u",
pdu_type),
isis_header->fixed_len,
isis_header->version,
isis_header->pdu_version,
id_length,
isis_header->id_length,
max_area,
isis_header->max_area));
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
return(0); /* for optionally debugging the common header */
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
return (0); /* for optionally debugging the common header */
}
}
switch (pdu_type) {
case ISIS_PDU_L1_LAN_IIH:
case ISIS_PDU_L2_LAN_IIH:
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE));
return (0);
}
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)));
return (0);
}
ND_TCHECK(*header_iih_lan);
if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)
goto trunc;
if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, ", src-id %s",
isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
ND_PRINT((ndo, ", lan-id %s, prio %u",
isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
header_iih_lan->priority));
ND_PRINT((ndo, ", length %u", length));
return (1);
}
pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
}
ND_TCHECK(*header_iih_lan);
pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
}
ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
EXTRACT_16BITS(header_iih_lan->holding_time),
tok2str(isis_iih_circuit_type_values,
"unknown circuit type 0x%02x",
header_iih_lan->circuit_type)));
ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
EXTRACT_16BITS(header_iih_lan->holding_time),
tok2str(isis_iih_circuit_type_values,
"unknown circuit type 0x%02x",
header_iih_lan->circuit_type)));
ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u",
isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
(header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
pdu_len));
ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u",
isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
(header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
pdu_len));
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
return (0);
}
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
return(0);
}
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
break;
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
break;
case ISIS_PDU_PTP_IIH:
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE));
return (0);
}
ND_TCHECK(*header_iih_ptp);
pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
if (packet_len>pdu_len) {
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)));
return (0);
}
ND_TCHECK(*header_iih_ptp);
if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)
goto trunc;
if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
ND_PRINT((ndo, ", length %u", length));
return (1);
}
pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
}
}
ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
EXTRACT_16BITS(header_iih_ptp->holding_time),
tok2str(isis_iih_circuit_type_values,
"unknown circuit type 0x%02x",
header_iih_ptp->circuit_type)));
ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
EXTRACT_16BITS(header_iih_ptp->holding_time),
tok2str(isis_iih_circuit_type_values,
"unknown circuit type 0x%02x",
header_iih_ptp->circuit_type)));
ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u",
header_iih_ptp->circuit_id,
pdu_len));
ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u",
header_iih_ptp->circuit_id,
pdu_len));
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
return(0);
}
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
return (0);
}
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
break;
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
break;
case ISIS_PDU_L1_LSP:
case ISIS_PDU_L2_LSP:
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
return (0);
}
ND_TCHECK(*header_lsp);
pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
if (packet_len>pdu_len) {
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
return (0);
}
ND_TCHECK(*header_lsp);
if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)
goto trunc;
if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
EXTRACT_32BITS(header_lsp->sequence_number),
EXTRACT_16BITS(header_lsp->remaining_lifetime)));
ND_PRINT((ndo, ", length %u", length));
return (1);
}
pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
}
}
ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
EXTRACT_32BITS(header_lsp->sequence_number),
EXTRACT_16BITS(header_lsp->remaining_lifetime),
EXTRACT_16BITS(header_lsp->checksum)));
if (osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
EXTRACT_16BITS(header_lsp->checksum),
12, length-12) == 0)
goto trunc;
osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
EXTRACT_16BITS(header_lsp->checksum),
12, length-12);
ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
pdu_len,
ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""));
if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
ND_PRINT((ndo, "ATT bit set, "));
}
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
ND_PRINT((ndo, "ATT bit set, "));
}
ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
return(0);
}
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
return (0);
}
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
break;
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
break;
case ISIS_PDU_L1_CSNP:
case ISIS_PDU_L2_CSNP:
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE));
return (0);
}
ND_TCHECK(*header_csnp);
pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
if (packet_len>pdu_len) {
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)));
return (0);
}
ND_TCHECK(*header_csnp);
if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)
goto trunc;
if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
ND_PRINT((ndo, ", length %u", length));
return (1);
}
pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
}
}
ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
isis_print_id(header_csnp->source_id, NODE_ID_LEN),
pdu_len));
ND_PRINT((ndo, "\n\t start lsp-id: %s",
ND_PRINT((ndo, "\n\t start lsp-id: %s",
isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)));
ND_PRINT((ndo, "\n\t end lsp-id: %s",
ND_PRINT((ndo, "\n\t end lsp-id: %s",
isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)));
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
return(0);
}
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
return (0);
}
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
break;
case ISIS_PDU_L1_PSNP:
case ISIS_PDU_L2_PSNP:
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE));
return (0);
}
ND_TCHECK(*header_psnp);
pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
if (packet_len>pdu_len) {
if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)));
return (0);
}
ND_TCHECK(*header_psnp);
if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)
goto trunc;
if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
ND_PRINT((ndo, ", length %u", length));
return (1);
}
pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
if (packet_len>pdu_len) {
packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
length=pdu_len;
}
}
ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
isis_print_id(header_psnp->source_id, NODE_ID_LEN),
pdu_len));
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
return(0);
}
if (ndo->ndo_vflag > 1) {
if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
return (0);
}
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
break;
packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
break;
default:
if (ndo->ndo_vflag == 0) {
ND_PRINT((ndo, ", length %u", length));
return (1);
}
(void)print_unknown_data(ndo, pptr, "\n\t ", length);
return (0);
}
@ -2492,20 +2539,15 @@ isis_print(netdissect_options *ndo,
* Now print the TLV's.
*/
while (packet_len >= 2) {
if (pptr == ndo->ndo_snapend) {
return (1);
}
while (packet_len > 0) {
ND_TCHECK2(*pptr, 2);
if (packet_len < 2)
goto trunc;
tlv_type = *pptr++;
tlv_len = *pptr++;
tmp =tlv_len; /* copy temporary len & pointer to packet data */
tptr = pptr;
packet_len -= 2;
if (tlv_len > packet_len) {
break;
}
/* first lets see if we know the TLVs name*/
ND_PRINT((ndo, "\n\t %s TLV #%u, length: %u",
@ -2518,12 +2560,16 @@ isis_print(netdissect_options *ndo,
if (tlv_len == 0) /* something is invalid */
continue;
if (packet_len < tlv_len)
goto trunc;
/* now check if we have a decoder otherwise do a hexdump at the end*/
switch (tlv_type) {
case ISIS_TLV_AREA_ADDR:
ND_TCHECK2(*tptr, 1);
alen = *tptr++;
while (tmp && alen < tmp) {
ND_TCHECK2(*tptr, alen);
ND_PRINT((ndo, "\n\t Area address (length: %u): %s",
alen,
isonsap_string(ndo, tptr, alen)));
@ -2906,9 +2952,8 @@ isis_print(netdissect_options *ndo,
* to avoid conflicts the checksum TLV is zeroed.
* see rfc3358 for details
*/
if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
length) == 0)
goto trunc;
osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
length);
break;
case ISIS_TLV_POI:
@ -3102,40 +3147,33 @@ isis_print(netdissect_options *ndo,
return(1);
}
static int
static void
osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr,
uint16_t checksum, int checksum_offset, int length)
uint16_t checksum, int checksum_offset, u_int length)
{
uint16_t calculated_checksum;
/* do not attempt to verify the checksum if it is zero,
* if the total length is nonsense,
* if the offset is nonsense,
* or the base pointer is not sane
*/
if (!checksum
|| length < 0
|| checksum_offset < 0
|| length > ndo->ndo_snaplen
|| checksum_offset > ndo->ndo_snaplen
|| checksum_offset > length) {
|| !ND_TTEST2(*(pptr + checksum_offset), 2)
|| (u_int)checksum_offset > length
|| !ND_TTEST2(*pptr, length)) {
ND_PRINT((ndo, " (unverified)"));
return 1;
} else {
#if 0
printf("\nosi_print_cksum: %p %u %u %u\n", pptr, checksum_offset, length, ndo->ndo_snaplen);
printf("\nosi_print_cksum: %p %u %u\n", pptr, checksum_offset, length);
#endif
ND_TCHECK2(*pptr, length);
calculated_checksum = create_osi_cksum(pptr, checksum_offset, length);
if (checksum == calculated_checksum) {
ND_PRINT((ndo, " (correct)"));
} else {
ND_PRINT((ndo, " (incorrect should be 0x%04x)", calculated_checksum));
}
return 1;
}
trunc:
return 0;
}
/*

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: DLT_JUNIPER_* printers */
@ -472,6 +472,7 @@ juniper_ggsn_print(netdissect_options *ndo,
p+=l2info.header_len;
gh = (struct juniper_ggsn_header *)&l2info.cookie;
ND_TCHECK(*gh);
if (ndo->ndo_eflag) {
ND_PRINT((ndo, "proto %s (%u), vlan %u: ",
tok2str(juniper_protocol_values,"Unknown",gh->proto),
@ -492,6 +493,10 @@ juniper_ggsn_print(netdissect_options *ndo,
}
return l2info.header_len;
trunc:
ND_PRINT((ndo, "[|juniper_services]"));
return l2info.header_len;
}
#endif
@ -519,6 +524,7 @@ juniper_es_print(netdissect_options *ndo,
p+=l2info.header_len;
ih = (const struct juniper_ipsec_header *)p;
ND_TCHECK(*ih);
switch (ih->type) {
case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
@ -564,6 +570,10 @@ juniper_es_print(netdissect_options *ndo,
ip_print(ndo, p, l2info.length);
return l2info.header_len;
trunc:
ND_PRINT((ndo, "[|juniper_services]"));
return l2info.header_len;
}
#endif
@ -588,6 +598,7 @@ juniper_monitor_print(netdissect_options *ndo,
p+=l2info.header_len;
mh = (const struct juniper_monitor_header *)p;
ND_TCHECK(*mh);
if (ndo->ndo_eflag)
ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ",
EXTRACT_32BITS(&mh->service_id),
@ -598,6 +609,10 @@ juniper_monitor_print(netdissect_options *ndo,
ip_heuristic_guess (ndo, p, l2info.length);
return l2info.header_len;
trunc:
ND_PRINT((ndo, "[|juniper_services]"));
return l2info.header_len;
}
#endif
@ -622,6 +637,7 @@ juniper_services_print(netdissect_options *ndo,
p+=l2info.header_len;
sh = (const struct juniper_services_header *)p;
ND_TCHECK(*sh);
if (ndo->ndo_eflag)
ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
sh->svc_id,
@ -633,6 +649,10 @@ juniper_services_print(netdissect_options *ndo,
ip_heuristic_guess (ndo, p, l2info.length);
return l2info.header_len;
trunc:
ND_PRINT((ndo, "[|juniper_services]"));
return l2info.header_len;
}
#endif
@ -740,6 +760,7 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
p+=l2info.header_len;
ND_TCHECK2(p[0], 2);
extracted_ethertype = EXTRACT_16BITS(p);
/* this DLT contains nothing but raw PPPoE frames,
* prepended with a type field*/
@ -752,6 +773,10 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype));
return l2info.header_len;
trunc:
ND_PRINT((ndo, "[|juniper_pppoe_atm]"));
return l2info.header_len;
}
#endif
@ -793,7 +818,7 @@ juniper_mlppp_print(netdissect_options *ndo,
mpls_print(ndo, p, l2info.length);
return l2info.header_len;
case JUNIPER_LSQ_L3_PROTO_ISO:
isoclns_print(ndo, p, l2info.length, l2info.caplen);
isoclns_print(ndo, p, l2info.length);
return l2info.header_len;
default:
break;
@ -848,7 +873,7 @@ juniper_mfr_print(netdissect_options *ndo,
mpls_print(ndo, p, l2info.length);
return l2info.header_len;
case JUNIPER_LSQ_L3_PROTO_ISO:
isoclns_print(ndo, p, l2info.length, l2info.caplen);
isoclns_print(ndo, p, l2info.length);
return l2info.header_len;
default:
break;
@ -861,13 +886,13 @@ juniper_mfr_print(netdissect_options *ndo,
ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle));
switch (l2info.proto) {
case (LLCSAP_ISONS<<8 | LLCSAP_ISONS):
isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
isoclns_print(ndo, p + 1, l2info.length - 1);
break;
case (LLC_UI<<8 | NLPID_Q933):
case (LLC_UI<<8 | NLPID_IP):
case (LLC_UI<<8 | NLPID_IP6):
/* pass IP{4,6} to the OSI layer for proper link-layer printing */
isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
isoclns_print(ndo, p - 1, l2info.length + 1);
break;
default:
ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
@ -896,13 +921,13 @@ juniper_mlfr_print(netdissect_options *ndo,
switch (l2info.proto) {
case (LLC_UI):
case (LLC_UI<<8):
isoclns_print(ndo, p, l2info.length, l2info.caplen);
isoclns_print(ndo, p, l2info.length);
break;
case (LLC_UI<<8 | NLPID_Q933):
case (LLC_UI<<8 | NLPID_IP):
case (LLC_UI<<8 | NLPID_IP6):
/* pass IP{4,6} to the OSI layer for proper link-layer printing */
isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
isoclns_print(ndo, p - 1, l2info.length + 1);
break;
default:
ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
@ -940,6 +965,7 @@ juniper_atm1_print(netdissect_options *ndo,
return l2info.header_len;
}
ND_TCHECK2(p[0], 3);
if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
@ -949,7 +975,7 @@ juniper_atm1_print(netdissect_options *ndo,
}
if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
isoclns_print(ndo, p + 1, l2info.length - 1);
/* FIXME check if frame was recognized */
return l2info.header_len;
}
@ -958,6 +984,10 @@ juniper_atm1_print(netdissect_options *ndo,
return l2info.header_len;
return l2info.header_len;
trunc:
ND_PRINT((ndo, "[|juniper_atm1]"));
return l2info.header_len;
}
#endif
@ -989,6 +1019,7 @@ juniper_atm2_print(netdissect_options *ndo,
return l2info.header_len;
}
ND_TCHECK2(p[0], 3);
if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
@ -1004,7 +1035,7 @@ juniper_atm2_print(netdissect_options *ndo,
}
if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
isoclns_print(ndo, p + 1, l2info.length - 1);
/* FIXME check if frame was recognized */
return l2info.header_len;
}
@ -1016,6 +1047,10 @@ juniper_atm2_print(netdissect_options *ndo,
return l2info.header_len;
return l2info.header_len;
trunc:
ND_PRINT((ndo, "[|juniper_atm2]"));
return l2info.header_len;
}
#endif
@ -1280,6 +1315,7 @@ juniper_parse_header(netdissect_options *ndo,
l2info->caplen -= l2info->header_len;
/* search through the cookie table and copy values matching for our PIC type */
ND_TCHECK(p[0]);
while (lp->s != NULL) {
if (lp->pictype == l2info->pictype) {
@ -1331,6 +1367,7 @@ juniper_parse_header(netdissect_options *ndo,
if (ndo->ndo_eflag) ND_PRINT((ndo, ": ")); /* print demarc b/w L2/L3*/
ND_TCHECK_16BITS(p+l2info->cookie_len);
l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len);
break;
}
@ -1360,6 +1397,7 @@ juniper_parse_header(netdissect_options *ndo,
case DLT_JUNIPER_MLFR:
switch (l2info->cookie_type) {
case LS_COOKIE_ID:
ND_TCHECK2(p[0], 2);
l2info->bundle = l2info->cookie[1];
l2info->proto = EXTRACT_16BITS(p);
l2info->header_len += 2;
@ -1383,6 +1421,7 @@ juniper_parse_header(netdissect_options *ndo,
case DLT_JUNIPER_MFR:
switch (l2info->cookie_type) {
case LS_COOKIE_ID:
ND_TCHECK2(p[0], 2);
l2info->bundle = l2info->cookie[1];
l2info->proto = EXTRACT_16BITS(p);
l2info->header_len += 2;

View File

@ -297,10 +297,14 @@ print_32bits_val(netdissect_options *ndo, const uint32_t *dat)
/* AVP-specific print out routines */
/***********************************/
static void
l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat)
l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
EXTRACT_16BITS(ptr))));
}
@ -310,28 +314,53 @@ l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); ptr++; /* Result Code */
if (length > 2) { /* Error Code (opt) */
ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr))); ptr++;
/* Result Code */
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
if (length > 4) { /* Error Message (opt) */
ND_PRINT((ndo, " "));
print_string(ndo, (const u_char *)ptr, length - 4);
ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr)));
ptr++;
length -= 2;
/* Error Code (opt) */
if (length == 0)
return;
if (length < 2) {
ND_PRINT((ndo, " AVP too short"));
return;
}
ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr)));
ptr++;
length -= 2;
/* Error Message (opt) */
if (length == 0)
return;
ND_PRINT((ndo, " "));
print_string(ndo, (const u_char *)ptr, length);
}
static void
l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat)
l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length)
{
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ND_PRINT((ndo, "%u.%u", (EXTRACT_16BITS(dat) >> 8),
(EXTRACT_16BITS(dat) & 0xff)));
}
static void
l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat)
l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
@ -341,10 +370,14 @@ l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat)
}
static void
l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat)
l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
@ -356,19 +389,29 @@ l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat)
static void
l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
if (length < 3) {
ND_PRINT((ndo, "AVP too short"));
return;
}
print_16bits_val(ndo, (const uint16_t *)dat);
ND_PRINT((ndo, ", %02x", dat[2]));
if (length > 3) {
dat += 3;
length -= 3;
if (length != 0) {
ND_PRINT((ndo, " "));
print_string(ndo, dat+3, length-3);
print_string(ndo, dat, length);
}
}
static void
l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat)
l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
@ -378,10 +421,14 @@ l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat)
}
static void
l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat)
l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint32_t *ptr = (const uint32_t *)dat;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
@ -397,67 +444,117 @@ l2tp_packet_proc_delay_print(netdissect_options *ndo)
}
static void
l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat)
l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str,
"AuthType-#%u", EXTRACT_16BITS(ptr))));
}
static void
l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat)
l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK));
}
static void
l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat)
l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
uint16_t val_h, val_l;
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ptr++; /* skip "Reserved" */
length -= 2;
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l));
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l));
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l));
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l));
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l));
}
static void
l2tp_accm_print(netdissect_options *ndo, const u_char *dat)
l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
const uint16_t *ptr = (const uint16_t *)dat;
uint16_t val_h, val_l;
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ptr++; /* skip "Reserved" */
length -= 2;
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
val_h = EXTRACT_16BITS(ptr); ptr++;
val_l = EXTRACT_16BITS(ptr); ptr++;
ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l));
@ -468,14 +565,27 @@ l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int lengt
{
const uint16_t *ptr = (const uint16_t *)dat;
ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(ptr))); ptr++; /* Disconnect Code */
ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(ptr))); ptr++; /* Control Protocol Number */
if (length < 5) {
ND_PRINT((ndo, "AVP too short"));
return;
}
/* Disconnect Code */
ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(dat)));
dat += 2;
length -= 2;
/* Control Protocol Number */
ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(dat)));
dat += 2;
length -= 2;
/* Direction */
ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str,
"Direction-#%u", *((const u_char *)ptr++))));
"Direction-#%u", EXTRACT_8BITS(ptr))));
ptr++;
length--;
if (length > 5) {
if (length != 0) {
ND_PRINT((ndo, " "));
print_string(ndo, (const u_char *)ptr, length-5);
print_string(ndo, (const u_char *)ptr, length);
}
}
@ -508,7 +618,12 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
/* If it goes past the end of the remaining length of the captured
data, we'll give up. */
ND_TCHECK2(*ptr, len);
/* After this point, no need to worry about truncation */
/*
* After this point, we don't need to check whether we go past
* the length of the captured data; however, we *do* need to
* check whether we go past the end of the AVP.
*/
if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
ND_PRINT((ndo, "*"));
@ -537,27 +652,35 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
} else {
switch (attr_type) {
case L2TP_AVP_MSGTYPE:
l2tp_msgtype_print(ndo, (const u_char *)ptr);
l2tp_msgtype_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_RESULT_CODE:
l2tp_result_code_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PROTO_VER:
l2tp_proto_ver_print(ndo, ptr);
l2tp_proto_ver_print(ndo, ptr, len-6);
break;
case L2TP_AVP_FRAMING_CAP:
l2tp_framing_cap_print(ndo, (const u_char *)ptr);
l2tp_framing_cap_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_BEARER_CAP:
l2tp_bearer_cap_print(ndo, (const u_char *)ptr);
l2tp_bearer_cap_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_TIE_BREAKER:
if (len-6 < 8) {
ND_PRINT((ndo, "AVP too short"));
break;
}
print_octets(ndo, (const u_char *)ptr, 8);
break;
case L2TP_AVP_FIRM_VER:
case L2TP_AVP_ASSND_TUN_ID:
case L2TP_AVP_RECV_WIN_SIZE:
case L2TP_AVP_ASSND_SESS_ID:
if (len-6 < 2) {
ND_PRINT((ndo, "AVP too short"));
break;
}
print_16bits_val(ndo, ptr);
break;
case L2TP_AVP_HOST_NAME:
@ -582,6 +705,10 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_CHALLENGE_RESP:
if (len-6 < 16) {
ND_PRINT((ndo, "AVP too short"));
break;
}
print_octets(ndo, (const u_char *)ptr, 16);
break;
case L2TP_AVP_CALL_SER_NUM:
@ -590,28 +717,32 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
case L2TP_AVP_TX_CONN_SPEED:
case L2TP_AVP_PHY_CHANNEL_ID:
case L2TP_AVP_RX_CONN_SPEED:
if (len-6 < 4) {
ND_PRINT((ndo, "AVP too short"));
break;
}
print_32bits_val(ndo, (const uint32_t *)ptr);
break;
case L2TP_AVP_BEARER_TYPE:
l2tp_bearer_type_print(ndo, (const u_char *)ptr);
l2tp_bearer_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_FRAMING_TYPE:
l2tp_framing_type_print(ndo, (const u_char *)ptr);
l2tp_framing_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PACKET_PROC_DELAY:
l2tp_packet_proc_delay_print(ndo);
break;
case L2TP_AVP_PROXY_AUTH_TYPE:
l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr);
l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_PROXY_AUTH_ID:
l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr);
l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_CALL_ERRORS:
l2tp_call_errors_print(ndo, (const u_char *)ptr);
l2tp_call_errors_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_ACCM:
l2tp_accm_print(ndo, (const u_char *)ptr);
l2tp_accm_print(ndo, (const u_char *)ptr, len-6);
break;
case L2TP_AVP_SEQ_REQUIRED:
break; /* No Attribute Value */

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
* and Steinar Haug (sthaug@nethelp.no)
*/

View File

@ -324,7 +324,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
#endif
if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
&& control == LLC_UI) {
isoclns_print(ndo, p, length, caplen);
isoclns_print(ndo, p, length);
return (hdrlen);
}

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
* IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com>
* DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net>
*/
@ -590,6 +590,7 @@ static const struct tok lldp_evb_mode_values[]={
{ LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"},
{ LLDP_EVB_MODE_EVB_STATION, "EVB Staion"},
{ LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"},
{ 0, NULL},
};
#define NO_OF_BITS 8
@ -650,7 +651,7 @@ lldp_private_8021_print(netdissect_options *ndo,
int subtype, hexdump = FALSE;
u_int sublen;
u_int tval;
uint8_t i;
u_int i;
if (tlv_len < 4) {
return hexdump;
@ -786,9 +787,9 @@ lldp_private_8021_print(netdissect_options *ndo,
ND_PRINT((ndo, "\n\t Application Priority Table"));
while(i<sublen) {
tval=*(tptr+i+5);
ND_PRINT((ndo, "\n\t Priority: %d, RES: %d, Sel: %d",
tval >> 5, (tval >> 3) & 0x03, (tval & 0x07)));
ND_PRINT((ndo, "Protocol ID: %d", EXTRACT_16BITS(tptr + i + 5)));
ND_PRINT((ndo, "\n\t Priority: %u, RES: %u, Sel: %u, Protocol ID: %u",
tval >> 5, (tval >> 3) & 0x03, (tval & 0x07),
EXTRACT_16BITS(tptr + i + 5)));
i=i+3;
}
break;
@ -897,6 +898,9 @@ lldp_private_8023_print(netdissect_options *ndo,
break;
case LLDP_PRIVATE_8023_SUBTYPE_MTU:
if (tlv_len < 6) {
return hexdump;
}
ND_PRINT((ndo, "\n\t MTU size %u", EXTRACT_16BITS(tptr + 4)));
break;
@ -926,7 +930,7 @@ lldp_extract_latlon(const u_char *tptr)
* (right now there is only one)
*/
static int
lldp_private_iana_print(netdissect_options *ndo,
const u_char *tptr, u_int tlv_len)
@ -950,12 +954,12 @@ lldp_private_iana_print(netdissect_options *ndo,
default:
hexdump=TRUE;
}
return hexdump;
}
/*
* Print private TIA extensions.
*/
@ -1400,7 +1404,7 @@ lldp_mgmt_addr_tlv_print(netdissect_options *ndo,
if (tlen) {
oid_len = *tptr;
if (tlen < oid_len) {
if (tlen < 1U + oid_len) {
return 0;
}
if (oid_len) {

View File

@ -10,14 +10,15 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Support for LMP service discovery extensions (defined by UNI 1.0) added
* by Manu Pathak (mapathak@cisco.com), May 2005
* Original code by Hannes Gredler (hannes@gredler.at)
* Support for LMP service discovery extensions (defined by OIF UNI 1.0)
* added by Manu Pathak (mapathak@cisco.com), May 2005
*/
/* \summary: Link Management Protocol (LMP) printer */
/* specification: RFC 4204 */
/* OIF UNI 1.0: http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -353,6 +354,73 @@ static const struct tok lmp_ctype_values[] = {
{ 0, NULL}
};
static int
lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
int total_subobj_len, int offset)
{
int hexdump = FALSE;
int subobj_type, subobj_len;
union { /* int to float conversion buffer */
float f;
uint32_t i;
} bw;
while (total_subobj_len > 0 && hexdump == FALSE ) {
subobj_type = EXTRACT_8BITS(obj_tptr+offset);
subobj_len = EXTRACT_8BITS(obj_tptr+offset+1);
ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
tok2str(lmp_data_link_subobj,
"Unknown",
subobj_type),
subobj_type,
subobj_len));
if (subobj_len < 4) {
ND_PRINT((ndo, " (too short)"));
break;
}
if ((subobj_len % 4) != 0) {
ND_PRINT((ndo, " (not a multiple of 4)"));
break;
}
if (total_subobj_len < subobj_len) {
ND_PRINT((ndo, " (goes past the end of the object)"));
break;
}
switch(subobj_type) {
case INT_SWITCHING_TYPE_SUBOBJ:
ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
tok2str(gmpls_switch_cap_values,
"Unknown",
EXTRACT_8BITS(obj_tptr+offset+2)),
EXTRACT_8BITS(obj_tptr+offset+2)));
ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
tok2str(gmpls_encoding_values,
"Unknown",
EXTRACT_8BITS(obj_tptr+offset+3)),
EXTRACT_8BITS(obj_tptr+offset+3)));
bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
bw.f*8/1000000));
bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
bw.f*8/1000000));
break;
case WAVELENGTH_SUBOBJ:
ND_PRINT((ndo, "\n\t Wavelength: %u",
EXTRACT_32BITS(obj_tptr+offset+4)));
break;
default:
/* Any Unknown Subobject ==> Exit loop */
hexdump=TRUE;
break;
}
total_subobj_len-=subobj_len;
offset+=subobj_len;
}
return (hexdump);
}
void
lmp_print(netdissect_options *ndo,
register const u_char *pptr, register u_int len)
@ -360,10 +428,10 @@ lmp_print(netdissect_options *ndo,
const struct lmp_common_header *lmp_com_header;
const struct lmp_object_header *lmp_obj_header;
const u_char *tptr,*obj_tptr;
int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
int hexdump;
int offset,subobj_type,subobj_len,total_subobj_len;
int link_type;
u_int offset;
u_int link_type;
union { /* int to float conversion buffer */
float f;
@ -401,6 +469,14 @@ lmp_print(netdissect_options *ndo,
tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type),
bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags),
tlen));
if (tlen < sizeof(const struct lmp_common_header)) {
ND_PRINT((ndo, " (too short)"));
return;
}
if (tlen > len) {
ND_PRINT((ndo, " (too long)"));
tlen = len;
}
tptr+=sizeof(const struct lmp_common_header);
tlen-=sizeof(const struct lmp_common_header);
@ -413,9 +489,6 @@ lmp_print(netdissect_options *ndo,
lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length);
lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f;
if(lmp_obj_len % 4 || lmp_obj_len < 4)
return;
ND_PRINT((ndo, "\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
tok2str(lmp_obj_values,
"Unknown",
@ -428,6 +501,15 @@ lmp_print(netdissect_options *ndo,
(lmp_obj_header->ctype)&0x80 ? "" : "non-",
lmp_obj_len));
if (lmp_obj_len < 4) {
ND_PRINT((ndo, " (too short)"));
return;
}
if ((lmp_obj_len % 4) != 0) {
ND_PRINT((ndo, " (not a multiple of 4)"));
return;
}
obj_tptr=tptr+sizeof(struct lmp_object_header);
obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
@ -441,6 +523,10 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_LOC:
case LMP_CTYPE_RMT:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Control Channel ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@ -456,18 +542,30 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4_LOC:
case LMP_CTYPE_IPV4_RMT:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t IPv4 Link ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_IPV6_LOC:
case LMP_CTYPE_IPV6_RMT:
if (obj_tlen != 16) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t IPv6 Link ID: %s (0x%08x)",
ip6addr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_UNMD_LOC:
case LMP_CTYPE_UNMD_RMT:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Link ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@ -480,11 +578,19 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_MESSAGE_ID:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Message ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
break;
case LMP_CTYPE_2:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Message ID Ack: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@ -498,6 +604,10 @@ lmp_print(netdissect_options *ndo,
switch(lmp_obj_ctype) {
case LMP_CTYPE_LOC:
case LMP_CTYPE_RMT:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Node ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr),
EXTRACT_32BITS(obj_tptr)));
@ -511,6 +621,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CONFIG:
switch(lmp_obj_ctype) {
case LMP_CTYPE_HELLO_CONFIG:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Hello Interval: %u\n\t Hello Dead Interval: %u",
EXTRACT_16BITS(obj_tptr),
EXTRACT_16BITS(obj_tptr+2)));
@ -524,6 +638,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_HELLO:
switch(lmp_obj_ctype) {
case LMP_CTYPE_HELLO:
if (obj_tlen != 8) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Tx Seq: %u, Rx Seq: %u",
EXTRACT_32BITS(obj_tptr),
EXTRACT_32BITS(obj_tptr+4)));
@ -535,13 +653,17 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_OBJ_TE_LINK:
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_te_link_flag_values,
"none",
EXTRACT_16BITS(obj_tptr)>>8)));
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
if (obj_tlen != 12) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_te_link_flag_values,
"none",
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)"
"\n\t Remote Link-ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+4),
@ -551,21 +673,57 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_IPV6:
if (obj_tlen != 36) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_te_link_flag_values,
"none",
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)"
"\n\t Remote Link-ID: %s (0x%08x)",
ip6addr_string(ndo, obj_tptr+4),
EXTRACT_32BITS(obj_tptr+4),
ip6addr_string(ndo, obj_tptr+20),
EXTRACT_32BITS(obj_tptr+20)));
break;
case LMP_CTYPE_UNMD:
if (obj_tlen != 12) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_te_link_flag_values,
"none",
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Link-ID: %u (0x%08x)"
"\n\t Remote Link-ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr+4),
EXTRACT_32BITS(obj_tptr+4),
EXTRACT_32BITS(obj_tptr+8),
EXTRACT_32BITS(obj_tptr+8)));
break;
default:
hexdump=TRUE;
}
break;
case LMP_OBJ_DATA_LINK:
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_data_link_flag_values,
"none",
EXTRACT_16BITS(obj_tptr)>>8)));
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
case LMP_CTYPE_UNMD:
if (obj_tlen < 12) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_data_link_flag_values,
"none",
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)"
"\n\t Remote Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+4),
@ -573,51 +731,50 @@ lmp_print(netdissect_options *ndo,
ipaddr_string(ndo, obj_tptr+8),
EXTRACT_32BITS(obj_tptr+8)));
total_subobj_len = lmp_obj_len - 16;
offset = 12;
while (total_subobj_len > 0 && hexdump == FALSE ) {
subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8;
subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF;
ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
tok2str(lmp_data_link_subobj,
"Unknown",
subobj_type),
subobj_type,
subobj_len));
switch(subobj_type) {
case INT_SWITCHING_TYPE_SUBOBJ:
ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
tok2str(gmpls_switch_cap_values,
"Unknown",
EXTRACT_16BITS(obj_tptr+offset+2)>>8),
EXTRACT_16BITS(obj_tptr+offset+2)>>8));
ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
tok2str(gmpls_encoding_values,
"Unknown",
EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF),
EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF));
bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
bw.f*8/1000000));
bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
bw.f*8/1000000));
break;
case WAVELENGTH_SUBOBJ:
ND_PRINT((ndo, "\n\t Wavelength: %u",
EXTRACT_32BITS(obj_tptr+offset+4)));
break;
default:
/* Any Unknown Subobject ==> Exit loop */
hexdump=TRUE;
break;
}
total_subobj_len-=subobj_len;
offset+=subobj_len;
}
if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
hexdump=TRUE;
break;
case LMP_CTYPE_IPV6:
if (obj_tlen < 36) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_data_link_flag_values,
"none",
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)"
"\n\t Remote Interface ID: %s (0x%08x)",
ip6addr_string(ndo, obj_tptr+4),
EXTRACT_32BITS(obj_tptr+4),
ip6addr_string(ndo, obj_tptr+20),
EXTRACT_32BITS(obj_tptr+20)));
if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
hexdump=TRUE;
break;
case LMP_CTYPE_UNMD:
if (obj_tlen < 12) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: [%s]",
bittok2str(lmp_obj_data_link_flag_values,
"none",
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t Local Interface ID: %u (0x%08x)"
"\n\t Remote Interface ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr+4),
EXTRACT_32BITS(obj_tptr+4),
EXTRACT_32BITS(obj_tptr+8),
EXTRACT_32BITS(obj_tptr+8)));
if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
hexdump=TRUE;
break;
default:
hexdump=TRUE;
}
@ -626,6 +783,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_BEGIN:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
if (obj_tlen != 20) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: %s",
bittok2str(lmp_obj_begin_verify_flag_values,
"none",
@ -654,6 +815,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_BEGIN_ACK:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Verify Dead Interval: %u"
"\n\t Verify Transport Response: %u",
EXTRACT_16BITS(obj_tptr),
@ -668,6 +833,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_VERIFY_ID:
switch(lmp_obj_ctype) {
case LMP_CTYPE_1:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Verify ID: %u",
EXTRACT_32BITS(obj_tptr)));
break;
@ -680,19 +849,20 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CHANNEL_STATUS:
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
case LMP_CTYPE_UNMD:
offset = 0;
/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
while (offset+8 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
ND_PRINT((ndo, "\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
(EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
"Allocated" : "Non-allocated",
(EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
"Transmit" : "Receive",
(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
@ -704,7 +874,61 @@ lmp_print(netdissect_options *ndo,
offset+=8;
}
break;
case LMP_CTYPE_IPV6:
offset = 0;
/* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */
while (offset+20 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ip6addr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
(EXTRACT_32BITS(obj_tptr+offset+16)>>31) ?
"Allocated" : "Non-allocated",
(EXTRACT_32BITS(obj_tptr+offset+16)>>31)));
ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
(EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1 ?
"Transmit" : "Receive",
(EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1));
ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)",
tok2str(lmp_obj_channel_status_values,
"Unknown",
EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF),
EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF));
offset+=20;
}
break;
case LMP_CTYPE_UNMD:
offset = 0;
/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
while (offset+8 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
ND_PRINT((ndo, "\n\t\t Active: %s (%u)",
(EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
"Allocated" : "Non-allocated",
(EXTRACT_32BITS(obj_tptr+offset+4)>>31)));
ND_PRINT((ndo, "\n\t\t Direction: %s (%u)",
(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
"Transmit" : "Receive",
(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1));
ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)",
tok2str(lmp_obj_channel_status_values,
"Unknown",
EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF),
EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF));
offset+=8;
}
break;
default:
hexdump=TRUE;
}
@ -713,16 +937,35 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_CHANNEL_STATUS_REQ:
switch(lmp_obj_ctype) {
case LMP_CTYPE_IPV4:
case LMP_CTYPE_UNMD:
offset = 0;
while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
while (offset+4 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ipaddr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
offset+=4;
}
break;
case LMP_CTYPE_IPV6:
offset = 0;
while (offset+16 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)",
ip6addr_string(ndo, obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
offset+=16;
}
break;
case LMP_CTYPE_UNMD:
offset = 0;
while (offset+4 <= obj_tlen) {
ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)",
EXTRACT_32BITS(obj_tptr+offset),
EXTRACT_32BITS(obj_tptr+offset)));
offset+=4;
}
break;
default:
hexdump=TRUE;
}
@ -731,6 +974,10 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_ERROR_CODE:
switch(lmp_obj_ctype) {
case LMP_CTYPE_BEGIN_VERIFY_ERROR:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Error Code: %s",
bittok2str(lmp_obj_begin_verify_error_values,
"none",
@ -738,6 +985,10 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_LINK_SUMMARY_ERROR:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Error Code: %s",
bittok2str(lmp_obj_link_summary_error_values,
"none",
@ -751,51 +1002,60 @@ lmp_print(netdissect_options *ndo,
case LMP_OBJ_SERVICE_CONFIG:
switch (lmp_obj_ctype) {
case LMP_CTYPE_SERVICE_CONFIG_SP:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Flags: %s",
bittok2str(lmp_obj_service_config_sp_flag_values,
"none",
EXTRACT_16BITS(obj_tptr)>>8)));
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t UNI Version: %u",
EXTRACT_16BITS(obj_tptr) & 0x00FF));
EXTRACT_8BITS(obj_tptr+1)));
break;
case LMP_CTYPE_SERVICE_CONFIG_CPSA:
if (obj_tlen != 16) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
link_type = EXTRACT_16BITS(obj_tptr)>>8;
link_type = EXTRACT_8BITS(obj_tptr);
ND_PRINT((ndo, "\n\t Link Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_link_type_values,
"Unknown", link_type),
link_type));
if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) {
switch (link_type) {
case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH:
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
"Unknown",
EXTRACT_16BITS(obj_tptr) & 0x00FF),
EXTRACT_16BITS(obj_tptr) & 0x00FF));
}
EXTRACT_8BITS(obj_tptr+1)),
EXTRACT_8BITS(obj_tptr+1)));
break;
if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) {
case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
"Unknown",
EXTRACT_16BITS(obj_tptr) & 0x00FF),
EXTRACT_16BITS(obj_tptr) & 0x00FF));
EXTRACT_8BITS(obj_tptr+1)),
EXTRACT_8BITS(obj_tptr+1)));
break;
}
ND_PRINT((ndo, "\n\t Transparency: %s",
bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
"none",
EXTRACT_16BITS(obj_tptr+2)>>8)));
EXTRACT_8BITS(obj_tptr+2))));
ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s",
bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
"none",
EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF)));
EXTRACT_8BITS(obj_tptr+3))));
ND_PRINT((ndo, "\n\t Minimum NCC: %u",
EXTRACT_16BITS(obj_tptr+4)));
@ -816,6 +1076,10 @@ lmp_print(netdissect_options *ndo,
break;
case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
if (obj_tlen != 8) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Transparency Flags: %s",
bittok2str(
@ -827,17 +1091,21 @@ lmp_print(netdissect_options *ndo,
bittok2str(
lmp_obj_service_config_nsa_tcm_flag_values,
"none",
EXTRACT_16BITS(obj_tptr+6) & 0x00FF)));
EXTRACT_8BITS(obj_tptr+7))));
break;
case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
if (obj_tlen != 4) {
ND_PRINT((ndo, " (not correct for object)"));
break;
}
ND_PRINT((ndo, "\n\t Diversity: Flags: %s",
bittok2str(
lmp_obj_service_config_nsa_network_diversity_flag_values,
"none",
EXTRACT_16BITS(obj_tptr+2) & 0x00FF)));
EXTRACT_8BITS(obj_tptr+3))));
break;
default:

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: MPLS LSP PING printer */
@ -104,6 +104,7 @@ static const struct tok lspping_return_code_values[] = {
{ 11, "No label entry at stack-depth"},
{ 12, "Protocol not associated with interface at FEC stack depth"},
{ 13, "Premature termination of ping due to label stack shrinking to a single label"},
{ 0, NULL},
};

View File

@ -67,7 +67,7 @@ static const struct tok MessageClasses[] = {
{ M3UA_MSGC_SSNM, "SS7" },
{ M3UA_MSGC_ASPSM, "ASP" },
{ M3UA_MSGC_ASPTM, "ASP" },
{ M3UA_MSGC_RKM, "Routing Key Managment" },
{ M3UA_MSGC_RKM, "Routing Key Management"},
{ 0, NULL }
};

View File

@ -28,6 +28,7 @@
*/
/* \summary: IPv6 mobility printer */
/* RFC 3775 */
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -35,11 +36,12 @@
#include <netdissect-stdinc.h>
#include "ip6.h"
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
#include "ip6.h"
static const char tstr[] = "[|MOBILITY]";
/* Mobility header */
@ -148,6 +150,7 @@ mobility_opt_print(netdissect_options *ndo,
goto trunc;
}
/* units of 4 secs */
ND_TCHECK_16BITS(&bp[i+2]);
ND_PRINT((ndo, "(refresh: %u)",
EXTRACT_16BITS(&bp[i+2]) << 2));
break;
@ -156,6 +159,7 @@ mobility_opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "(altcoa: trunc)"));
goto trunc;
}
ND_TCHECK_128BITS(&bp[i+2]);
ND_PRINT((ndo, "(alt-CoA: %s)", ip6addr_string(ndo, &bp[i+2])));
break;
case IP6MOPT_NONCEID:
@ -163,6 +167,8 @@ mobility_opt_print(netdissect_options *ndo,
ND_PRINT((ndo, "(ni: trunc)"));
goto trunc;
}
ND_TCHECK_16BITS(&bp[i+2]);
ND_TCHECK_16BITS(&bp[i+4]);
ND_PRINT((ndo, "(ni: ho=0x%04x co=0x%04x)",
EXTRACT_16BITS(&bp[i+2]),
EXTRACT_16BITS(&bp[i+4])));
@ -241,7 +247,7 @@ mobility_print(netdissect_options *ndo,
case IP6M_CAREOF_TEST_INIT:
hlen = IP6M_MINLEN;
if (ndo->ndo_vflag) {
ND_TCHECK2(*mh, hlen + 8);
ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Init Cookie=%08x:%08x",
type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@ -255,7 +261,7 @@ mobility_print(netdissect_options *ndo,
ND_PRINT((ndo, " nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0])));
hlen = IP6M_MINLEN;
if (ndo->ndo_vflag) {
ND_TCHECK2(*mh, hlen + 8);
ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Init Cookie=%08x:%08x",
type == IP6M_HOME_TEST ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@ -263,7 +269,7 @@ mobility_print(netdissect_options *ndo,
}
hlen += 8;
if (ndo->ndo_vflag) {
ND_TCHECK2(*mh, hlen + 8);
ND_TCHECK_32BITS(&bp[hlen + 4]);
ND_PRINT((ndo, " %s Keygen Token=%08x:%08x",
type == IP6M_HOME_TEST ? "Home" : "Care-of",
EXTRACT_32BITS(&bp[hlen]),
@ -275,22 +281,23 @@ mobility_print(netdissect_options *ndo,
ND_TCHECK(mh->ip6m_data16[0]);
ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&mh->ip6m_data16[0])));
hlen = IP6M_MINLEN;
ND_TCHECK2(*mh, hlen + 1);
if (bp[hlen] & 0xf0)
ND_TCHECK_16BITS(&bp[hlen]);
if (bp[hlen] & 0xf0) {
ND_PRINT((ndo, " "));
if (bp[hlen] & 0x80)
ND_PRINT((ndo, "A"));
if (bp[hlen] & 0x40)
ND_PRINT((ndo, "H"));
if (bp[hlen] & 0x20)
ND_PRINT((ndo, "L"));
if (bp[hlen] & 0x10)
ND_PRINT((ndo, "K"));
if (bp[hlen] & 0x80)
ND_PRINT((ndo, "A"));
if (bp[hlen] & 0x40)
ND_PRINT((ndo, "H"));
if (bp[hlen] & 0x20)
ND_PRINT((ndo, "L"));
if (bp[hlen] & 0x10)
ND_PRINT((ndo, "K"));
}
/* Reserved (4bits) */
hlen += 1;
/* Reserved (8bits) */
hlen += 1;
ND_TCHECK2(*mh, hlen + 2);
ND_TCHECK_16BITS(&bp[hlen]);
/* units of 4 secs */
ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2));
hlen += 2;
@ -298,14 +305,15 @@ mobility_print(netdissect_options *ndo,
case IP6M_BINDING_ACK:
ND_TCHECK(mh->ip6m_data8[0]);
ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0]));
ND_TCHECK(mh->ip6m_data8[1]);
if (mh->ip6m_data8[1] & 0x80)
ND_PRINT((ndo, " K"));
/* Reserved (7bits) */
hlen = IP6M_MINLEN;
ND_TCHECK2(*mh, hlen + 2);
ND_TCHECK_16BITS(&bp[hlen]);
ND_PRINT((ndo, " seq#=%u", EXTRACT_16BITS(&bp[hlen])));
hlen += 2;
ND_TCHECK2(*mh, hlen + 2);
ND_TCHECK_16BITS(&bp[hlen]);
/* units of 4 secs */
ND_PRINT((ndo, " lifetime=%u", EXTRACT_16BITS(&bp[hlen]) << 2));
hlen += 2;
@ -315,7 +323,7 @@ mobility_print(netdissect_options *ndo,
ND_PRINT((ndo, " status=%u", mh->ip6m_data8[0]));
/* Reserved */
hlen = IP6M_MINLEN;
ND_TCHECK2(*mh, hlen + 16);
ND_TCHECK2(bp[hlen], 16);
ND_PRINT((ndo, " homeaddr %s", ip6addr_string(ndo, &bp[hlen])));
hlen += 16;
break;
@ -332,5 +340,5 @@ mobility_print(netdissect_options *ndo,
trunc:
ND_PRINT((ndo, "%s", tstr));
return(mhlen);
return(-1);
}

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE 802.3ah Multi-Point Control Protocol (MPCP) printer */

View File

@ -201,7 +201,7 @@ mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
break;
case PT_OSI:
isoclns_print(ndo, p, length, length);
isoclns_print(ndo, p, length);
break;
default:

View File

@ -178,7 +178,7 @@ mp_capable_print(netdissect_options *ndo,
{
const struct mp_capable *mpc = (const struct mp_capable *) opt;
if (!(opt_len == 12 && flags & TH_SYN) &&
if (!(opt_len == 12 && (flags & TH_SYN)) &&
!(opt_len == 20 && (flags & (TH_SYN | TH_ACK)) == TH_ACK))
return 0;
@ -202,9 +202,9 @@ mp_join_print(netdissect_options *ndo,
{
const struct mp_join *mpj = (const struct mp_join *) opt;
if (!(opt_len == 12 && flags & TH_SYN) &&
if (!(opt_len == 12 && (flags & TH_SYN)) &&
!(opt_len == 16 && (flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) &&
!(opt_len == 24 && flags & TH_ACK))
!(opt_len == 24 && (flags & TH_ACK)))
return 0;
if (opt_len != 24) {
@ -236,76 +236,92 @@ mp_join_print(netdissect_options *ndo,
return 1;
}
static u_int mp_dss_len(const struct mp_dss *m, int csum)
{
u_int len;
len = 4;
if (m->flags & MP_DSS_A) {
/* Ack present - 4 or 8 octets */
len += (m->flags & MP_DSS_a) ? 8 : 4;
}
if (m->flags & MP_DSS_M) {
/*
* Data Sequence Number (DSN), Subflow Sequence Number (SSN),
* Data-Level Length present, and Checksum possibly present.
* All but the Checksum are 10 bytes if the m flag is
* clear (4-byte DSN) and 14 bytes if the m flag is set
* (8-byte DSN).
*/
len += (m->flags & MP_DSS_m) ? 14 : 10;
/*
* The Checksum is present only if negotiated.
*/
if (csum)
len += 2;
}
return len;
}
static int
mp_dss_print(netdissect_options *ndo,
const u_char *opt, u_int opt_len, u_char flags)
{
const struct mp_dss *mdss = (const struct mp_dss *) opt;
if ((opt_len != mp_dss_len(mdss, 1) &&
opt_len != mp_dss_len(mdss, 0)) || flags & TH_SYN)
/* We need the flags, at a minimum. */
if (opt_len < 4)
return 0;
if (flags & TH_SYN)
return 0;
if (mdss->flags & MP_DSS_F)
ND_PRINT((ndo, " fin"));
opt += 4;
opt_len -= 4;
if (mdss->flags & MP_DSS_A) {
/* Ack present */
ND_PRINT((ndo, " ack "));
/*
* If the a flag is set, we have an 8-byte ack; if it's
* clear, we have a 4-byte ack.
*/
if (mdss->flags & MP_DSS_a) {
if (opt_len < 8)
return 0;
ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt)));
opt += 8;
opt_len -= 8;
} else {
if (opt_len < 4)
return 0;
ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt)));
opt += 4;
opt_len -= 4;
}
}
if (mdss->flags & MP_DSS_M) {
/*
* Data Sequence Number (DSN), Subflow Sequence Number (SSN),
* Data-Level Length present, and Checksum possibly present.
*/
ND_PRINT((ndo, " seq "));
/*
* If the m flag is set, we have an 8-byte NDS; if it's clear,
* we have a 4-byte DSN.
*/
if (mdss->flags & MP_DSS_m) {
if (opt_len < 8)
return 0;
ND_PRINT((ndo, "%" PRIu64, EXTRACT_64BITS(opt)));
opt += 8;
opt_len -= 8;
} else {
if (opt_len < 4)
return 0;
ND_PRINT((ndo, "%u", EXTRACT_32BITS(opt)));
opt += 4;
opt_len -= 4;
}
if (opt_len < 4)
return 0;
ND_PRINT((ndo, " subseq %u", EXTRACT_32BITS(opt)));
opt += 4;
opt_len -= 4;
if (opt_len < 2)
return 0;
ND_PRINT((ndo, " len %u", EXTRACT_16BITS(opt)));
opt += 2;
opt_len -= 2;
if (opt_len == mp_dss_len(mdss, 1))
/*
* The Checksum is present only if negotiated.
* If there are at least 2 bytes left, process the next 2
* bytes as the Checksum.
*/
if (opt_len >= 2) {
ND_PRINT((ndo, " csum 0x%x", EXTRACT_16BITS(opt)));
opt_len -= 2;
}
}
if (opt_len != 0)
return 0;
return 1;
}

View File

@ -628,17 +628,15 @@ nfsreq_print_noaddr(netdissect_options *ndo,
if ((dp = parsereq(ndo, rp, length)) != NULL &&
(dp = parsefh(ndo, dp, v3)) != NULL) {
if (v3) {
ND_TCHECK(dp[2]);
ND_TCHECK(dp[4]);
ND_PRINT((ndo, " %u (%u) bytes @ %" PRIu64,
EXTRACT_32BITS(&dp[4]),
EXTRACT_32BITS(&dp[2]),
EXTRACT_64BITS(&dp[0])));
if (ndo->ndo_vflag) {
dp += 3;
ND_TCHECK(dp[0]);
ND_PRINT((ndo, " <%s>",
tok2str(nfsv3_writemodes,
NULL, EXTRACT_32BITS(dp))));
NULL, EXTRACT_32BITS(&dp[3]))));
}
} else {
ND_TCHECK(dp[3]);
@ -809,11 +807,15 @@ nfs_printfh(netdissect_options *ndo,
if (sfsname) {
/* file system ID is ASCII, not numeric, for this server OS */
static char temp[NFSX_V3FHMAX+1];
char temp[NFSX_V3FHMAX+1];
u_int stringlen;
/* Make sure string is null-terminated */
strncpy(temp, sfsname, NFSX_V3FHMAX);
temp[sizeof(temp) - 1] = '\0';
stringlen = len;
if (stringlen > NFSX_V3FHMAX)
stringlen = NFSX_V3FHMAX;
strncpy(temp, sfsname, stringlen);
temp[stringlen] = '\0';
/* Remove trailing spaces */
spacep = strchr(temp, ' ');
if (spacep)
@ -868,7 +870,7 @@ xid_map_enter(netdissect_options *ndo,
const struct ip6_hdr *ip6 = NULL;
struct xid_map_entry *xmep;
if (!ND_TTEST(rp->rm_call.cb_vers))
if (!ND_TTEST(rp->rm_call.cb_proc))
return (0);
switch (IP_V((const struct ip *)bp)) {
case 4:
@ -1002,11 +1004,11 @@ parserep(netdissect_options *ndo,
* skip past the ar_verf credentials.
*/
dp += (len + (2*sizeof(uint32_t) + 3)) / sizeof(uint32_t);
ND_TCHECK2(dp[0], 0);
/*
* now we can check the ar_stat field
*/
ND_TCHECK(dp[0]);
astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp);
if (astat != SUNRPC_SUCCESS) {
ND_PRINT((ndo, " %s", tok2str(sunrpc_str, "ar_stat %d", astat)));
@ -1243,6 +1245,7 @@ static const uint32_t *
parse_wcc_attr(netdissect_options *ndo,
const uint32_t *dp)
{
/* Our caller has already checked this */
ND_PRINT((ndo, " sz %" PRIu64, EXTRACT_64BITS(&dp[0])));
ND_PRINT((ndo, " mtime %u.%06u ctime %u.%06u",
EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]),
@ -1511,8 +1514,10 @@ interp_reply(netdissect_options *ndo,
ND_PRINT((ndo, " attr:"));
if (!(dp = parse_post_op_attr(ndo, dp, ndo->ndo_vflag)))
break;
if (!er)
if (!er) {
ND_TCHECK(dp[0]);
ND_PRINT((ndo, " c %04x", EXTRACT_32BITS(&dp[0])));
}
return;
case NFSPROC_READLINK:

View File

@ -117,7 +117,7 @@ null_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
break;
case BSD_AFNUM_ISO:
isoclns_print(ndo, p, length, caplen);
isoclns_print(ndo, p, length);
break;
case BSD_AFNUM_APPLETALK:

View File

@ -13,7 +13,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler <hannes@juniper.net>
* Original code by Hannes Gredler <hannes@gredler.at>
* IPv6 additions by Florian Forster <octo at verplant.org>
*/
@ -359,10 +359,9 @@ olsr_print(netdissect_options *ndo,
} msgptr;
int msg_len_valid = 0;
ND_TCHECK2(*tptr, sizeof(struct olsr_msg4));
if (is_ipv6)
{
ND_TCHECK2(*tptr, sizeof(struct olsr_msg6));
msgptr.v6 = (const struct olsr_msg6 *) tptr;
msg_type = msgptr.v6->msg_type;
msg_len = EXTRACT_16BITS(msgptr.v6->msg_len);
@ -393,6 +392,7 @@ olsr_print(netdissect_options *ndo,
}
else /* (!is_ipv6) */
{
ND_TCHECK2(*tptr, sizeof(struct olsr_msg4));
msgptr.v4 = (const struct olsr_msg4 *) tptr;
msg_type = msgptr.v4->msg_type;
msg_len = EXTRACT_16BITS(msgptr.v4->msg_len);
@ -616,22 +616,25 @@ olsr_print(netdissect_options *ndo,
case OLSR_NAMESERVICE_MSG:
{
u_int name_entries = EXTRACT_16BITS(msg_data+2);
u_int addr_size = 4;
int name_entries_valid = 0;
u_int name_entries;
u_int addr_size;
int name_entries_valid;
u_int i;
if (is_ipv6)
addr_size = 16;
if ((name_entries > 0)
&& ((name_entries * (4 + addr_size)) <= msg_tlen))
name_entries_valid = 1;
if (msg_tlen < 4)
goto trunc;
ND_TCHECK2(*msg_data, 4);
name_entries = EXTRACT_16BITS(msg_data+2);
addr_size = 4;
if (is_ipv6)
addr_size = 16;
name_entries_valid = 0;
if ((name_entries > 0)
&& ((name_entries * (4 + addr_size)) <= msg_tlen))
name_entries_valid = 1;
ND_PRINT((ndo, "\n\t Version %u, Entries %u%s",
EXTRACT_16BITS(msg_data),
name_entries, (name_entries_valid == 0) ? " (invalid)" : ""));

View File

@ -648,6 +648,7 @@ ospf6_print_lsa(netdissect_options *ndo,
if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
return (1);
lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
ND_TCHECK(llsap->llsa_nprefix);
prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix);
ND_PRINT((ndo, "\n\t Priority %d, Link-local address %s, Prefixes %d:",
llsap->llsa_priority,
@ -735,6 +736,7 @@ ospf6_decode_v3(netdissect_options *ndo,
case OSPF_TYPE_HELLO: {
register const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
ND_TCHECK_32BITS(&hellop->hello_options);
ND_PRINT((ndo, "\n\tOptions [%s]",
bittok2str(ospf6_option_values, "none",
EXTRACT_32BITS(&hellop->hello_options))));
@ -933,10 +935,12 @@ ospf6_decode_v3_trailer(netdissect_options *ndo,
if (op->ospf6_type == OSPF_TYPE_HELLO) {
const struct hello6 *hellop = (const struct hello6 *)((const uint8_t *)op + OSPF6HDR_LEN);
ND_TCHECK(hellop->hello_options);
if (EXTRACT_32BITS(&hellop->hello_options) & OSPF6_OPTION_L)
lls_hello = 1;
} else if (op->ospf6_type == OSPF_TYPE_DD) {
const struct dd6 *ddp = (const struct dd6 *)((const uint8_t *)op + OSPF6HDR_LEN);
ND_TCHECK(ddp->db_options);
if (EXTRACT_32BITS(&ddp->db_options) & OSPF6_OPTION_L)
lls_dd = 1;
}

View File

@ -169,13 +169,12 @@ pgm_print(netdissect_options *ndo,
ND_PRINT((ndo, "%s > %s: [|pgm]",
ip6addr_string(ndo, &ip6->ip6_src),
ip6addr_string(ndo, &ip6->ip6_dst)));
return;
} else {
ND_PRINT((ndo, "%s > %s: [|pgm]",
ipaddr_string(ndo, &ip->ip_src),
ipaddr_string(ndo, &ip->ip_dst)));
return;
}
return;
}
sport = EXTRACT_16BITS(&pgm->pgm_sport);
@ -362,6 +361,7 @@ pgm_print(netdissect_options *ndo,
* and stopping if we don't have enough.
*/
bp += (2 * sizeof(uint16_t));
ND_TCHECK_16BITS(bp);
switch (EXTRACT_16BITS(bp)) {
case AFNUM_INET:
ND_TCHECK2(*bp, sizeof(struct in_addr));
@ -457,6 +457,10 @@ pgm_print(netdissect_options *ndo,
ND_PRINT((ndo, "[Total option length leaves no room for final option]"));
return;
}
if (!ND_TTEST2(*bp, 2)) {
ND_PRINT((ndo, " [|OPT]"));
return;
}
opt_type = *bp++;
opt_len = *bp++;
if (opt_len < PGM_MIN_OPT_LEN) {
@ -475,112 +479,130 @@ pgm_print(netdissect_options *ndo,
switch (opt_type & PGM_OPT_MASK) {
case PGM_OPT_LENGTH:
if (opt_len != 4) {
ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != 4]", opt_len));
#define PGM_OPT_LENGTH_LEN (2+2)
if (opt_len != PGM_OPT_LENGTH_LEN) {
ND_PRINT((ndo, "[Bad OPT_LENGTH option, length %u != %u]",
opt_len, PGM_OPT_LENGTH_LEN));
return;
}
ND_PRINT((ndo, " OPTS LEN (extra?) %d", EXTRACT_16BITS(bp)));
bp += sizeof(uint16_t);
opts_len -= 4;
bp += 2;
opts_len -= PGM_OPT_LENGTH_LEN;
break;
case PGM_OPT_FRAGMENT:
if (opt_len != 16) {
ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != 16]", opt_len));
#define PGM_OPT_FRAGMENT_LEN (2+2+4+4+4)
if (opt_len != PGM_OPT_FRAGMENT_LEN) {
ND_PRINT((ndo, "[Bad OPT_FRAGMENT option, length %u != %u]",
opt_len, PGM_OPT_FRAGMENT_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
offset = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
len = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
ND_PRINT((ndo, " FRAG seq %u off %u len %u", seq, offset, len));
opts_len -= 16;
opts_len -= PGM_OPT_FRAGMENT_LEN;
break;
case PGM_OPT_NAK_LIST:
bp += 2;
opt_len -= sizeof(uint32_t); /* option header */
opt_len -= 4; /* option header */
ND_PRINT((ndo, " NAK LIST"));
while (opt_len) {
if (opt_len < sizeof(uint32_t)) {
if (opt_len < 4) {
ND_PRINT((ndo, "[Option length not a multiple of 4]"));
return;
}
ND_TCHECK2(*bp, sizeof(uint32_t));
ND_TCHECK2(*bp, 4);
ND_PRINT((ndo, " %u", EXTRACT_32BITS(bp)));
bp += sizeof(uint32_t);
opt_len -= sizeof(uint32_t);
opts_len -= sizeof(uint32_t);
bp += 4;
opt_len -= 4;
opts_len -= 4;
}
break;
case PGM_OPT_JOIN:
if (opt_len != 8) {
ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != 8]", opt_len));
#define PGM_OPT_JOIN_LEN (2+2+4)
if (opt_len != PGM_OPT_JOIN_LEN) {
ND_PRINT((ndo, "[Bad OPT_JOIN option, length %u != %u]",
opt_len, PGM_OPT_JOIN_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
ND_PRINT((ndo, " JOIN %u", seq));
opts_len -= 8;
opts_len -= PGM_OPT_JOIN_LEN;
break;
case PGM_OPT_NAK_BO_IVL:
if (opt_len != 12) {
ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len));
#define PGM_OPT_NAK_BO_IVL_LEN (2+2+4+4)
if (opt_len != PGM_OPT_NAK_BO_IVL_LEN) {
ND_PRINT((ndo, "[Bad OPT_NAK_BO_IVL option, length %u != %u]",
opt_len, PGM_OPT_NAK_BO_IVL_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
seq = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
ND_PRINT((ndo, " BACKOFF ivl %u ivlseq %u", offset, seq));
opts_len -= 12;
opts_len -= PGM_OPT_NAK_BO_IVL_LEN;
break;
case PGM_OPT_NAK_BO_RNG:
if (opt_len != 12) {
ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len));
#define PGM_OPT_NAK_BO_RNG_LEN (2+2+4+4)
if (opt_len != PGM_OPT_NAK_BO_RNG_LEN) {
ND_PRINT((ndo, "[Bad OPT_NAK_BO_RNG option, length %u != %u]",
opt_len, PGM_OPT_NAK_BO_RNG_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
seq = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
ND_PRINT((ndo, " BACKOFF max %u min %u", offset, seq));
opts_len -= 12;
opts_len -= PGM_OPT_NAK_BO_RNG_LEN;
break;
case PGM_OPT_REDIRECT:
#define PGM_OPT_REDIRECT_FIXED_LEN (2+2+2+2)
if (opt_len < PGM_OPT_REDIRECT_FIXED_LEN) {
ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u < %u]",
opt_len, PGM_OPT_REDIRECT_FIXED_LEN));
return;
}
bp += 2;
nla_afnum = EXTRACT_16BITS(bp);
bp += (2 * sizeof(uint16_t));
bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
if (opt_len != 4 + sizeof(struct in_addr)) {
ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr)) {
ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]",
opt_len, PGM_OPT_REDIRECT_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
opts_len -= 4 + sizeof(struct in_addr);
opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
if (opt_len != 4 + sizeof(struct in6_addr)) {
ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len));
if (opt_len != PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr)) {
ND_PRINT((ndo, "[Bad OPT_REDIRECT option, length %u != %u + address size]",
PGM_OPT_REDIRECT_FIXED_LEN, opt_len));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
opts_len -= 4 + sizeof(struct in6_addr);
opts_len -= PGM_OPT_REDIRECT_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
@ -591,49 +613,57 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_PARITY_PRM:
if (opt_len != 8) {
ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len));
#define PGM_OPT_PARITY_PRM_LEN (2+2+4)
if (opt_len != PGM_OPT_PARITY_PRM_LEN) {
ND_PRINT((ndo, "[Bad OPT_PARITY_PRM option, length %u != %u]",
opt_len, PGM_OPT_PARITY_PRM_LEN));
return;
}
bp += 2;
len = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
ND_PRINT((ndo, " PARITY MAXTGS %u", len));
opts_len -= 8;
opts_len -= PGM_OPT_PARITY_PRM_LEN;
break;
case PGM_OPT_PARITY_GRP:
if (opt_len != 8) {
ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len));
#define PGM_OPT_PARITY_GRP_LEN (2+2+4)
if (opt_len != PGM_OPT_PARITY_GRP_LEN) {
ND_PRINT((ndo, "[Bad OPT_PARITY_GRP option, length %u != %u]",
opt_len, PGM_OPT_PARITY_GRP_LEN));
return;
}
bp += 2;
seq = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
ND_PRINT((ndo, " PARITY GROUP %u", seq));
opts_len -= 8;
opts_len -= PGM_OPT_PARITY_GRP_LEN;
break;
case PGM_OPT_CURR_TGSIZE:
if (opt_len != 8) {
ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len));
#define PGM_OPT_CURR_TGSIZE_LEN (2+2+4)
if (opt_len != PGM_OPT_CURR_TGSIZE_LEN) {
ND_PRINT((ndo, "[Bad OPT_CURR_TGSIZE option, length %u != %u]",
opt_len, PGM_OPT_CURR_TGSIZE_LEN));
return;
}
bp += 2;
len = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
ND_PRINT((ndo, " PARITY ATGS %u", len));
opts_len -= 8;
opts_len -= PGM_OPT_CURR_TGSIZE_LEN;
break;
case PGM_OPT_NBR_UNREACH:
if (opt_len != 4) {
ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len));
#define PGM_OPT_NBR_UNREACH_LEN (2+2)
if (opt_len != PGM_OPT_NBR_UNREACH_LEN) {
ND_PRINT((ndo, "[Bad OPT_NBR_UNREACH option, length %u != %u]",
opt_len, PGM_OPT_NBR_UNREACH_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " NBR_UNREACH"));
opts_len -= 4;
opts_len -= PGM_OPT_NBR_UNREACH_LEN;
break;
case PGM_OPT_PATH_NLA:
@ -643,33 +673,39 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_SYN:
if (opt_len != 4) {
ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != 4]", opt_len));
#define PGM_OPT_SYN_LEN (2+2)
if (opt_len != PGM_OPT_SYN_LEN) {
ND_PRINT((ndo, "[Bad OPT_SYN option, length %u != %u]",
opt_len, PGM_OPT_SYN_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " SYN"));
opts_len -= 4;
opts_len -= PGM_OPT_SYN_LEN;
break;
case PGM_OPT_FIN:
if (opt_len != 4) {
ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != 4]", opt_len));
#define PGM_OPT_FIN_LEN (2+2)
if (opt_len != PGM_OPT_FIN_LEN) {
ND_PRINT((ndo, "[Bad OPT_FIN option, length %u != %u]",
opt_len, PGM_OPT_FIN_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " FIN"));
opts_len -= 4;
opts_len -= PGM_OPT_FIN_LEN;
break;
case PGM_OPT_RST:
if (opt_len != 4) {
ND_PRINT((ndo, "[Bad OPT_RST option, length %u != 4]", opt_len));
#define PGM_OPT_RST_LEN (2+2)
if (opt_len != PGM_OPT_RST_LEN) {
ND_PRINT((ndo, "[Bad OPT_RST option, length %u != %u]",
opt_len, PGM_OPT_RST_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " RST"));
opts_len -= 4;
opts_len -= PGM_OPT_RST_LEN;
break;
case PGM_OPT_CR:
@ -679,41 +715,51 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_CRQST:
if (opt_len != 4) {
ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != 4]", opt_len));
#define PGM_OPT_CRQST_LEN (2+2)
if (opt_len != PGM_OPT_CRQST_LEN) {
ND_PRINT((ndo, "[Bad OPT_CRQST option, length %u != %u]",
opt_len, PGM_OPT_CRQST_LEN));
return;
}
bp += 2;
ND_PRINT((ndo, " CRQST"));
opts_len -= 4;
opts_len -= PGM_OPT_CRQST_LEN;
break;
case PGM_OPT_PGMCC_DATA:
#define PGM_OPT_PGMCC_DATA_FIXED_LEN (2+2+4+2+2)
if (opt_len < PGM_OPT_PGMCC_DATA_FIXED_LEN) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u < %u]",
opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
nla_afnum = EXTRACT_16BITS(bp);
bp += (2 * sizeof(uint16_t));
bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
if (opt_len != 12 + sizeof(struct in_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]",
opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
opts_len -= 12 + sizeof(struct in_addr);
opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
if (opt_len != 12 + sizeof(struct in6_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
if (opt_len != PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != %u + address size]",
opt_len, PGM_OPT_PGMCC_DATA_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
opts_len -= 12 + sizeof(struct in6_addr);
opts_len -= PGM_OPT_PGMCC_DATA_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;
@ -724,31 +770,39 @@ pgm_print(netdissect_options *ndo,
break;
case PGM_OPT_PGMCC_FEEDBACK:
#define PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN (2+2+4+2+2)
if (opt_len < PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN) {
ND_PRINT((ndo, "[Bad PGM_OPT_PGMCC_FEEDBACK option, length %u < %u]",
opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
return;
}
bp += 2;
offset = EXTRACT_32BITS(bp);
bp += sizeof(uint32_t);
bp += 4;
nla_afnum = EXTRACT_16BITS(bp);
bp += (2 * sizeof(uint16_t));
bp += 2+2;
switch (nla_afnum) {
case AFNUM_INET:
if (opt_len != 12 + sizeof(struct in_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]",
opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in_addr));
addrtostr(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in_addr);
opts_len -= 12 + sizeof(struct in_addr);
opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in_addr);
break;
case AFNUM_INET6:
if (opt_len != 12 + sizeof(struct in6_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len));
if (opt_len != PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr)) {
ND_PRINT((ndo, "[Bad OPT_PGMCC_FEEDBACK option, length %u != %u + address size]",
opt_len, PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN));
return;
}
ND_TCHECK2(*bp, sizeof(struct in6_addr));
addrtostr6(bp, nla_buf, sizeof(nla_buf));
bp += sizeof(struct in6_addr);
opts_len -= 12 + sizeof(struct in6_addr);
opts_len -= PGM_OPT_PGMCC_FEEDBACK_FIXED_LEN + sizeof(struct in6_addr);
break;
default:
goto trunc;

View File

@ -169,20 +169,28 @@ pimv1_join_prune_print(netdissect_options *ndo,
return;
}
if (len < sizeof(struct in_addr))
goto trunc;
ND_TCHECK2(bp[0], sizeof(struct in_addr));
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n"));
ND_PRINT((ndo, " Upstream Nbr: %s", ipaddr_string(ndo, bp)));
ND_TCHECK2(bp[6], 2);
bp += 4;
len -= 4;
if (len < 4)
goto trunc;
ND_TCHECK2(bp[2], 2);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n"));
ND_PRINT((ndo, " Hold time: "));
unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[6]));
unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2]));
if (ndo->ndo_vflag < 2)
return;
bp += 8;
len -= 8;
bp += 4;
len -= 4;
if (len < 4)
goto trunc;
ND_TCHECK2(bp[0], 4);
ngroups = bp[3];
bp += 4;
@ -192,17 +200,27 @@ pimv1_join_prune_print(netdissect_options *ndo,
* XXX - does the address have length "addrlen" and the
* mask length "maddrlen"?
*/
if (len < 4)
goto trunc;
ND_TCHECK2(bp[0], sizeof(struct in_addr));
ND_PRINT((ndo, "\n\tGroup: %s", ipaddr_string(ndo, bp)));
ND_TCHECK2(bp[4], sizeof(struct in_addr));
if (EXTRACT_32BITS(&bp[4]) != 0xffffffff)
ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[4])));
ND_TCHECK2(bp[8], 4);
njoin = EXTRACT_16BITS(&bp[8]);
nprune = EXTRACT_16BITS(&bp[10]);
bp += 4;
len -= 4;
if (len < 4)
goto trunc;
ND_TCHECK2(bp[0], sizeof(struct in_addr));
if (EXTRACT_32BITS(&bp[0]) != 0xffffffff)
ND_PRINT((ndo, "/%s", ipaddr_string(ndo, &bp[0])));
bp += 4;
len -= 4;
if (len < 4)
goto trunc;
ND_TCHECK2(bp[0], 4);
njoin = EXTRACT_16BITS(&bp[0]);
nprune = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, " joined: %d pruned: %d", njoin, nprune));
bp += 12;
len -= 12;
bp += 4;
len -= 4;
for (njp = 0; njp < (njoin + nprune); njp++) {
const char *type;
@ -210,12 +228,15 @@ pimv1_join_prune_print(netdissect_options *ndo,
type = "Join ";
else
type = "Prune";
if (len < 6)
goto trunc;
ND_TCHECK2(bp[0], 6);
ND_PRINT((ndo, "\n\t%s %s%s%s%s/%d", type,
(bp[0] & 0x01) ? "Sparse " : "Dense ",
(bp[1] & 0x80) ? "WC " : "",
(bp[1] & 0x40) ? "RP " : "SPT ",
ipaddr_string(ndo, &bp[2]), bp[1] & 0x3f));
ipaddr_string(ndo, &bp[2]),
bp[1] & 0x3f));
bp += 6;
len -= 6;
}
@ -230,13 +251,8 @@ void
pimv1_print(netdissect_options *ndo,
register const u_char *bp, register u_int len)
{
register const u_char *ep;
register u_char type;
ep = (const u_char *)ndo->ndo_snapend;
if (bp >= ep)
return;
ND_TCHECK(bp[1]);
type = bp[1];
@ -302,10 +318,14 @@ pimv1_print(netdissect_options *ndo,
case PIMV1_TYPE_JOIN_PRUNE:
case PIMV1_TYPE_GRAFT:
case PIMV1_TYPE_GRAFT_ACK:
if (ndo->ndo_vflag)
if (ndo->ndo_vflag) {
if (len < 8)
goto trunc;
pimv1_join_prune_print(ndo, &bp[8], len - 8);
}
break;
}
ND_TCHECK(bp[4]);
if ((bp[4] >> 4) != 1)
ND_PRINT((ndo, " [v%d]", bp[4] >> 4));
return;
@ -329,6 +349,8 @@ cisco_autorp_print(netdissect_options *ndo,
int numrps;
int hold;
if (len < 8)
goto trunc;
ND_TCHECK(bp[0]);
ND_PRINT((ndo, " auto-rp "));
type = bp[0];
@ -376,10 +398,16 @@ cisco_autorp_print(netdissect_options *ndo,
int nentries;
char s;
if (len < 4)
goto trunc;
ND_TCHECK2(bp[0], 4);
ND_PRINT((ndo, " RP %s", ipaddr_string(ndo, bp)));
ND_TCHECK(bp[4]);
switch (bp[4] & 0x3) {
bp += 4;
len -= 4;
if (len < 1)
goto trunc;
ND_TCHECK(bp[0]);
switch (bp[0] & 0x3) {
case 0: ND_PRINT((ndo, " PIMv?"));
break;
case 1: ND_PRINT((ndo, " PIMv1"));
@ -389,13 +417,20 @@ cisco_autorp_print(netdissect_options *ndo,
case 3: ND_PRINT((ndo, " PIMv1+2"));
break;
}
if (bp[4] & 0xfc)
ND_PRINT((ndo, " [rsvd=0x%02x]", bp[4] & 0xfc));
ND_TCHECK(bp[5]);
nentries = bp[5];
bp += 6; len -= 6;
if (bp[0] & 0xfc)
ND_PRINT((ndo, " [rsvd=0x%02x]", bp[0] & 0xfc));
bp += 1;
len -= 1;
if (len < 1)
goto trunc;
ND_TCHECK(bp[0]);
nentries = bp[0];
bp += 1;
len -= 1;
s = ' ';
for (; nentries; nentries--) {
if (len < 6)
goto trunc;
ND_TCHECK2(bp[0], 6);
ND_PRINT((ndo, "%c%s%s/%d", s, bp[0] & 1 ? "!" : "",
ipaddr_string(ndo, &bp[2]), bp[1]));
@ -420,16 +455,13 @@ void
pim_print(netdissect_options *ndo,
register const u_char *bp, register u_int len, const u_char *bp2)
{
register const u_char *ep;
register const struct pim *pim = (const struct pim *)bp;
ep = (const u_char *)ndo->ndo_snapend;
if (bp >= ep)
return;
#ifdef notyet /* currently we see only version and type */
ND_TCHECK(pim->pim_rsv);
#endif
ND_TCHECK(pim->pim_typever);
switch (PIM_VER(pim->pim_typever)) {
case 2:
if (!ndo->ndo_vflag) {
@ -453,6 +485,10 @@ pim_print(netdissect_options *ndo,
break;
}
return;
trunc:
ND_PRINT((ndo, "[|pim]"));
return;
}
/*
@ -495,8 +531,6 @@ pim_print(netdissect_options *ndo,
*
*/
static int pimv2_addr_len;
enum pimv2_addrtype {
pimv2_unicast, pimv2_group, pimv2_source
};
@ -523,23 +557,24 @@ enum pimv2_addrtype {
*/
static int
pimv2_addr_print(netdissect_options *ndo,
const u_char *bp, enum pimv2_addrtype at, int silent)
const u_char *bp, u_int len, enum pimv2_addrtype at,
u_int addr_len, int silent)
{
int af;
int len, hdrlen;
int hdrlen;
ND_TCHECK(bp[0]);
if (pimv2_addr_len == 0) {
if (addr_len == 0) {
if (len < 2)
goto trunc;
ND_TCHECK(bp[1]);
switch (bp[0]) {
case 1:
af = AF_INET;
len = sizeof(struct in_addr);
addr_len = (u_int)sizeof(struct in_addr);
break;
case 2:
af = AF_INET6;
len = sizeof(struct in6_addr);
addr_len = (u_int)sizeof(struct in6_addr);
break;
default:
return -1;
@ -548,7 +583,7 @@ pimv2_addr_print(netdissect_options *ndo,
return -1;
hdrlen = 2;
} else {
switch (pimv2_addr_len) {
switch (addr_len) {
case sizeof(struct in_addr):
af = AF_INET;
break;
@ -559,14 +594,16 @@ pimv2_addr_print(netdissect_options *ndo,
return -1;
break;
}
len = pimv2_addr_len;
hdrlen = 0;
}
bp += hdrlen;
len -= hdrlen;
switch (at) {
case pimv2_unicast:
ND_TCHECK2(bp[0], len);
if (len < addr_len)
goto trunc;
ND_TCHECK2(bp[0], addr_len);
if (af == AF_INET) {
if (!silent)
ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp)));
@ -575,10 +612,12 @@ pimv2_addr_print(netdissect_options *ndo,
if (!silent)
ND_PRINT((ndo, "%s", ip6addr_string(ndo, bp)));
}
return hdrlen + len;
return hdrlen + addr_len;
case pimv2_group:
case pimv2_source:
ND_TCHECK2(bp[0], len + 2);
if (len < addr_len + 2)
goto trunc;
ND_TCHECK2(bp[0], addr_len + 2);
if (af == AF_INET) {
if (!silent) {
ND_PRINT((ndo, "%s", ipaddr_string(ndo, bp + 2)));
@ -607,7 +646,7 @@ pimv2_addr_print(netdissect_options *ndo,
ND_PRINT((ndo, ")"));
}
}
return hdrlen + 2 + len;
return hdrlen + 2 + addr_len;
default:
return -1;
}
@ -655,21 +694,21 @@ static void
pimv2_print(netdissect_options *ndo,
register const u_char *bp, register u_int len, const u_char *bp2)
{
register const u_char *ep;
register const struct pim *pim = (const struct pim *)bp;
int advance;
enum checksum_status cksum_status;
int pimv2_addr_len;
ep = (const u_char *)ndo->ndo_snapend;
if (bp >= ep)
return;
if (ep > bp + len)
ep = bp + len;
if (len < 2)
goto trunc;
ND_TCHECK(pim->pim_rsv);
pimv2_addr_len = pim->pim_rsv;
if (pimv2_addr_len != 0)
ND_PRINT((ndo, ", RFC2117-encoding"));
if (len < 4)
goto trunc;
ND_TCHECK(pim->pim_cksum);
ND_PRINT((ndo, ", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum)));
if (EXTRACT_16BITS(&pim->pim_cksum) == 0) {
ND_PRINT((ndo, "(unverified)"));
@ -710,26 +749,36 @@ pimv2_print(netdissect_options *ndo,
break;
}
}
bp += 4;
len -= 4;
switch (PIM_TYPE(pim->pim_typever)) {
case PIMV2_TYPE_HELLO:
{
uint16_t otype, olen;
bp += 4;
while (bp < ep) {
while (len > 0) {
if (len < 4)
goto trunc;
ND_TCHECK2(bp[0], 4);
otype = EXTRACT_16BITS(&bp[0]);
olen = EXTRACT_16BITS(&bp[2]);
ND_TCHECK2(bp[0], 4 + olen);
ND_PRINT((ndo, "\n\t %s Option (%u), length %u, Value: ",
tok2str(pimv2_hello_option_values, "Unknown", otype),
otype,
olen));
bp += 4;
len -= 4;
if (len < olen)
goto trunc;
ND_TCHECK2(bp[0], olen);
switch (otype) {
case PIMV2_HELLO_OPTION_HOLDTIME:
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
if (olen != 2) {
ND_PRINT((ndo, "ERROR: Option Length != 2 Bytes (%u)", olen));
} else {
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
}
break;
case PIMV2_HELLO_OPTION_LANPRUNEDELAY:
@ -763,17 +812,25 @@ pimv2_print(netdissect_options *ndo,
break;
case PIMV2_HELLO_OPTION_GENID:
ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp)));
if (olen != 4) {
ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen));
} else {
ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(bp)));
}
break;
case PIMV2_HELLO_OPTION_REFRESH_CAP:
ND_PRINT((ndo, "v%d", *bp));
if (*(bp+1) != 0) {
ND_PRINT((ndo, ", interval "));
unsigned_relts_print(ndo, *(bp+1));
}
if (EXTRACT_16BITS(bp+2) != 0) {
ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2)));
if (olen != 4) {
ND_PRINT((ndo, "ERROR: Option Length != 4 Bytes (%u)", olen));
} else {
ND_PRINT((ndo, "v%d", *bp));
if (*(bp+1) != 0) {
ND_PRINT((ndo, ", interval "));
unsigned_relts_print(ndo, *(bp+1));
}
if (EXTRACT_16BITS(bp+2) != 0) {
ND_PRINT((ndo, " ?0x%04x?", EXTRACT_16BITS(bp+2)));
}
}
break;
@ -784,14 +841,14 @@ pimv2_print(netdissect_options *ndo,
case PIMV2_HELLO_OPTION_ADDRESS_LIST:
if (ndo->ndo_vflag > 1) {
const u_char *ptr = bp;
u_int plen = len;
while (ptr < (bp+olen)) {
ND_PRINT((ndo, "\n\t "));
advance = pimv2_addr_print(ndo, ptr, pimv2_unicast, 0);
if (advance < 0) {
ND_PRINT((ndo, "..."));
break;
}
advance = pimv2_addr_print(ndo, ptr, plen, pimv2_unicast, pimv2_addr_len, 0);
if (advance < 0)
goto trunc;
ptr += advance;
plen -= advance;
}
}
break;
@ -804,6 +861,7 @@ pimv2_print(netdissect_options *ndo,
if (ndo->ndo_vflag> 1)
print_unknown_data(ndo, bp, "\n\t ", olen);
bp += olen;
len -= olen;
}
break;
}
@ -812,18 +870,24 @@ pimv2_print(netdissect_options *ndo,
{
const struct ip *ip;
ND_TCHECK2(*(bp + 4), PIMV2_REGISTER_FLAG_LEN);
if (len < 4)
goto trunc;
ND_TCHECK2(*bp, PIMV2_REGISTER_FLAG_LEN);
ND_PRINT((ndo, ", Flags [ %s ]\n\t",
tok2str(pimv2_register_flag_values,
"none",
EXTRACT_32BITS(bp+4))));
EXTRACT_32BITS(bp))));
bp += 8; len -= 8;
bp += 4; len -= 4;
/* encapsulated multicast packet */
if (len == 0)
goto trunc;
ip = (const struct ip *)bp;
ND_TCHECK(ip->ip_vhl);
switch (IP_V(ip)) {
case 0: /* Null header */
ND_TCHECK(ip->ip_dst);
ND_PRINT((ndo, "IP-Null-header %s > %s",
ipaddr_string(ndo, &ip->ip_src),
ipaddr_string(ndo, &ip->ip_dst)));
@ -845,22 +909,13 @@ pimv2_print(netdissect_options *ndo,
}
case PIMV2_TYPE_REGISTER_STOP:
bp += 4; len -= 4;
if (bp >= ep)
break;
ND_PRINT((ndo, " group="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
if (bp >= ep)
break;
ND_PRINT((ndo, " source="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
break;
@ -911,19 +966,15 @@ pimv2_print(netdissect_options *ndo,
uint16_t nprune;
int i, j;
bp += 4; len -= 4;
if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/
if (bp >= ep)
break;
ND_PRINT((ndo, ", upstream-neighbor: "));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
}
if (bp + 4 > ep)
break;
if (len < 4)
goto trunc;
ND_TCHECK2(*bp, 4);
ngroup = bp[1];
holdtime = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, "\n\t %u group(s)", ngroup));
@ -936,139 +987,125 @@ pimv2_print(netdissect_options *ndo,
}
bp += 4; len -= 4;
for (i = 0; i < ngroup; i++) {
if (bp >= ep)
goto jp_done;
ND_PRINT((ndo, "\n\t group #%u: ", i+1));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
ND_PRINT((ndo, "...)"));
goto jp_done;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
if (bp + 4 > ep) {
ND_PRINT((ndo, "...)"));
goto jp_done;
}
if (len < 4)
goto trunc;
ND_TCHECK2(*bp, 4);
njoin = EXTRACT_16BITS(&bp[0]);
nprune = EXTRACT_16BITS(&bp[2]);
ND_PRINT((ndo, ", joined sources: %u, pruned sources: %u", njoin, nprune));
bp += 4; len -= 4;
for (j = 0; j < njoin; j++) {
ND_PRINT((ndo, "\n\t joined source #%u: ", j+1));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) {
ND_PRINT((ndo, "...)"));
goto jp_done;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
}
for (j = 0; j < nprune; j++) {
ND_PRINT((ndo, "\n\t pruned source #%u: ", j+1));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_source, 0)) < 0) {
ND_PRINT((ndo, "...)"));
goto jp_done;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_source, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
}
}
jp_done:
break;
}
case PIMV2_TYPE_BOOTSTRAP:
{
int i, j, frpcnt;
bp += 4;
/* Fragment Tag, Hash Mask len, and BSR-priority */
if (bp + sizeof(uint16_t) >= ep) break;
if (len < 2)
goto trunc;
ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " tag=%x", EXTRACT_16BITS(bp)));
bp += sizeof(uint16_t);
if (bp >= ep) break;
bp += 2;
len -= 2;
if (len < 1)
goto trunc;
ND_TCHECK(bp[0]);
ND_PRINT((ndo, " hashmlen=%d", bp[0]));
if (bp + 1 >= ep) break;
if (len < 2)
goto trunc;
ND_TCHECK(bp[2]);
ND_PRINT((ndo, " BSRprio=%d", bp[1]));
bp += 2;
len -= 2;
/* Encoded-Unicast-BSR-Address */
if (bp >= ep) break;
ND_PRINT((ndo, " BSR="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance;
len -= advance;
for (i = 0; bp < ep; i++) {
for (i = 0; len > 0; i++) {
/* Encoded-Group Address */
ND_PRINT((ndo, " (group%d: ", i));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0))
< 0) {
ND_PRINT((ndo, "...)"));
goto bs_done;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance;
len -= advance;
/* RP-Count, Frag RP-Cnt, and rsvd */
if (bp >= ep) {
ND_PRINT((ndo, "...)"));
goto bs_done;
}
if (len < 1)
goto trunc;
ND_TCHECK(bp[0]);
ND_PRINT((ndo, " RPcnt=%d", bp[0]));
if (bp + 1 >= ep) {
ND_PRINT((ndo, "...)"));
goto bs_done;
}
if (len < 2)
goto trunc;
ND_TCHECK(bp[1]);
ND_PRINT((ndo, " FRPcnt=%d", frpcnt = bp[1]));
if (len < 4)
goto trunc;
bp += 4;
len -= 4;
for (j = 0; j < frpcnt && bp < ep; j++) {
for (j = 0; j < frpcnt && len > 0; j++) {
/* each RP info */
ND_PRINT((ndo, " RP%d=", j));
if ((advance = pimv2_addr_print(ndo, bp,
if ((advance = pimv2_addr_print(ndo, bp, len,
pimv2_unicast,
0)) < 0) {
ND_PRINT((ndo, "...)"));
goto bs_done;
}
pimv2_addr_len,
0)) < 0)
goto trunc;
bp += advance;
len -= advance;
if (bp + 1 >= ep) {
ND_PRINT((ndo, "...)"));
goto bs_done;
}
if (len < 2)
goto trunc;
ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, ",holdtime="));
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
if (bp + 2 >= ep) {
ND_PRINT((ndo, "...)"));
goto bs_done;
}
if (len < 3)
goto trunc;
ND_TCHECK(bp[2]);
ND_PRINT((ndo, ",prio=%d", bp[2]));
if (len < 4)
goto trunc;
bp += 4;
len -= 4;
}
ND_PRINT((ndo, ")"));
}
bs_done:
break;
}
case PIMV2_TYPE_ASSERT:
bp += 4; len -= 4;
if (bp >= ep)
break;
ND_PRINT((ndo, " group="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
if (bp >= ep)
break;
ND_PRINT((ndo, " src="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance; len -= advance;
if (bp + 8 > ep)
break;
if (len < 8)
goto trunc;
ND_TCHECK2(*bp, 8);
if (bp[0] & 0x80)
ND_PRINT((ndo, " RPT"));
ND_PRINT((ndo, " pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff));
@ -1078,61 +1115,62 @@ pimv2_print(netdissect_options *ndo,
case PIMV2_TYPE_CANDIDATE_RP:
{
int i, pfxcnt;
bp += 4;
/* Prefix-Cnt, Priority, and Holdtime */
if (bp >= ep) break;
if (len < 1)
goto trunc;
ND_TCHECK(bp[0]);
ND_PRINT((ndo, " prefix-cnt=%d", bp[0]));
pfxcnt = bp[0];
if (bp + 1 >= ep) break;
if (len < 2)
goto trunc;
ND_TCHECK(bp[1]);
ND_PRINT((ndo, " prio=%d", bp[1]));
if (bp + 3 >= ep) break;
if (len < 4)
goto trunc;
ND_TCHECK_16BITS(&bp[2]);
ND_PRINT((ndo, " holdtime="));
unsigned_relts_print(ndo, EXTRACT_16BITS(&bp[2]));
bp += 4;
len -= 4;
/* Encoded-Unicast-RP-Address */
if (bp >= ep) break;
ND_PRINT((ndo, " RP="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance;
len -= advance;
/* Encoded-Group Addresses */
for (i = 0; i < pfxcnt && bp < ep; i++) {
for (i = 0; i < pfxcnt && len > 0; i++) {
ND_PRINT((ndo, " Group%d=", i));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0))
< 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance;
len -= advance;
}
break;
}
case PIMV2_TYPE_PRUNE_REFRESH:
ND_PRINT((ndo, " src="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance;
len -= advance;
ND_PRINT((ndo, " grp="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_group, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_group, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance;
len -= advance;
ND_PRINT((ndo, " forwarder="));
if ((advance = pimv2_addr_print(ndo, bp, pimv2_unicast, 0)) < 0) {
ND_PRINT((ndo, "..."));
break;
}
if ((advance = pimv2_addr_print(ndo, bp, len, pimv2_unicast, pimv2_addr_len, 0)) < 0)
goto trunc;
bp += advance;
ND_TCHECK2(bp[0], 2);
len -= advance;
if (len < 2)
goto trunc;
ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " TUNR "));
unsigned_relts_print(ndo, EXTRACT_16BITS(bp));
break;

View File

@ -104,6 +104,7 @@ pktap_if_print(netdissect_options *ndo,
u_int length = h->len;
if_printer printer;
const pktap_header_t *hdr;
struct pcap_pkthdr nhdr;
if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) {
ND_PRINT((ndo, "[|pktap]"));
@ -144,7 +145,10 @@ pktap_if_print(netdissect_options *ndo,
case PKT_REC_PACKET:
if ((printer = lookup_printer(dlt)) != NULL) {
hdrlen += printer(ndo, h, p);
nhdr = *h;
nhdr.caplen = caplen;
nhdr.len = length;
hdrlen += printer(ndo, &nhdr, p);
} else {
if (!ndo->ndo_eflag)
pktap_header_print(ndo, (const u_char *)hdr,

View File

@ -611,7 +611,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 6)"));
return len;
}
ND_TCHECK2(*(p + 2), 3);
ND_TCHECK_24BITS(p + 2);
ND_PRINT((ndo, ": Vendor: %s (%u)",
tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
EXTRACT_24BITS(p + 2)));
@ -630,7 +630,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return len;
}
ND_TCHECK2(*(p + 2), 2);
ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_ACCM:
@ -638,7 +638,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return len;
}
ND_TCHECK2(*(p + 2), 4);
ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
break;
case LCPOPT_AP:
@ -646,7 +646,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
ND_TCHECK2(*(p + 2), 2);
ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2))));
switch (EXTRACT_16BITS(p+2)) {
@ -668,7 +668,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return 0;
}
ND_TCHECK2(*(p + 2), 2);
ND_TCHECK_16BITS(p+2);
if (EXTRACT_16BITS(p+2) == PPP_LQM)
ND_PRINT((ndo, ": LQR"));
else
@ -679,7 +679,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return 0;
}
ND_TCHECK2(*(p + 2), 4);
ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
break;
case LCPOPT_PFC:
@ -691,7 +691,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return 0;
}
ND_TCHECK2(*(p + 2), 2);
ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_CBACK:
@ -710,7 +710,7 @@ print_lcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 4)"));
return 0;
}
ND_TCHECK2(*(p + 2), 2);
ND_TCHECK_16BITS(p + 2);
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
break;
case LCPOPT_MLED:
@ -811,6 +811,15 @@ handle_mlppp(netdissect_options *ndo,
if (!ndo->ndo_eflag)
ND_PRINT((ndo, "MLPPP, "));
if (length < 2) {
ND_PRINT((ndo, "[|mlppp]"));
return;
}
if (!ND_TTEST_16BITS(p)) {
ND_PRINT((ndo, "[|mlppp]"));
return;
}
ND_PRINT((ndo, "seq 0x%03x, Flags [%s], length %u",
(EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */
bittok2str(ppp_ml_flag_values, "none", *p & 0xc0),
@ -1055,7 +1064,7 @@ print_ipcp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return 0;
}
ND_TCHECK2(*(p + 2), 2);
ND_TCHECK_16BITS(p+2);
compproto = EXTRACT_16BITS(p+2);
ND_PRINT((ndo, ": %s (0x%02x):",
@ -1241,7 +1250,7 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 3)"));
return len;
}
ND_TCHECK2(*(p + 2), 1);
ND_TCHECK(p[2]);
ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u",
p[2] >> 5, p[2] & 0x1f));
break;
@ -1250,7 +1259,7 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
ND_TCHECK2(*(p + 2), 1);
ND_TCHECK(p[3]);
ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u",
(p[2] & 0xc0) >> 6,
(p[2] & 0x20) ? "Enabled" : "Disabled",
@ -1261,10 +1270,10 @@ print_ccp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be >= 4)"));
return len;
}
ND_TCHECK2(*(p + 2), 1);
ND_TCHECK(p[3]);
ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u",
(p[2] & 0xf0) >> 4,
((p[2] & 0x0f) == 8) ? "zlib" : "unkown",
((p[2] & 0x0f) == 8) ? "zlib" : "unknown",
p[2] & 0x0f, (p[3] & 0xfc) >> 2, p[3] & 0x03));
break;
@ -1336,7 +1345,7 @@ print_bacp_config_options(netdissect_options *ndo,
ND_PRINT((ndo, " (length bogus, should be = 6)"));
return len;
}
ND_TCHECK2(*(p + 2), 4);
ND_TCHECK_32BITS(p + 2);
ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)));
break;
default:
@ -1484,7 +1493,7 @@ handle_ppp(netdissect_options *ndo,
ipx_print(ndo, p, length);
break;
case PPP_OSI:
isoclns_print(ndo, p, length, length);
isoclns_print(ndo, p, length);
break;
case PPP_MPLS_UCAST:
case PPP_MPLS_MCAST:

View File

@ -496,10 +496,7 @@ print_attr_string(netdissect_options *ndo,
{
case TUNNEL_PASS:
if (length < 3)
{
ND_PRINT((ndo, "%s", tstr));
return;
}
goto trunc;
if (*data && (*data <=0x1F) )
ND_PRINT((ndo, "Tag[%u] ", *data));
else
@ -519,10 +516,7 @@ print_attr_string(netdissect_options *ndo,
if (*data <= 0x1F)
{
if (length < 1)
{
ND_PRINT((ndo, "%s", tstr));
return;
}
goto trunc;
if (*data)
ND_PRINT((ndo, "Tag[%u] ", *data));
else
@ -532,6 +526,8 @@ print_attr_string(netdissect_options *ndo,
}
break;
case EGRESS_VLAN_NAME:
if (length < 1)
goto trunc;
ND_PRINT((ndo, "%s (0x%02x) ",
tok2str(rfc4675_tagged,"Unknown tag",*data),
*data));
@ -540,7 +536,7 @@ print_attr_string(netdissect_options *ndo,
break;
}
for (i=0; *data && i < length ; i++, data++)
for (i=0; i < length && *data; i++, data++)
ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data));
return;

View File

@ -481,8 +481,10 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
ND_TCHECK(*bp);
c = *bp;
if (!(c >= '0' && c <= '9')) {
if (!saw_digit)
if (!saw_digit) {
bp++;
goto invalid;
}
break;
}
c -= '0';
@ -491,7 +493,7 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
too_large = 1;
} else {
result *= 10;
if (result == INT_MAX && c > (INT_MAX % 10)) {
if (result == ((INT_MAX / 10) * 10) && c > (INT_MAX % 10)) {
/* This will overflow an int when we add c */
too_large = 1;
} else
@ -501,24 +503,24 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
len--;
saw_digit = 1;
}
if (!saw_digit)
goto invalid;
/*
* OK, the next thing should be \r\n.
* OK, we found a non-digit character. It should be a \r, followed
* by a \n.
*/
if (len == 0)
goto trunc;
ND_TCHECK(*bp);
if (*bp != '\r')
if (*bp != '\r') {
bp++;
goto invalid;
}
bp++;
len--;
if (len == 0)
goto trunc;
ND_TCHECK(*bp);
if (*bp != '\n')
if (*bp != '\n') {
bp++;
goto invalid;
}
bp++;
len--;
*endp = bp;
@ -531,8 +533,10 @@ resp_get_length(netdissect_options *ndo, register const u_char *bp, int len, con
return (too_large ? -3 : result);
trunc:
*endp = bp;
return (-2);
invalid:
*endp = bp;
return (-5);
}

View File

@ -110,65 +110,74 @@ ripng_print(netdissect_options *ndo, const u_char *dat, unsigned int length)
{
register const struct rip6 *rp = (const struct rip6 *)dat;
register const struct netinfo6 *ni;
register u_int amt;
register u_int i;
int j;
int trunc;
if (ndo->ndo_snapend < dat)
return;
amt = ndo->ndo_snapend - dat;
i = min(length, amt);
if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
return;
i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
unsigned int length_left;
u_int j;
ND_TCHECK(rp->rip6_cmd);
switch (rp->rip6_cmd) {
case RIP6_REQUEST:
j = length / sizeof(*ni);
if (j == 1
&& rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
&& IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
ND_PRINT((ndo, " ripng-req dump"));
break;
length_left = length;
if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
goto trunc;
length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
j = length_left / sizeof(*ni);
if (j == 1) {
ND_TCHECK(rp->rip6_nets);
if (rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
&& IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
ND_PRINT((ndo, " ripng-req dump"));
break;
}
}
if (j * sizeof(*ni) != length - 4)
ND_PRINT((ndo, " ripng-req %d[%u]:", j, length));
if (j * sizeof(*ni) != length_left)
ND_PRINT((ndo, " ripng-req %u[%u]:", j, length));
else
ND_PRINT((ndo, " ripng-req %d:", j));
trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
for (ni = rp->rip6_nets; i >= sizeof(*ni);
i -= sizeof(*ni), ++ni) {
ND_PRINT((ndo, " ripng-req %u:", j));
for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
length_left -= sizeof(*ni), ++ni) {
ND_TCHECK(*ni);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n\t"));
else
ND_PRINT((ndo, " "));
rip6_entry_print(ndo, ni, 0);
}
if (length_left != 0)
goto trunc;
break;
case RIP6_RESPONSE:
j = length / sizeof(*ni);
if (j * sizeof(*ni) != length - 4)
length_left = length;
if (length_left < (sizeof(struct rip6) - sizeof(struct netinfo6)))
goto trunc;
length_left -= (sizeof(struct rip6) - sizeof(struct netinfo6));
j = length_left / sizeof(*ni);
if (j * sizeof(*ni) != length_left)
ND_PRINT((ndo, " ripng-resp %d[%u]:", j, length));
else
ND_PRINT((ndo, " ripng-resp %d:", j));
trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
for (ni = rp->rip6_nets; i >= sizeof(*ni);
i -= sizeof(*ni), ++ni) {
for (ni = rp->rip6_nets; length_left >= sizeof(*ni);
length_left -= sizeof(*ni), ++ni) {
ND_TCHECK(*ni);
if (ndo->ndo_vflag > 1)
ND_PRINT((ndo, "\n\t"));
else
ND_PRINT((ndo, " "));
rip6_entry_print(ndo, ni, ni->rip6_metric);
}
if (trunc)
ND_PRINT((ndo, "[|ripng]"));
if (length_left != 0)
goto trunc;
break;
default:
ND_PRINT((ndo, " ripng-%d ?? %u", rp->rip6_cmd, length));
break;
}
ND_TCHECK(rp->rip6_vers);
if (rp->rip6_vers != RIP6_VERSION)
ND_PRINT((ndo, " [vers %d]", rp->rip6_vers));
return;
trunc:
ND_PRINT((ndo, "[|ripng]"));
return;
}

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Resource Public Key Infrastructure (RPKI) to Router Protocol printer */
@ -82,6 +82,9 @@ typedef struct rpki_rtr_pdu_ipv6_prefix_ {
typedef struct rpki_rtr_pdu_error_report_ {
rpki_rtr_pdu pdu_header;
u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */
/* Copy of Erroneous PDU (variable, optional) */
/* Length of Error Text (4 octets in network byte order) */
/* Arbitrary Text of Error Diagnostic Message (variable, optional) */
} rpki_rtr_pdu_error_report;
/*
@ -171,17 +174,38 @@ indent_string (u_int indent)
/*
* Print a single PDU.
*/
static int
rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
static u_int
rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, const u_int len,
const u_char recurse, const u_int indent)
{
const rpki_rtr_pdu *pdu_header;
u_int pdu_type, pdu_len, hexdump;
const u_char *msg;
/* Protocol Version */
ND_TCHECK_8BITS(tptr);
if (*tptr != 0) {
/* Skip the rest of the input buffer because even if this is
* a well-formed PDU of a future RPKI-Router protocol version
* followed by a well-formed PDU of RPKI-Router protocol
* version 0, there is no way to know exactly how to skip the
* current PDU.
*/
ND_PRINT((ndo, "%sRPKI-RTRv%u (unknown)", indent_string(8), *tptr));
return len;
}
if (len < sizeof(rpki_rtr_pdu)) {
ND_PRINT((ndo, "(%u bytes is too few to decode)", len));
goto invalid;
}
ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu));
pdu_header = (const rpki_rtr_pdu *)tptr;
pdu_type = pdu_header->pdu_type;
pdu_len = EXTRACT_32BITS(pdu_header->length);
ND_TCHECK2(*tptr, pdu_len);
/* Do not check bounds with pdu_len yet, do it in the case blocks
* below to make it possible to decode at least the beginning of
* a truncated Error Report PDU or a truncated encapsulated PDU.
*/
hexdump = FALSE;
ND_PRINT((ndo, "%sRPKI-RTRv%u, %s PDU (%u), length: %u",
@ -189,6 +213,8 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
pdu_header->version,
tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type),
pdu_type, pdu_len));
if (pdu_len < sizeof(rpki_rtr_pdu) || pdu_len > len)
goto invalid;
switch (pdu_type) {
@ -198,6 +224,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
case RPKI_RTR_SERIAL_NOTIFY_PDU:
case RPKI_RTR_SERIAL_QUERY_PDU:
case RPKI_RTR_END_OF_DATA_PDU:
if (pdu_len != sizeof(rpki_rtr_pdu) + 4)
goto invalid;
ND_TCHECK2(*tptr, pdu_len);
msg = (const u_char *)(pdu_header + 1);
ND_PRINT((ndo, "%sSession ID: 0x%04x, Serial: %u",
indent_string(indent+2),
@ -210,6 +239,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
*/
case RPKI_RTR_RESET_QUERY_PDU:
case RPKI_RTR_CACHE_RESET_PDU:
if (pdu_len != sizeof(rpki_rtr_pdu))
goto invalid;
/* no additional boundary to check */
/*
* Zero payload PDUs.
@ -217,6 +249,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
break;
case RPKI_RTR_CACHE_RESPONSE_PDU:
if (pdu_len != sizeof(rpki_rtr_pdu))
goto invalid;
/* no additional boundary to check */
ND_PRINT((ndo, "%sSession ID: 0x%04x",
indent_string(indent+2),
EXTRACT_16BITS(pdu_header->u.session_id)));
@ -226,6 +261,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
const rpki_rtr_pdu_ipv4_prefix *pdu;
if (pdu_len != sizeof(rpki_rtr_pdu) + 12)
goto invalid;
ND_TCHECK2(*tptr, pdu_len);
pdu = (const rpki_rtr_pdu_ipv4_prefix *)tptr;
ND_PRINT((ndo, "%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
indent_string(indent+2),
@ -239,6 +277,9 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
{
const rpki_rtr_pdu_ipv6_prefix *pdu;
if (pdu_len != sizeof(rpki_rtr_pdu) + 24)
goto invalid;
ND_TCHECK2(*tptr, pdu_len);
pdu = (const rpki_rtr_pdu_ipv6_prefix *)tptr;
ND_PRINT((ndo, "%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
indent_string(indent+2),
@ -253,10 +294,17 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
const rpki_rtr_pdu_error_report *pdu;
u_int encapsulated_pdu_length, text_length, tlen, error_code;
tlen = sizeof(rpki_rtr_pdu);
/* Do not test for the "Length of Error Text" data element yet. */
if (pdu_len < tlen + 4)
goto invalid;
ND_TCHECK2(*tptr, tlen + 4);
/* Safe up to and including the "Length of Encapsulated PDU"
* data element, more data elements may be present.
*/
pdu = (const rpki_rtr_pdu_error_report *)tptr;
encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length);
ND_TCHECK2(*tptr, encapsulated_pdu_length);
tlen = pdu_len;
tlen += 4;
error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code);
ND_PRINT((ndo, "%sError code: %s (%u), Encapsulated PDU length: %u",
@ -264,41 +312,58 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
tok2str(rpki_rtr_error_codes, "Unknown", error_code),
error_code, encapsulated_pdu_length));
tptr += sizeof(*pdu);
tlen -= sizeof(*pdu);
/*
* Recurse if there is an encapsulated PDU.
*/
if (encapsulated_pdu_length &&
(encapsulated_pdu_length <= tlen)) {
ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
if (rpki_rtr_pdu_print(ndo, tptr, indent+2))
goto trunc;
if (encapsulated_pdu_length) {
/* Section 5.10 of RFC 6810 says:
* "An Error Report PDU MUST NOT be sent for an Error Report PDU."
*
* However, as far as the protocol encoding goes Error Report PDUs can
* happen to be nested in each other, however many times, in which case
* the decoder should still print such semantically incorrect PDUs.
*
* That said, "the Erroneous PDU field MAY be truncated" (ibid), thus
* to keep things simple this implementation decodes only the two
* outermost layers of PDUs and makes bounds checks in the outer and
* the inner PDU independently.
*/
if (pdu_len < tlen + encapsulated_pdu_length)
goto invalid;
if (! recurse) {
ND_TCHECK2(*tptr, tlen + encapsulated_pdu_length);
}
else {
ND_PRINT((ndo, "%s-----encapsulated PDU-----", indent_string(indent+4)));
rpki_rtr_pdu_print(ndo, tptr + tlen,
encapsulated_pdu_length, 0, indent + 2);
}
tlen += encapsulated_pdu_length;
}
tptr += encapsulated_pdu_length;
tlen -= encapsulated_pdu_length;
if (pdu_len < tlen + 4)
goto invalid;
ND_TCHECK2(*tptr, tlen + 4);
/* Safe up to and including the "Length of Error Text" data element,
* one more data element may be present.
*/
/*
* Extract, trail-zero and print the Error message.
*/
text_length = 0;
if (tlen > 4) {
text_length = EXTRACT_32BITS(tptr);
tptr += 4;
tlen -= 4;
}
ND_TCHECK2(*tptr, text_length);
if (text_length && (text_length <= tlen )) {
text_length = EXTRACT_32BITS(tptr + tlen);
tlen += 4;
if (text_length) {
if (pdu_len < tlen + text_length)
goto invalid;
/* fn_printn() makes the bounds check */
ND_PRINT((ndo, "%sError text: ", indent_string(indent+2)));
if (fn_printn(ndo, tptr, text_length, ndo->ndo_snapend))
if (fn_printn(ndo, tptr + tlen, text_length, ndo->ndo_snapend))
goto trunc;
}
}
break;
default:
ND_TCHECK2(*tptr, pdu_len);
/*
* Unknown data, please hexdump.
@ -310,57 +375,29 @@ rpki_rtr_pdu_print (netdissect_options *ndo, const u_char *tptr, u_int indent)
if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
print_unknown_data(ndo,tptr,"\n\t ", pdu_len);
}
return 0;
return pdu_len;
invalid:
ND_PRINT((ndo, "%s", istr));
ND_TCHECK2(*tptr, len);
return len;
trunc:
return 1;
ND_PRINT((ndo, "\n\t%s", tstr));
return len;
}
void
rpki_rtr_print(netdissect_options *ndo, register const u_char *pptr, register u_int len)
{
u_int tlen, pdu_type, pdu_len;
const u_char *tptr;
const rpki_rtr_pdu *pdu_header;
tptr = pptr;
tlen = len;
if (!ndo->ndo_vflag) {
ND_PRINT((ndo, ", RPKI-RTR"));
return;
}
while (tlen >= sizeof(rpki_rtr_pdu)) {
ND_TCHECK2(*tptr, sizeof(rpki_rtr_pdu));
pdu_header = (const rpki_rtr_pdu *)tptr;
pdu_type = pdu_header->pdu_type;
pdu_len = EXTRACT_32BITS(pdu_header->length);
ND_TCHECK2(*tptr, pdu_len);
/* infinite loop check */
if (!pdu_type || !pdu_len) {
break;
}
if (tlen < pdu_len) {
goto trunc;
}
/*
* Print the PDU.
*/
if (rpki_rtr_pdu_print(ndo, tptr, 8))
goto trunc;
tlen -= pdu_len;
tptr += pdu_len;
while (len) {
u_int pdu_len = rpki_rtr_pdu_print(ndo, pptr, len, 1, 8);
len -= pdu_len;
pptr += pdu_len;
}
return;
trunc:
ND_PRINT((ndo, "\n\t%s", tstr));
}
/*

View File

@ -12,7 +12,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: Resource ReSerVation Protocol (RSVP) printer */
@ -1205,6 +1205,17 @@ rsvp_obj_print(netdissect_options *ndo,
/* read variable length subobjects */
total_subobj_len = obj_tlen;
while(total_subobj_len > 0) {
/* If RFC 3476 Section 3.1 defined that a sub-object of the
* GENERALIZED_UNI RSVP object must have the Length field as
* a multiple of 4, instead of the check below it would be
* better to test total_subobj_len only once before the loop.
* So long as it does not define it and this while loop does
* not implement such a requirement, let's accept that within
* each iteration subobj_len may happen to be a multiple of 1
* and test it and total_subobj_len respectively.
*/
if (total_subobj_len < 4)
goto invalid;
subobj_len = EXTRACT_16BITS(obj_tptr);
subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8;
af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF;
@ -1216,7 +1227,13 @@ rsvp_obj_print(netdissect_options *ndo,
tok2str(af_values, "Unknown", af), af,
subobj_len));
if(subobj_len == 0)
/* In addition to what is explained above, the same spec does not
* explicitly say that the same Length field includes the 4-octet
* sub-object header, but as long as this while loop implements it
* as it does include, let's keep the check below consistent with
* the rest of the code.
*/
if(subobj_len < 4 || subobj_len > total_subobj_len)
goto invalid;
switch(subobj_type) {
@ -1472,12 +1489,12 @@ rsvp_obj_print(netdissect_options *ndo,
case RSVP_OBJ_FASTREROUTE:
/* the differences between c-type 1 and 7 are minor */
obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_1: /* new style */
if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
return-1;
bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
ident,
(int)obj_ptr.rsvp_obj_frr->setup_prio,
@ -1496,6 +1513,7 @@ rsvp_obj_print(netdissect_options *ndo,
case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
if (obj_tlen < 16)
return-1;
bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
ND_PRINT((ndo, "%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
ident,
(int)obj_ptr.rsvp_obj_frr->setup_prio,

View File

@ -29,12 +29,12 @@
#include <string.h>
#include "ip6.h"
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
#include "ip6.h"
int
rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2 _U_)
{
@ -45,13 +45,13 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2
register const struct in6_addr *addr;
dp = (const struct ip6_rthdr *)bp;
len = dp->ip6r_len;
/* 'ep' points to the end of available data. */
ep = ndo->ndo_snapend;
ND_TCHECK(dp->ip6r_segleft);
len = dp->ip6r_len;
ND_PRINT((ndo, "srcrt (len=%d", dp->ip6r_len)); /*)*/
ND_PRINT((ndo, ", type=%d", dp->ip6r_type));
ND_PRINT((ndo, ", segleft=%d", dp->ip6r_segleft));
@ -62,7 +62,7 @@ rt6_print(netdissect_options *ndo, register const u_char *bp, const u_char *bp2
dp0 = (const struct ip6_rthdr0 *)dp;
ND_TCHECK(dp0->ip6r0_reserved);
if (dp0->ip6r0_reserved || ndo->ndo_vflag) {
if (EXTRACT_32BITS(dp0->ip6r0_reserved) || ndo->ndo_vflag) {
ND_PRINT((ndo, ", rsv=0x%0x",
EXTRACT_32BITS(&dp0->ip6r0_reserved)));
}

View File

@ -75,12 +75,12 @@
#define PRSFS_ADMINISTER 64 /* Change ACL's */
struct rx_header {
uint32_t epoch;
uint32_t cid;
uint32_t callNumber;
uint32_t seq;
uint32_t serial;
uint8_t type;
nd_uint32_t epoch;
nd_uint32_t cid;
nd_uint32_t callNumber;
nd_uint32_t seq;
nd_uint32_t serial;
nd_uint8_t type;
#define RX_PACKET_TYPE_DATA 1
#define RX_PACKET_TYPE_ACK 2
#define RX_PACKET_TYPE_BUSY 3
@ -91,7 +91,7 @@ struct rx_header {
#define RX_PACKET_TYPE_DEBUG 8
#define RX_PACKET_TYPE_PARAMS 9
#define RX_PACKET_TYPE_VERSION 13
uint8_t flags;
nd_uint8_t flags;
#define RX_CLIENT_INITIATED 1
#define RX_REQUEST_ACK 2
#define RX_LAST_PACKET 4
@ -99,10 +99,10 @@ struct rx_header {
#define RX_FREE_PACKET 16
#define RX_SLOW_START_OK 32
#define RX_JUMBO_PACKET 32
uint8_t userStatus;
uint8_t securityIndex;
uint16_t spare; /* How clever: even though the AFS */
uint16_t serviceId; /* header files indicate that the */
nd_uint8_t userStatus;
nd_uint8_t securityIndex;
nd_uint16_t spare; /* How clever: even though the AFS */
nd_uint16_t serviceId; /* header files indicate that the */
}; /* serviceId is first, it's really */
/* encoded _after_ the spare field */
/* I wasted a day figuring that out! */
@ -690,11 +690,11 @@ rx_cache_insert(netdissect_options *ndo,
if (++rx_cache_next >= RX_CACHE_SIZE)
rx_cache_next = 0;
rxent->callnum = rxh->callNumber;
rxent->callnum = EXTRACT_32BITS(&rxh->callNumber);
UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t));
UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t));
rxent->dport = dport;
rxent->serviceId = rxh->serviceId;
rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId);
rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
}
@ -722,10 +722,10 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
i = rx_cache_hint;
do {
rxent = &rx_cache[i];
if (rxent->callnum == rxh->callNumber &&
if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) &&
rxent->client.s_addr == clip &&
rxent->server.s_addr == sip &&
rxent->serviceId == rxh->serviceId &&
rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) &&
rxent->dport == sport) {
/* We got a match! */
@ -1262,6 +1262,7 @@ cb_print(netdissect_options *ndo,
if (j == 0)
ND_PRINT((ndo, " <none!>"));
ND_TCHECK_32BITS(bp);
j = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
@ -2533,6 +2534,10 @@ ubik_print(netdissect_options *ndo,
* gleaned from ubik/ubik_int.xg
*/
/* Every function that calls this function first makes a bounds check
* for (sizeof(rx_header) + 4) bytes, so long as it remains this way
* the line below will not over-read.
*/
ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)));
@ -2577,6 +2582,7 @@ ubik_print(netdissect_options *ndo,
INTOUT();
ND_PRINT((ndo, " length"));
INTOUT();
ND_TCHECK_32BITS(bp);
temp = EXTRACT_32BITS(bp);
bp += sizeof(int32_t);
tok2str(ubik_lock_types, "type %d", temp);

View File

@ -10,7 +10,7 @@
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
* Turned into common "text protocol" code, which this uses, by
* Guy Harris.
*/

View File

@ -131,8 +131,21 @@ sliplink_print(netdissect_options *ndo,
u_int hlen;
dir = p[SLX_DIR];
ND_PRINT((ndo, dir == SLIPDIR_IN ? "I " : "O "));
switch (dir) {
case SLIPDIR_IN:
ND_PRINT((ndo, "I "));
break;
case SLIPDIR_OUT:
ND_PRINT((ndo, "O "));
break;
default:
ND_PRINT((ndo, "Invalid direction %d ", dir));
dir = -1;
break;
}
if (ndo->ndo_nflag) {
/* XXX just dump the header */
register int i;
@ -155,13 +168,21 @@ sliplink_print(netdissect_options *ndo,
* has restored the IP header copy to IPPROTO_TCP.
*/
lastconn = ((const struct ip *)&p[SLX_CHDR])->ip_p;
ND_PRINT((ndo, "utcp %d: ", lastconn));
if (dir == -1) {
/* Direction is bogus, don't use it */
return;
}
hlen = IP_HL(ip);
hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]);
lastlen[dir][lastconn] = length - (hlen << 2);
ND_PRINT((ndo, "utcp %d: ", lastconn));
break;
default:
if (dir == -1) {
/* Direction is bogus, don't use it */
return;
}
if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
compressed_sl_print(ndo, &p[SLX_CHDR], ip,
length, dir);

View File

@ -15,7 +15,7 @@
* support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad
* OAM as per 802.3ah
*
* Original code by Hannes Gredler (hannes@juniper.net)
* Original code by Hannes Gredler (hannes@gredler.at)
*/
/* \summary: IEEE "slow protocols" (802.3ad/802.3ah) printer */

View File

@ -256,6 +256,7 @@ stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu,
return 1;
}
ND_TCHECK(stp_bpdu->flags);
ND_PRINT((ndo, "\n\tport-role %s, ",
tok2str(rstp_obj_port_role_values, "Unknown",
RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))));
@ -475,6 +476,7 @@ stp_print(netdissect_options *ndo, const u_char *p, u_int length)
if (stp_bpdu->protocol_version == STP_PROTO_SPB)
{
/* Validate v4 length */
ND_TCHECK_16BITS(p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
spb_len += 2;
if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) ||

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
* Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at>
* The TCPDUMP project
*
* Redistribution and use in source and binary forms, with or without

View File

@ -442,6 +442,7 @@ telnet_parse(netdissect_options *ndo, const u_char *sp, u_int length, int print)
break;
p++;
}
ND_TCHECK(*p);
if (*p != IAC)
goto pktend;

View File

@ -46,21 +46,6 @@
#define TFTP_ERROR 05 /* error code */
#define OACK 06 /* option acknowledgement */
struct tftphdr {
unsigned short th_opcode; /* packet type */
union {
unsigned short tu_block; /* block # */
unsigned short tu_code; /* error code */
char tu_stuff[1]; /* request packet stuff */
} th_u;
char th_data[1]; /* data or error string */
};
#define th_block th_u.tu_block
#define th_code th_u.tu_code
#define th_stuff th_u.tu_stuff
#define th_msg th_data
/*
* Error codes.
*/
@ -106,80 +91,75 @@ void
tftp_print(netdissect_options *ndo,
register const u_char *bp, u_int length)
{
register const struct tftphdr *tp;
register const char *cp;
register const u_char *p;
register int opcode;
u_int ui;
tp = (const struct tftphdr *)bp;
/* Print length */
ND_PRINT((ndo, " %d", length));
/* Print tftp request type */
if (length < 2)
goto trunc;
ND_TCHECK(tp->th_opcode);
opcode = EXTRACT_16BITS(&tp->th_opcode);
ND_TCHECK_16BITS(bp);
opcode = EXTRACT_16BITS(bp);
cp = tok2str(op2str, "tftp-#%d", opcode);
length -= 2;
ND_PRINT((ndo, " %s", cp));
/* Bail if bogus opcode */
if (*cp == 't')
return;
bp += 2;
length -= 2;
switch (opcode) {
case RRQ:
case WRQ:
p = (const u_char *)tp->th_stuff;
if (length == 0)
goto trunc;
ND_PRINT((ndo, " "));
/* Print filename */
ND_PRINT((ndo, "\""));
ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
ND_PRINT((ndo, "\""));
if (ui == 0)
goto trunc;
p += ui;
bp += ui;
length -= ui;
/* Print the mode - RRQ and WRQ only */
if (length == 0)
goto trunc; /* no mode */
ND_PRINT((ndo, " "));
ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
p += ui;
bp += ui;
length -= ui;
/* Print options, if any */
while (length != 0) {
ND_TCHECK(*p);
if (*p != '\0')
ND_TCHECK(*bp);
if (*bp != '\0')
ND_PRINT((ndo, " "));
ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
p += ui;
bp += ui;
length -= ui;
}
break;
case OACK:
p = (const u_char *)tp->th_stuff;
/* Print options */
while (length != 0) {
ND_TCHECK(*p);
if (*p != '\0')
ND_TCHECK(*bp);
if (*bp != '\0')
ND_PRINT((ndo, " "));
ui = fn_printztn(ndo, p, length, ndo->ndo_snapend);
ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
if (ui == 0)
goto trunc;
p += ui;
bp += ui;
length -= ui;
}
break;
@ -188,23 +168,24 @@ tftp_print(netdissect_options *ndo,
case DATA:
if (length < 2)
goto trunc; /* no block number */
ND_TCHECK(tp->th_block);
ND_PRINT((ndo, " block %d", EXTRACT_16BITS(&tp->th_block)));
ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " block %d", EXTRACT_16BITS(bp)));
break;
case TFTP_ERROR:
/* Print error code string */
if (length < 2)
goto trunc; /* no error code */
ND_TCHECK(tp->th_code);
ND_TCHECK_16BITS(bp);
ND_PRINT((ndo, " %s", tok2str(err2str, "tftp-err-#%d \"",
EXTRACT_16BITS(&tp->th_code))));
EXTRACT_16BITS(bp))));
bp += 2;
length -= 2;
/* Print error message string */
if (length == 0)
goto trunc; /* no error message */
ND_PRINT((ndo, " \""));
ui = fn_printztn(ndo, (const u_char *)tp->th_data, length, ndo->ndo_snapend);
ui = fn_printztn(ndo, bp, length, ndo->ndo_snapend);
ND_PRINT((ndo, "\""));
if (ui == 0)
goto trunc;

View File

@ -26,6 +26,7 @@
#include "netdissect.h"
#include "extract.h"
#include "addrtoname.h"
#include "ether.h"
#define VQP_VERSION 1
#define VQP_EXTRACT_VERSION(x) ((x)&0xFF)
@ -105,13 +106,15 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
const u_char *tptr;
uint16_t vqp_obj_len;
uint32_t vqp_obj_type;
int tlen;
u_int tlen;
uint8_t nitems;
tptr=pptr;
tlen = len;
vqp_common_header = (const struct vqp_common_header_t *)pptr;
ND_TCHECK(*vqp_common_header);
if (sizeof(struct vqp_common_header_t) > tlen)
goto trunc;
/*
* Sanity checking of the header.
@ -151,6 +154,9 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
while (nitems > 0 && tlen > 0) {
vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
ND_TCHECK(*vqp_obj_tlv);
if (sizeof(struct vqp_obj_tlv_t) > tlen)
goto trunc;
vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
tptr+=sizeof(struct vqp_obj_tlv_t);
@ -167,9 +173,13 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
/* did we capture enough for fully decoding the object ? */
ND_TCHECK2(*tptr, vqp_obj_len);
if (vqp_obj_len > tlen)
goto trunc;
switch(vqp_obj_type) {
case VQP_OBJ_IP_ADDRESS:
if (vqp_obj_len != 4)
goto trunc;
ND_PRINT((ndo, "%s (0x%08x)", ipaddr_string(ndo, tptr), EXTRACT_32BITS(tptr)));
break;
/* those objects have similar semantics - fall through */
@ -182,6 +192,8 @@ vqp_print(netdissect_options *ndo, register const u_char *pptr, register u_int l
/* those objects have similar semantics - fall through */
case VQP_OBJ_MAC_ADDRESS:
case VQP_OBJ_MAC_NULL:
if (vqp_obj_len != ETHER_ADDR_LEN)
goto trunc;
ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr)));
break;
default:

View File

@ -13,9 +13,8 @@
* FOR A PARTICULAR PURPOSE.
*
* Reference documentation:
* http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml
* http://www.cisco.com/warp/public/473/21.html
* http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
* http://www.cisco.com/c/en/us/support/docs/lan-switching/vtp/10558-21.html
* http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
*
* Original code ode by Carles Kishimoto <carles.kishimoto@gmail.com>
*/
@ -36,7 +35,7 @@
#define VTP_DOMAIN_NAME_LEN 32
#define VTP_MD5_DIGEST_LEN 16
#define VTP_UPDATE_TIMESTAMP_LEN 12
#define VTP_VLAN_INFO_OFFSET 12
#define VTP_VLAN_INFO_FIXED_PART_LEN 12 /* length of VLAN info before VLAN name */
#define VTP_SUMMARY_ADV 0x01
#define VTP_SUBSET_ADV 0x02
@ -223,6 +222,7 @@ vtp_print (netdissect_options *ndo,
*
*/
ND_TCHECK_32BITS(tptr);
ND_PRINT((ndo, ", Config Rev %x", EXTRACT_32BITS(tptr)));
/*
@ -243,6 +243,7 @@ vtp_print (netdissect_options *ndo,
tptr += 4;
while (tptr < (pptr+length)) {
ND_TCHECK_8BITS(tptr);
len = *tptr;
if (len == 0)
break;
@ -250,6 +251,8 @@ vtp_print (netdissect_options *ndo,
ND_TCHECK2(*tptr, len);
vtp_vlan = (const struct vtp_vlan_*)tptr;
if (len < VTP_VLAN_INFO_FIXED_PART_LEN)
goto trunc;
ND_TCHECK(*vtp_vlan);
ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ",
tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status),
@ -257,22 +260,33 @@ vtp_print (netdissect_options *ndo,
EXTRACT_16BITS(&vtp_vlan->vlanid),
EXTRACT_16BITS(&vtp_vlan->mtu),
EXTRACT_32BITS(&vtp_vlan->index)));
fn_printzp(ndo, tptr + VTP_VLAN_INFO_OFFSET, vtp_vlan->name_len, NULL);
len -= VTP_VLAN_INFO_FIXED_PART_LEN;
tptr += VTP_VLAN_INFO_FIXED_PART_LEN;
if (len < 4*((vtp_vlan->name_len + 3)/4))
goto trunc;
ND_TCHECK2(*tptr, vtp_vlan->name_len);
fn_printzp(ndo, tptr, vtp_vlan->name_len, NULL);
/*
* Vlan names are aligned to 32-bit boundaries.
*/
len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
/*
* Vlan names are aligned to 32-bit boundaries.
*/
len -= 4*((vtp_vlan->name_len + 3)/4);
tptr += 4*((vtp_vlan->name_len + 3)/4);
/* TLV information follows */
while (len > 0) {
/*
* Cisco specs says 2 bytes for type + 2 bytes for length, take only 1
* See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
* Cisco specs say 2 bytes for type + 2 bytes for length;
* see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
* However, actual packets on the wire appear to use 1
* byte for the type and 1 byte for the length, so that's
* what we do.
*/
if (len < 2)
goto trunc;
ND_TCHECK2(*tptr, 2);
type = *tptr;
tlv_len = *(tptr+1);
@ -280,59 +294,65 @@ vtp_print (netdissect_options *ndo,
tok2str(vtp_vlan_tlv_values, "Unknown", type),
type));
/*
* infinite loop check
*/
if (type == 0 || tlv_len == 0) {
if (len < tlv_len * 2 + 2) {
ND_PRINT((ndo, " (TLV goes past the end of the packet)"));
return;
}
ND_TCHECK2(*tptr, tlv_len * 2 +2);
tlv_value = EXTRACT_16BITS(tptr+2);
/*
* We assume the value is a 2-byte integer; the length is
* in units of 16-bit words.
*/
if (tlv_len != 1) {
ND_PRINT((ndo, " (invalid TLV length %u != 1)", tlv_len));
return;
} else {
tlv_value = EXTRACT_16BITS(tptr+2);
switch (type) {
case VTP_VLAN_STE_HOP_COUNT:
ND_PRINT((ndo, ", %u", tlv_value));
break;
switch (type) {
case VTP_VLAN_STE_HOP_COUNT:
ND_PRINT((ndo, ", %u", tlv_value));
break;
case VTP_VLAN_PRUNING:
ND_PRINT((ndo, ", %s (%u)",
tlv_value == 1 ? "Enabled" : "Disabled",
tlv_value));
break;
case VTP_VLAN_PRUNING:
ND_PRINT((ndo, ", %s (%u)",
tlv_value == 1 ? "Enabled" : "Disabled",
tlv_value));
break;
case VTP_VLAN_STP_TYPE:
ND_PRINT((ndo, ", %s (%u)",
tok2str(vtp_stp_type_values, "Unknown", tlv_value),
tlv_value));
break;
case VTP_VLAN_STP_TYPE:
ND_PRINT((ndo, ", %s (%u)",
tok2str(vtp_stp_type_values, "Unknown", tlv_value),
tlv_value));
break;
case VTP_VLAN_BRIDGE_TYPE:
ND_PRINT((ndo, ", %s (%u)",
tlv_value == 1 ? "SRB" : "SRT",
tlv_value));
break;
case VTP_VLAN_BRIDGE_TYPE:
ND_PRINT((ndo, ", %s (%u)",
tlv_value == 1 ? "SRB" : "SRT",
tlv_value));
break;
case VTP_VLAN_BACKUP_CRF_MODE:
ND_PRINT((ndo, ", %s (%u)",
tlv_value == 1 ? "Backup" : "Not backup",
tlv_value));
break;
case VTP_VLAN_BACKUP_CRF_MODE:
ND_PRINT((ndo, ", %s (%u)",
tlv_value == 1 ? "Backup" : "Not backup",
tlv_value));
break;
/*
* FIXME those are the defined TLVs that lack a decoder
* you are welcome to contribute code ;-)
*/
/*
* FIXME those are the defined TLVs that lack a decoder
* you are welcome to contribute code ;-)
*/
case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
case VTP_VLAN_PARENT_VLAN:
case VTP_VLAN_TRANS_BRIDGED_VLAN:
case VTP_VLAN_ARP_HOP_COUNT:
default:
print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2);
break;
case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
case VTP_VLAN_PARENT_VLAN:
case VTP_VLAN_TRANS_BRIDGED_VLAN:
case VTP_VLAN_ARP_HOP_COUNT:
default:
print_unknown_data(ndo, tptr, "\n\t\t ", 2 + tlv_len*2);
break;
}
}
len -= 2 + tlv_len*2;
tptr += 2 + tlv_len*2;

View File

@ -263,9 +263,8 @@ wb_prep(netdissect_options *ndo,
const u_char *ep = ndo->ndo_snapend;
ND_PRINT((ndo, " wb-prep:"));
if (len < sizeof(*prep)) {
if (len < sizeof(*prep) || !ND_TTEST(*prep))
return (-1);
}
n = EXTRACT_32BITS(&prep->pp_n);
ps = (const struct pgstate *)(prep + 1);
while (--n >= 0 && ND_TTEST(*ps)) {
@ -419,31 +418,37 @@ wb_print(netdissect_options *ndo,
case PT_ID:
if (wb_id(ndo, (const struct pkt_id *)(ph + 1), len) >= 0)
return;
ND_PRINT((ndo, "%s", tstr));
break;
case PT_RREQ:
if (wb_rreq(ndo, (const struct pkt_rreq *)(ph + 1), len) >= 0)
return;
ND_PRINT((ndo, "%s", tstr));
break;
case PT_RREP:
if (wb_rrep(ndo, (const struct pkt_rrep *)(ph + 1), len) >= 0)
return;
ND_PRINT((ndo, "%s", tstr));
break;
case PT_DRAWOP:
if (wb_drawop(ndo, (const struct pkt_dop *)(ph + 1), len) >= 0)
return;
ND_PRINT((ndo, "%s", tstr));
break;
case PT_PREQ:
if (wb_preq(ndo, (const struct pkt_preq *)(ph + 1), len) >= 0)
return;
ND_PRINT((ndo, "%s", tstr));
break;
case PT_PREP:
if (wb_prep(ndo, (const struct pkt_prep *)(ph + 1), len) >= 0)
return;
ND_PRINT((ndo, "%s", tstr));
break;
default:

View File

@ -76,30 +76,41 @@ static const struct tok z_types[] = {
{ Z_PACKET_SERVACK, "serv-ack" },
{ Z_PACKET_SERVNAK, "serv-nak" },
{ Z_PACKET_CLIENTACK, "client-ack" },
{ Z_PACKET_STAT, "stat" }
{ Z_PACKET_STAT, "stat" },
{ 0, NULL }
};
static char z_buf[256];
static const char *
parse_field(netdissect_options *ndo, const char **pptr, int *len)
parse_field(netdissect_options *ndo, const char **pptr, int *len, int *truncated)
{
const char *s;
if (*len <= 0 || !pptr || !*pptr)
return NULL;
if (*pptr > (const char *) ndo->ndo_snapend)
return NULL;
/* Start of string */
s = *pptr;
while (*pptr <= (const char *) ndo->ndo_snapend && *len >= 0 && **pptr) {
/* Scan for the NUL terminator */
for (;;) {
if (*len == 0) {
/* Ran out of packet data without finding it */
return NULL;
}
if (!ND_TTEST(**pptr)) {
/* Ran out of captured data without finding it */
*truncated = 1;
return NULL;
}
if (**pptr == '\0') {
/* Found it */
break;
}
/* Keep scanning */
(*pptr)++;
(*len)--;
}
/* Skip the NUL terminator */
(*pptr)++;
(*len)--;
if (*len < 0 || *pptr > (const char *) ndo->ndo_snapend)
return NULL;
return s;
}
@ -138,6 +149,7 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
int parselen = length;
const char *s;
int lose = 0;
int truncated = 0;
/* squelch compiler warnings */
@ -148,8 +160,9 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
z.sender = 0;
z.recipient = 0;
#define PARSE_STRING \
s = parse_field(ndo, &parse, &parselen); \
#define PARSE_STRING \
s = parse_field(ndo, &parse, &parselen, &truncated); \
if (truncated) goto trunc; \
if (!s) lose = 1;
#define PARSE_FIELD_INT(field) \
@ -182,10 +195,8 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
PARSE_FIELD_INT(z.multi);
PARSE_FIELD_STR(z.multi_uid);
if (lose) {
ND_PRINT((ndo, " [|zephyr] (%d)", length));
return;
}
if (lose)
goto trunc;
ND_PRINT((ndo, " zephyr"));
if (strncmp(z.version+4, "0.2", 3)) {
@ -317,4 +328,9 @@ zephyr_print(netdissect_options *ndo, const u_char *cp, int length)
ND_PRINT((ndo, " to %s", z_triple(z.class, z.inst, z.recipient)));
if (*z.opcode)
ND_PRINT((ndo, " op %s", z.opcode));
return;
trunc:
ND_PRINT((ndo, " [|zephyr] (%d)", length));
return;
}

Some files were not shown because too many files have changed in this diff Show More