12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*	$OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $	*/
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * All rights reserved.
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that the following conditions
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * are met:
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    documentation and/or other materials provided with the distribution.
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 3. All advertising materials mentioning features or use of this software
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    must display the following acknowledgement:
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	This product includes software developed by Jason L. Wright
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 4. The name of the author may not be used to endorse or promote products
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    derived from this software without specific prior written permission.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * POSSIBILITY OF SUCH DAMAGE.
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * tcpdump filter for GRE - Generic Routing Encapsulation
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * RFC1701 (GRE), RFC1702 (GRE IPv4), and RFC2637 (Enhanced GRE)
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef lint
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ =
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.28 2005/04/06 21:32:39 mcr Exp $ (LBL)";
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h"
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ip.h"
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ethertype.h"
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_CP		0x8000		/* checksum present */
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_RP		0x4000		/* routing present */
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_KP		0x2000		/* key present */
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_SP		0x1000		/* sequence# present */
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_sP		0x0800		/* source routing */
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_RECRS	0x0700		/* recursion count */
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_AP		0x0080		/* acknowledgment# present */
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct tok gre_flag_values[] = {
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { GRE_CP, "checksum present"},
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { GRE_RP, "routing present"},
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { GRE_KP, "key present"},
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { GRE_SP, "sequence# present"},
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { GRE_sP, "source routing present"},
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { GRE_RECRS, "recursion count"},
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { GRE_AP, "ack present"},
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRE_VERS_MASK	0x0007		/* protocol version */
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* source route entry types */
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRESRE_IP	0x0800		/* IP */
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define	GRESRE_ASN	0xfffe		/* ASN */
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid gre_print_0(const u_char *, u_int);
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid gre_print_1(const u_char *, u_int);
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid gre_sre_print(u_int16_t, u_int8_t, u_int8_t, const u_char *, u_int);
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid gre_sre_ip_print(u_int8_t, u_int8_t, const u_char *, u_int);
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid gre_sre_asn_print(u_int8_t, u_int8_t, const u_char *, u_int);
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgre_print(const u_char *bp, u_int length)
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int len = length, vers;
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len < 2) {
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("[|gre]");
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK;
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        printf("GREv%u",vers);
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        switch(vers) {
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case 0:
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            gre_print_0(bp, len);
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case 1:
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            gre_print_1(bp, len);
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(" ERROR: unknown-version");
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            break;
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgre_print_0(const u_char *bp, u_int length)
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int len = length;
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int16_t flags, prot;
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	flags = EXTRACT_16BITS(bp);
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (vflag)
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", Flags [%s]",
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   bittok2str(gre_flag_values,"none",flags));
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	len -= 2;
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	bp += 2;
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len < 2)
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		goto trunc;
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	prot = EXTRACT_16BITS(bp);
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	len -= 2;
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	bp += 2;
1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((flags & GRE_CP) | (flags & GRE_RP)) {
1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 2)
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag)
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", sum 0x%x", EXTRACT_16BITS(bp));
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 2;
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 2;
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 2)
1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", off 0x%x", EXTRACT_16BITS(bp));
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 2;
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 2;
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (flags & GRE_KP) {
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 4)
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", key=0x%x", EXTRACT_32BITS(bp));
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 4;
1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 4;
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (flags & GRE_SP) {
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 4)
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", seq %u", EXTRACT_32BITS(bp));
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 4;
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 4;
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (flags & GRE_RP) {
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		for (;;) {
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_int16_t af;
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_int8_t sreoff;
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			u_int8_t srelen;
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (len < 4)
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			af = EXTRACT_16BITS(bp);
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			sreoff = *(bp + 2);
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			srelen = *(bp + 3);
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			bp += 4;
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			len -= 4;
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (af == 0 && srelen == 0)
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				break;
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			gre_sre_print(af, sreoff, srelen, bp, len);
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (len < srelen)
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			bp += srelen;
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			len -= srelen;
1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (eflag)
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", proto %s (0x%04x)",
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   tok2str(ethertype_values,"unknown",prot),
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   prot);
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        printf(", length %u",length);
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (vflag < 1)
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(": "); /* put in a colon as protocol demarc */
2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        else
2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf("\n\t"); /* if verbose go multiline */
2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (prot) {
2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ETHERTYPE_IP:
2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	        ip_print(gndo, bp, len);
2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ETHERTYPE_IPV6:
2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ip6_print(bp, len);
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ETHERTYPE_MPLS:
2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		mpls_print(bp, len);
2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ETHERTYPE_IPX:
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ipx_print(bp, len);
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ETHERTYPE_ATALK:
2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		atalk_print(bp, len);
2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ETHERTYPE_GRE_ISO:
2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		isoclns_print(bp, len, len);
2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("gre-proto-0x%x", prot);
2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("[|gre]");
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
2362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgre_print_1(const u_char *bp, u_int length)
2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int len = length;
2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int16_t flags, prot;
2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	flags = EXTRACT_16BITS(bp);
2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	len -= 2;
2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	bp += 2;
2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (vflag)
2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", Flags [%s]",
2492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   bittok2str(gre_flag_values,"none",flags));
2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (len < 2)
2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		goto trunc;
2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	prot = EXTRACT_16BITS(bp);
2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	len -= 2;
2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	bp += 2;
2562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (flags & GRE_KP) {
2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		u_int32_t k;
2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 4)
2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
2632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		k = EXTRACT_32BITS(bp);
2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", call %d", k & 0xffff);
2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 4;
2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 4;
2672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (flags & GRE_SP) {
2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 4)
2712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", seq %u", EXTRACT_32BITS(bp));
2732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 4;
2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 4;
2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (flags & GRE_AP) {
2782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 4)
2792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
2802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", ack %u", EXTRACT_32BITS(bp));
2812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 4;
2822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 4;
2832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((flags & GRE_SP) == 0)
2862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", no-payload");
2872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (eflag)
2892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", proto %s (0x%04x)",
2902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   tok2str(ethertype_values,"unknown",prot),
2912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   prot);
2922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        printf(", length %u",length);
2942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if ((flags & GRE_SP) == 0)
2962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return;
2972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (vflag < 1)
2992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(": "); /* put in a colon as protocol demarc */
3002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        else
3012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf("\n\t"); /* if verbose go multiline */
3022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (prot) {
3042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case ETHERTYPE_PPP:
3052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                ppp_print(bp, len);
3062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
3082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("gre-proto-0x%x", prot);
3092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
3142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("[|gre]");
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgre_sre_print(u_int16_t af, u_int8_t sreoff, u_int8_t srelen,
3192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    const u_char *bp, u_int len)
3202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (af) {
3222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case GRESRE_IP:
3232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", (rtaf=ip");
3242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		gre_sre_ip_print(sreoff, srelen, bp, len);
3252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(") ");
3262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case GRESRE_ASN:
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", (rtaf=asn");
3292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		gre_sre_asn_print(sreoff, srelen, bp, len);
3302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(") ");
3312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
3332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", (rtaf=0x%x) ", af);
3342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
3372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgre_sre_ip_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len)
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct in_addr a;
3402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *up = bp;
3412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (sreoff & 3) {
3432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", badoffset=%u", sreoff);
3442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
3452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (srelen & 3) {
3472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", badlength=%u", srelen);
3482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
3492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (sreoff >= srelen) {
3512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", badoff/len=%u/%u", sreoff, srelen);
3522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
3532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	for (;;) {
3562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 4 || srelen == 0)
3572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			return;
3582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		memcpy(&a, bp, sizeof(a));
3602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" %s%s",
3612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    ((bp - up) == sreoff) ? "*" : "",
3622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    inet_ntoa(a));
3632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 4;
3652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 4;
3662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		srelen -= 4;
3672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
3712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgre_sre_asn_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len)
3722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *up = bp;
3742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (sreoff & 1) {
3762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", badoffset=%u", sreoff);
3772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
3782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (srelen & 1) {
3802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", badlength=%u", srelen);
3812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
3822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (sreoff >= srelen) {
3842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(", badoff/len=%u/%u", sreoff, srelen);
3852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
3862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	for (;;) {
3892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len < 2 || srelen == 0)
3902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			return;
3912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" %s%x",
3932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    ((bp - up) == sreoff) ? "*" : "",
3942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    EXTRACT_16BITS(bp));
3952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		bp += 2;
3972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len -= 2;
3982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		srelen -= 2;
3992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
4002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
401