1 /* 2 * Copyright (c) 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Lawrence Berkeley Laboratory, 11 * Berkeley, CA. The name of the University may not be used to 12 * endorse or promote products derived from this software without 13 * specific prior written permission. 14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 * 18 * Initial contribution from John Hawkinson <jhawk@bbnplanet.com> 19 * 20 * This module implements support for decoding GRE (Generic Routing 21 * Encapsulation) tunnels; they're documented in RFC1701 and RFC1702. 22 * This code only supports the IP encapsulation thereof. 23 */ 24 25 #ifndef lint 26 static const char rcsid[] = 27 "@(#) $Header: print-gre.c,v 1.4 96/12/10 23:28:23 leres Exp $"; 28 #endif 29 30 #include <sys/param.h> 31 #include <sys/time.h> 32 #include <sys/uio.h> 33 #include <sys/socket.h> 34 35 #include <netinet/in.h> 36 #include <netinet/in_systm.h> 37 #include <netinet/ip.h> 38 39 #include <netdb.h> 40 #include <stdio.h> 41 42 #include "interface.h" 43 #include "addrtoname.h" 44 #include "extract.h" /* must come after interface.h */ 45 46 #define GRE_SIZE (20) 47 48 struct gre { 49 u_short flags; 50 u_short proto; 51 union { 52 struct gre_ckof { 53 u_short cksum; 54 u_short offset; 55 } gre_ckof; 56 u_int32_t key; 57 u_int32_t seq; 58 } gre_void1; 59 union { 60 u_int32_t key; 61 u_int32_t seq; 62 u_int32_t routing; 63 } gre_void2; 64 union { 65 u_int32_t seq; 66 u_int32_t routing; 67 } gre_void3; 68 union { 69 u_int32_t routing; 70 } gre_void4; 71 }; 72 73 #define GRE_CP 0x8000 /* Checksum Present */ 74 #define GRE_RP 0x4000 /* Routing Present */ 75 #define GRE_KP 0x2000 /* Key Present */ 76 #define GRE_SP 0x1000 /* Sequence Present */ 77 78 79 #define GREPROTO_IP 0x0800 80 81 82 /* 83 * Deencapsulate and print a GRE-tunneled IP datagram 84 */ 85 void 86 gre_print(const u_char *bp, u_int length) 87 { 88 const u_char *cp = bp + 4; 89 const struct gre *gre; 90 u_short flags, proto; 91 92 gre = (const struct gre *)bp; 93 94 if (length < GRE_SIZE) { 95 goto trunc; 96 } 97 flags = EXTRACT_16BITS(&gre->flags); 98 proto = EXTRACT_16BITS(&gre->proto); 99 100 if (vflag) { 101 /* Decode the flags */ 102 putchar('['); 103 if (flags & GRE_CP) 104 putchar('C'); 105 if (flags & GRE_RP) 106 putchar('R'); 107 if (flags & GRE_KP) 108 putchar('K'); 109 if (flags & GRE_SP) 110 putchar('S'); 111 fputs("] ", stdout); 112 } 113 /* Checksum & Offset are present */ 114 if ((flags & GRE_CP) | (flags & GRE_RP)) 115 cp += 4; 116 117 /* We don't support routing fields (variable length) now. Punt. */ 118 if (flags & GRE_RP) 119 return; 120 121 if (flags & GRE_KP) 122 cp += 4; 123 if (flags & GRE_SP) 124 cp += 4; 125 126 switch (proto) { 127 128 case GREPROTO_IP: 129 ip_print(cp, length - ((cp - bp) / sizeof(u_char))); 130 break; 131 132 default: 133 printf("gre-proto-0x%04X", proto); 134 break; 135 } 136 return; 137 138 trunc: 139 fputs("[|gre]", stdout); 140 141 } 142