-
Notifications
You must be signed in to change notification settings - Fork 861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GUE dissection support #510
Changes from all commits
aa99b21
9a250f4
c99861a
2609889
aaab44b
4c0dac4
a239795
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/* $OpenBSD: print-gue.c */ | ||
|
||
/* | ||
* Copyright (c) 2016 Google | ||
* Author: Wilmer van der Gaast ([email protected]) | ||
* 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 Jason L. Wright | ||
* 4. The name of the author may not be used to endorse or promote products | ||
* derived from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. | ||
*/ | ||
|
||
/* | ||
* netdissect printer for GUE - Generic UDP Encapsulation | ||
* Currently described in: | ||
* https://tools.ietf.org/html/draft-ietf-nvo3-gue-02#section-2.2 | ||
*/ | ||
|
||
#ifdef HAVE_CONFIG_H | ||
#include <config.h> | ||
#endif | ||
|
||
#include "netdissect-stdinc.h" | ||
|
||
#include <string.h> | ||
|
||
#include "netdissect.h" | ||
#include "addrtostr.h" | ||
#include "extract.h" | ||
#include "ipproto.h" | ||
|
||
static const char tstr[] = "[|gue]"; | ||
|
||
/* These macros operate on the first 16-bit word of a GUE packet. */ | ||
#define GUE_VERS(bits) ((bits & 0xc000) >> 14) | ||
#define GUE_CONTROL(bits) (bits & 0x400) | ||
#define GUE_HLEN(bits) ((bits & 0x1f00) >> 8) | ||
#define GUE_PROTO(bits) (bits & 0xff) | ||
#define GUE_CTYPE(bits) (bits & 0xff) | ||
|
||
static void gue_print_0(netdissect_options *, const u_char *, u_int); | ||
|
||
void | ||
gue_print(netdissect_options *ndo, const u_char *bp, u_int length) | ||
{ | ||
u_int len = length, vers; | ||
|
||
ndo->ndo_protocol = "gue"; | ||
if (len < 2) { | ||
ND_PRINT("%s", tstr); | ||
return; | ||
} | ||
vers = GUE_VERS(EXTRACT_BE_U_2(bp)); | ||
ND_PRINT("GUEv%u", vers); | ||
|
||
switch(vers) { | ||
case 0: | ||
gue_print_0(ndo, bp, len); | ||
break; | ||
default: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you like to add support for version 0x1? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll need some dumps to do so, I don't have any so far which makes writing (and testing) that a little bit hard. Will update this PR once that (and the other changes) are done. |
||
ND_PRINT("%s", " (unknown)"); | ||
break; | ||
} | ||
return; | ||
} | ||
|
||
static void | ||
gue_print_0(netdissect_options *ndo, const u_char *bp, u_int length) | ||
{ | ||
u_int len = length; | ||
uint16_t flags, prot; | ||
u_int hlen; | ||
|
||
/* Boundary checking done above */ | ||
flags = EXTRACT_BE_U_2(bp); | ||
if (GUE_CONTROL(flags)) { | ||
ND_PRINT(", control packet %02x", GUE_CTYPE(flags)); | ||
prot = 0; | ||
} else { | ||
prot = GUE_PROTO(flags); | ||
} | ||
|
||
/* Length of additional headers */ | ||
hlen = GUE_HLEN(flags); | ||
hlen *= 4; | ||
|
||
len -= 2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it for sure len > 2 before this point? -- OK, I see it now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Happy to add another check for cleanliness if it helps. I don't like writing "secure only by pure luck" code :-) |
||
bp += 2; | ||
|
||
if (len < 2) | ||
goto trunc; | ||
flags = EXTRACT_BE_U_2(bp); | ||
|
||
if (flags) { | ||
ND_PRINT(", flags %04x", flags); | ||
} | ||
|
||
/* (E)FLAGS field */ | ||
len -= 2; | ||
bp += 2; | ||
|
||
if (len < hlen) | ||
goto trunc; | ||
|
||
len -= hlen; | ||
bp += hlen; | ||
|
||
if (prot == 0) { | ||
/* Control packet, nothing else to show. */ | ||
return; | ||
} | ||
|
||
if (ndo->ndo_vflag < 1) | ||
ND_PRINT(": "); /* put in a colon as protocol demarc */ | ||
else | ||
ND_PRINT("\n\t"); /* if verbose go multiline */ | ||
|
||
switch (prot) { | ||
case IPPROTO_IPV4: | ||
/* ip_print() reads some fields before checking length. */ | ||
if (len < sizeof(struct ip)) | ||
goto trunc; | ||
|
||
ip_print(ndo, bp, len); | ||
break; | ||
case IPPROTO_IPV6: | ||
ip6_print(ndo, bp, len); | ||
break; | ||
case IPPROTO_NONE: | ||
ND_PRINT("gue-fragment"); | ||
break; | ||
default: | ||
ND_PRINT("gue-proto-0x%02x", prot); | ||
} | ||
|
||
return; | ||
|
||
trunc: | ||
ND_PRINT("%s", tstr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -695,6 +695,8 @@ udp_print(netdissect_options *ndo, const u_char *bp, u_int length, | |
lisp_print(ndo, (const u_char *)(up + 1), length); | ||
else if (IS_SRC_OR_DST_PORT(VXLAN_GPE_PORT)) | ||
vxlan_gpe_print(ndo, (const u_char *)(up + 1), length); | ||
else if (dport == GUE_PORT) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems from the spec that the reponse from the middlebox to the faraway host would have UDP ports the other way round (from GUE_PORT to any other port), should it be accounted here as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hrm, I'll have to look more closely for that, I forgot about that case. Could that be metadata/OOB-only with no actual IP payload inside? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure which kind of packet exactly but generally packets in tunnels tend to go both ways. Unless, of course, in this protocol the return traffic uses a completely unrelated source and destination ports. I did not study the spec so well. |
||
gue_print(ndo, (const u_char *)(up + 1), length); | ||
else if (ND_TTEST_1(((const struct LAP *)cp)->type) && | ||
EXTRACT_U_1(((const struct LAP *)cp)->type) == lapDDP && | ||
(atalk_port(sport) || atalk_port(dport))) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
1457025435.738116 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 29) | ||
127.0.0.2.9 > 127.0.0.1.6080: [|gue] | ||
1457025435.738135 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 30) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0[|gue] | ||
1457025435.738140 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 32) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
[|gue] | ||
1457025435.738144 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 36) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
[|gue] | ||
1457025435.738148 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 44) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
[|gue] | ||
1457025435.738160 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 60) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP truncated-ip - 100 bytes missing! (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 128, bad cksum 944a (->78fd)!) | ||
10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738165 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 92) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP truncated-ip - 68 bytes missing! (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 128, bad cksum 944a (->78fd)!) | ||
10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738169 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 156) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP truncated-ip - 4 bytes missing! (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 128, bad cksum 944a (->78fd)!) | ||
10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738174 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 160) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 128, bad cksum 944a (->78fd)!) | ||
10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738178 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 160) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 128, bad cksum 944a (->78fd)!) | ||
10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025437.917296 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 29) | ||
127.0.0.2.9 > 127.0.0.1.6080: [|gue] | ||
1457025437.917320 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 30) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0[|gue] | ||
1457025437.917326 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 32) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
[|ip6] | ||
1457025437.917330 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 36) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
[|ip6] | ||
1457025437.917335 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 44) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
[|ip6] | ||
1457025437.917339 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 60) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
[|ip6] | ||
1457025437.917344 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 92) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP6 truncated-ip6 - 88 bytes missing!(hlim 8, next-header UDP (17) payload length: 108) 2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: UDP, length 100 | ||
1457025437.917348 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 156) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP6 truncated-ip6 - 24 bytes missing!(hlim 8, next-header UDP (17) payload length: 108) 2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: UDP, length 100 | ||
1457025437.917353 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 180) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP6 (hlim 8, next-header UDP (17) payload length: 108) 2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: [udp sum ok] UDP, length 100 | ||
1457025437.917358 IP (tos 0x0, ttl 8, id 1337, offset 0, flags [none], proto UDP (17), length 180) | ||
127.0.0.2.9 > 127.0.0.1.6080: GUEv0 | ||
IP6 (hlim 8, next-header UDP (17) payload length: 108) 2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: [udp sum ok] UDP, length 100 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
1457025435.738116 IP 127.0.0.2.9 > 127.0.0.1.6080: [|gue] | ||
1457025435.738135 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0[|gue] | ||
1457025435.738140 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: [|gue] | ||
1457025435.738144 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: [|gue] | ||
1457025435.738148 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: [|gue] | ||
1457025435.738160 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP truncated-ip - 100 bytes missing! 10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738165 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP truncated-ip - 68 bytes missing! 10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738169 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP truncated-ip - 4 bytes missing! 10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738174 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP 10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025435.738178 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP 10.11.12.13.9 > 14.15.16.17.8000: UDP, length 100 | ||
1457025437.917296 IP 127.0.0.2.9 > 127.0.0.1.6080: [|gue] | ||
1457025437.917320 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0[|gue] | ||
1457025437.917326 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: [|ip6] | ||
1457025437.917330 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: [|ip6] | ||
1457025437.917335 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: [|ip6] | ||
1457025437.917339 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: [|ip6] | ||
1457025437.917344 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP6 truncated-ip6 - 88 bytes missing!2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: UDP, length 100 | ||
1457025437.917348 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP6 truncated-ip6 - 24 bytes missing!2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: UDP, length 100 | ||
1457025437.917353 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP6 2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: UDP, length 100 | ||
1457025437.917358 IP 127.0.0.2.9 > 127.0.0.1.6080: GUEv0: IP6 2001:2::a:7c:6e:f3.9 > 2001:2::a:7c:6e:c.8000: UDP, length 100 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revision 03 of the Internet-Draft has been published.