/* Copyright (c) 2015, bugyo
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
*/
/* Make sure we have all the headers */
if (len < length * NSH_HDR_WORD_SIZE) {
ND_PRINT(" (too many headers for packet length %u)", len);
goto invalid;
}
/*
* length includes the lengths of the Base and Service Path headers.
* That means it must be at least 2.
*/
if (length < 2) {
ND_PRINT(" (less than two headers)");
goto invalid;
}
/*
* Print, or skip, the Context Headers.
* (length - 2) is the length of those headers.
*/
if (ndo->ndo_vflag > 2) {
u_int n;
if (md_type == MD_TYPE1) {
if (length != 6) {
ND_PRINT(" (length for the MD type)");
goto invalid;
}
for (n = 0; n < length - 2; n++) {
ND_PRINT("\n Context[%02u]: 0x%08x", n, GET_BE_U_4(bp));
bp += NSH_HDR_WORD_SIZE;
}
past_headers = 1;
} else if (md_type == MD_TYPE2) {
n = 0;
while (n < length - 2) {
uint16_t tlv_class;
uint8_t tlv_type, tlv_len, tlv_len_padded;
tlv_class = GET_BE_U_2(bp);
bp += 2;
tlv_type = GET_U_1(bp);
bp += 1;
tlv_len = GET_U_1(bp) & 0x7f;
bp += 1;
tlv_len_padded = roundup2(tlv_len, NSH_HDR_WORD_SIZE);
ND_PRINT("\n TLV Class %u, Type %u, Len %u",
tlv_class, tlv_type, tlv_len);
n += 1;
if (length - 2 < n + tlv_len_padded / NSH_HDR_WORD_SIZE) {
ND_PRINT(" (length too big)");
goto invalid;
}