* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/* \summary: Network Service Header (NSH) printer */
+
+/* specification: draft-ietf-sfc-nsh-01 */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define NSH_BASE_HDR_LEN 4
#define NSH_SERVICE_PATH_HDR_LEN 4
-#define NSH_HDR_WORD_SIZE 4
-
-/*
- * NSH, draft-ietf-sfc-nsh-01 Network Service Header
- */
+#define NSH_HDR_WORD_SIZE 4U
void
nsh_print(netdissect_options *ndo, const u_char *bp, u_int len)
if (len < NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN)
goto trunc;
- ND_TCHECK2(*bp, NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN);
+ ND_TCHECK_LEN(bp, NSH_BASE_HDR_LEN + NSH_SERVICE_PATH_HDR_LEN);
- ver = (uint8_t)(*bp >> 6);
- flags = *bp;
+ ver = (uint8_t)(EXTRACT_U_1(bp) >> 6);
+ flags = EXTRACT_U_1(bp);
bp += 1;
- length = *bp;
+ length = EXTRACT_U_1(bp);
bp += 1;
- md_type = *bp;
+ md_type = EXTRACT_U_1(bp);
bp += 1;
- next_protocol = *bp;
+ next_protocol = EXTRACT_U_1(bp);
bp += 1;
- service_path_id = EXTRACT_24BITS(bp);
+ service_path_id = EXTRACT_BE_U_3(bp);
bp += 3;
- service_index = *bp;
+ service_index = EXTRACT_U_1(bp);
bp += 1;
ND_PRINT((ndo, "NSH, "));
ND_PRINT((ndo, "service-path-id 0x%06x, ", service_path_id));
ND_PRINT((ndo, "service-index 0x%x", service_index));
- /* print Context Headers */
+ /* Make sure we have all the headers */
if (len < length * NSH_HDR_WORD_SIZE)
goto trunc;
- ND_TCHECK2(*bp, length * NSH_HDR_WORD_SIZE);
+ ND_TCHECK_LEN(bp, length * NSH_HDR_WORD_SIZE);
+
+ /*
+ * length includes the lengths of the Base and Service Path headers.
+ * That means it must be at least 2.
+ */
+ if (length < 2)
+ goto trunc;
+ /*
+ * Print, or skip, the Context Headers.
+ * (length - 2) is the length of those headers.
+ */
if (ndo->ndo_vflag > 2) {
if (md_type == 0x01) {
for (n = 0; n < length - 2; n++) {
- ctx = EXTRACT_32BITS(bp);
+ ctx = EXTRACT_BE_U_4(bp);
bp += NSH_HDR_WORD_SIZE;
ND_PRINT((ndo, "\n Context[%02d]: 0x%08x", n, ctx));
}
else if (md_type == 0x02) {
n = 0;
while (n < length - 2) {
- tlv_class = EXTRACT_16BITS(bp);
+ tlv_class = EXTRACT_BE_U_2(bp);
bp += 2;
- tlv_type = *bp;
+ tlv_type = EXTRACT_U_1(bp);
bp += 1;
- tlv_len = *bp;
+ tlv_len = EXTRACT_U_1(bp);
bp += 1;
ND_PRINT((ndo, "\n TLV Class %d, Type %d, Len %d",
}
for (vn = 0; vn < tlv_len; vn++) {
- ctx = EXTRACT_32BITS(bp);
+ ctx = EXTRACT_BE_U_4(bp);
bp += NSH_HDR_WORD_SIZE;
ND_PRINT((ndo, "\n Value[%02d]: 0x%08x", vn, ctx));
}
ip6_print(ndo, bp, next_len);
break;
case 0x3:
- ether_print(ndo, bp, next_len, next_len, NULL, NULL);
+ ether_print(ndo, bp, next_len, ndo->ndo_snapend - bp, NULL, NULL);
break;
default:
ND_PRINT((ndo, "ERROR: unknown-next-protocol"));