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:
commit
0bff6a5af8
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -263,6 +263,7 @@ HDR = \
|
||||
ether.h \
|
||||
ethertype.h \
|
||||
extract.h \
|
||||
funcattrs.h \
|
||||
getopt_long.h \
|
||||
gmpls.h \
|
||||
gmt2local.h \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
4.9.0
|
||||
4.9.2
|
||||
|
@ -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 *
|
||||
|
@ -33,7 +33,8 @@ enum {
|
||||
LINKADDR_ETHER,
|
||||
LINKADDR_FRELAY,
|
||||
LINKADDR_IEEE1394,
|
||||
LINKADDR_ATM
|
||||
LINKADDR_ATM,
|
||||
LINKADDR_OTHER
|
||||
};
|
||||
|
||||
#define BUFSIZE 128
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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[];
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
27
contrib/tcpdump/configure
vendored
27
contrib/tcpdump/configure
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
122
contrib/tcpdump/funcattrs.h
Normal 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 */
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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[];
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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[];
|
||||
|
@ -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
|
||||
|
@ -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[];
|
||||
|
@ -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;
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)"));
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)));
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)",
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
*/
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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},
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)" : ""));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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,
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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) ||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user