xref: /aosp_15_r20/external/tcpdump/print-geonet.c (revision 05b00f6010a2396e3db2409989fc67270046269f)
1*05b00f60SXin Li /*
2*05b00f60SXin Li  * Copyright (c) 2013 The TCPDUMP project
3*05b00f60SXin Li  *
4*05b00f60SXin Li  * Redistribution and use in source and binary forms, with or without
5*05b00f60SXin Li  * modification, are permitted provided that: (1) source code
6*05b00f60SXin Li  * distributions retain the above copyright notice and this paragraph
7*05b00f60SXin Li  * in its entirety, and (2) distributions including binary code include
8*05b00f60SXin Li  * the above copyright notice and this paragraph in its entirety in
9*05b00f60SXin Li  * the documentation or other materials provided with the distribution.
10*05b00f60SXin Li  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11*05b00f60SXin Li  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12*05b00f60SXin Li  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13*05b00f60SXin Li  * FOR A PARTICULAR PURPOSE.
14*05b00f60SXin Li  *
15*05b00f60SXin Li  * Original code by Ola Martin Lykkja ([email protected])
16*05b00f60SXin Li  */
17*05b00f60SXin Li 
18*05b00f60SXin Li /* \summary: ISO CALM FAST and ETSI GeoNetworking printer */
19*05b00f60SXin Li 
20*05b00f60SXin Li #ifdef HAVE_CONFIG_H
21*05b00f60SXin Li #include <config.h>
22*05b00f60SXin Li #endif
23*05b00f60SXin Li 
24*05b00f60SXin Li #include "netdissect-stdinc.h"
25*05b00f60SXin Li 
26*05b00f60SXin Li #define ND_LONGJMP_FROM_TCHECK
27*05b00f60SXin Li #include "netdissect.h"
28*05b00f60SXin Li #include "extract.h"
29*05b00f60SXin Li #include "addrtoname.h"
30*05b00f60SXin Li 
31*05b00f60SXin Li 
32*05b00f60SXin Li /*
33*05b00f60SXin Li    ETSI TS 102 636-5-1 V1.1.1 (2011-02)
34*05b00f60SXin Li    Intelligent Transport Systems (ITS); Vehicular Communications; GeoNetworking;
35*05b00f60SXin Li    Part 5: Transport Protocols; Sub-part 1: Basic Transport Protocol
36*05b00f60SXin Li 
37*05b00f60SXin Li    ETSI TS 102 636-4-1 V1.1.1 (2011-06)
38*05b00f60SXin Li    Intelligent Transport Systems (ITS); Vehicular communications; GeoNetworking;
39*05b00f60SXin Li    Part 4: Geographical addressing and forwarding for point-to-point and point-to-multipoint communications;
40*05b00f60SXin Li    Sub-part 1: Media-Independent Functionality
41*05b00f60SXin Li */
42*05b00f60SXin Li 
43*05b00f60SXin Li #define GEONET_ADDR_LEN 8
44*05b00f60SXin Li 
45*05b00f60SXin Li static const struct tok msg_type_values[] = {
46*05b00f60SXin Li 	{   0, "CAM" },
47*05b00f60SXin Li 	{   1, "DENM" },
48*05b00f60SXin Li 	{ 101, "TPEGM" },
49*05b00f60SXin Li 	{ 102, "TSPDM" },
50*05b00f60SXin Li 	{ 103, "VPM" },
51*05b00f60SXin Li 	{ 104, "SRM" },
52*05b00f60SXin Li 	{ 105, "SLAM" },
53*05b00f60SXin Li 	{ 106, "ecoCAM" },
54*05b00f60SXin Li 	{ 107, "ITM" },
55*05b00f60SXin Li 	{ 150, "SA" },
56*05b00f60SXin Li 	{   0, NULL }
57*05b00f60SXin Li };
58*05b00f60SXin Li 
59*05b00f60SXin Li static void
print_btp_body(netdissect_options * ndo,const u_char * bp)60*05b00f60SXin Li print_btp_body(netdissect_options *ndo,
61*05b00f60SXin Li 	       const u_char *bp)
62*05b00f60SXin Li {
63*05b00f60SXin Li 	u_int msg_type;
64*05b00f60SXin Li 
65*05b00f60SXin Li 	/* Assuming ItsPduHeader */
66*05b00f60SXin Li 	ND_PRINT("; ItsPduHeader v:%u", GET_U_1(bp));
67*05b00f60SXin Li 
68*05b00f60SXin Li 	msg_type = GET_U_1(bp + 1);
69*05b00f60SXin Li 	ND_PRINT(" t:%u-%s", msg_type,
70*05b00f60SXin Li 	         tok2str(msg_type_values, "unknown (%u)", msg_type));
71*05b00f60SXin Li }
72*05b00f60SXin Li 
73*05b00f60SXin Li /* EN 302 636-5-1 V2.2.1 Section 7.2: BTP-A header */
74*05b00f60SXin Li static void
print_btp(netdissect_options * ndo,const u_char * bp)75*05b00f60SXin Li print_btp(netdissect_options *ndo,
76*05b00f60SXin Li 	  const u_char *bp)
77*05b00f60SXin Li {
78*05b00f60SXin Li 	ND_PRINT("; BTP Dst:%u", GET_BE_U_2(bp + 0));
79*05b00f60SXin Li 	ND_PRINT(" Src:%u", GET_BE_U_2(bp + 2));
80*05b00f60SXin Li }
81*05b00f60SXin Li 
82*05b00f60SXin Li static void
print_long_pos_vector(netdissect_options * ndo,const u_char * bp)83*05b00f60SXin Li print_long_pos_vector(netdissect_options *ndo,
84*05b00f60SXin Li 		      const u_char *bp)
85*05b00f60SXin Li {
86*05b00f60SXin Li 	ND_PRINT("GN_ADDR:%s ", GET_LINKADDR_STRING(bp, LINKADDR_OTHER, GEONET_ADDR_LEN));
87*05b00f60SXin Li 	ND_PRINT("lat:%u ", GET_BE_U_4(bp + 12));
88*05b00f60SXin Li 	ND_PRINT("lon:%u", GET_BE_U_4(bp + 16));
89*05b00f60SXin Li }
90*05b00f60SXin Li 
91*05b00f60SXin Li 
92*05b00f60SXin Li /*
93*05b00f60SXin Li  * This is the top level routine of the printer.  'p' points
94*05b00f60SXin Li  * to the geonet header of the packet.
95*05b00f60SXin Li  */
96*05b00f60SXin Li void
geonet_print(netdissect_options * ndo,const u_char * bp,u_int length,const struct lladdr_info * src)97*05b00f60SXin Li geonet_print(netdissect_options *ndo, const u_char *bp, u_int length,
98*05b00f60SXin Li 	     const struct lladdr_info *src)
99*05b00f60SXin Li {
100*05b00f60SXin Li 	u_int version;
101*05b00f60SXin Li 	u_int next_hdr;
102*05b00f60SXin Li 	u_int hdr_type;
103*05b00f60SXin Li 	u_int hdr_subtype;
104*05b00f60SXin Li 	uint16_t payload_length;
105*05b00f60SXin Li 	u_int hop_limit;
106*05b00f60SXin Li 	const char *next_hdr_txt = "Unknown";
107*05b00f60SXin Li 	const char *hdr_type_txt = "Unknown";
108*05b00f60SXin Li 	int hdr_size = -1;
109*05b00f60SXin Li 
110*05b00f60SXin Li 	ndo->ndo_protocol = "geonet";
111*05b00f60SXin Li 	ND_PRINT("GeoNet ");
112*05b00f60SXin Li 	if (src != NULL)
113*05b00f60SXin Li 		ND_PRINT("src:%s", (src->addr_string)(ndo, src->addr));
114*05b00f60SXin Li 	ND_PRINT("; ");
115*05b00f60SXin Li 
116*05b00f60SXin Li 	/* Process Common Header */
117*05b00f60SXin Li 	if (length < 36) {
118*05b00f60SXin Li 		ND_PRINT(" (common header length %u < 36)", length);
119*05b00f60SXin Li 		goto invalid;
120*05b00f60SXin Li 	}
121*05b00f60SXin Li 
122*05b00f60SXin Li 	version = GET_U_1(bp) >> 4;
123*05b00f60SXin Li 	next_hdr = GET_U_1(bp) & 0x0f;
124*05b00f60SXin Li 	hdr_type = GET_U_1(bp + 1) >> 4;
125*05b00f60SXin Li 	hdr_subtype = GET_U_1(bp + 1) & 0x0f;
126*05b00f60SXin Li 	payload_length = GET_BE_U_2(bp + 4);
127*05b00f60SXin Li 	hop_limit = GET_U_1(bp + 7);
128*05b00f60SXin Li 
129*05b00f60SXin Li 	switch (next_hdr) {
130*05b00f60SXin Li 		case 0: next_hdr_txt = "Any"; break;
131*05b00f60SXin Li 		case 1: next_hdr_txt = "BTP-A"; break;
132*05b00f60SXin Li 		case 2: next_hdr_txt = "BTP-B"; break;
133*05b00f60SXin Li 		case 3: next_hdr_txt = "IPv6"; break;
134*05b00f60SXin Li 	}
135*05b00f60SXin Li 
136*05b00f60SXin Li 	switch (hdr_type) {
137*05b00f60SXin Li 		case 0: hdr_type_txt = "Any"; break;
138*05b00f60SXin Li 		case 1: hdr_type_txt = "Beacon"; break;
139*05b00f60SXin Li 		case 2: hdr_type_txt = "GeoUnicast"; break;
140*05b00f60SXin Li 		case 3: switch (hdr_subtype) {
141*05b00f60SXin Li 				case 0: hdr_type_txt = "GeoAnycastCircle"; break;
142*05b00f60SXin Li 				case 1: hdr_type_txt = "GeoAnycastRect"; break;
143*05b00f60SXin Li 				case 2: hdr_type_txt = "GeoAnycastElipse"; break;
144*05b00f60SXin Li 			}
145*05b00f60SXin Li 			break;
146*05b00f60SXin Li 		case 4: switch (hdr_subtype) {
147*05b00f60SXin Li 				case 0: hdr_type_txt = "GeoBroadcastCircle"; break;
148*05b00f60SXin Li 				case 1: hdr_type_txt = "GeoBroadcastRect"; break;
149*05b00f60SXin Li 				case 2: hdr_type_txt = "GeoBroadcastElipse"; break;
150*05b00f60SXin Li 			}
151*05b00f60SXin Li 			break;
152*05b00f60SXin Li 		case 5: switch (hdr_subtype) {
153*05b00f60SXin Li 				case 0: hdr_type_txt = "TopoScopeBcast-SH"; break;
154*05b00f60SXin Li 				case 1: hdr_type_txt = "TopoScopeBcast-MH"; break;
155*05b00f60SXin Li 			}
156*05b00f60SXin Li 			break;
157*05b00f60SXin Li 		case 6: switch (hdr_subtype) {
158*05b00f60SXin Li 				case 0: hdr_type_txt = "LocService-Request"; break;
159*05b00f60SXin Li 				case 1: hdr_type_txt = "LocService-Reply"; break;
160*05b00f60SXin Li 			}
161*05b00f60SXin Li 			break;
162*05b00f60SXin Li 	}
163*05b00f60SXin Li 
164*05b00f60SXin Li 	ND_PRINT("v:%u ", version);
165*05b00f60SXin Li 	ND_PRINT("NH:%u-%s ", next_hdr, next_hdr_txt);
166*05b00f60SXin Li 	ND_PRINT("HT:%u-%u-%s ", hdr_type, hdr_subtype, hdr_type_txt);
167*05b00f60SXin Li 	ND_PRINT("HopLim:%u ", hop_limit);
168*05b00f60SXin Li 	ND_PRINT("Payload:%u ", payload_length);
169*05b00f60SXin Li 	print_long_pos_vector(ndo, bp + 8);
170*05b00f60SXin Li 
171*05b00f60SXin Li 	/* Skip Common Header */
172*05b00f60SXin Li 	ND_TCHECK_LEN(bp, 36);
173*05b00f60SXin Li 	length -= 36;
174*05b00f60SXin Li 	bp += 36;
175*05b00f60SXin Li 
176*05b00f60SXin Li 	/* Process Extended Headers */
177*05b00f60SXin Li 	switch (hdr_type) {
178*05b00f60SXin Li 		case 0: /* Any */
179*05b00f60SXin Li 			hdr_size = 0;
180*05b00f60SXin Li 			break;
181*05b00f60SXin Li 		case 1: /* Beacon */
182*05b00f60SXin Li 			hdr_size = 0;
183*05b00f60SXin Li 			break;
184*05b00f60SXin Li 		case 2: /* GeoUnicast */
185*05b00f60SXin Li 			break;
186*05b00f60SXin Li 		case 3: switch (hdr_subtype) {
187*05b00f60SXin Li 				case 0: /* GeoAnycastCircle */
188*05b00f60SXin Li 					break;
189*05b00f60SXin Li 				case 1: /* GeoAnycastRect */
190*05b00f60SXin Li 					break;
191*05b00f60SXin Li 				case 2: /* GeoAnycastElipse */
192*05b00f60SXin Li 					break;
193*05b00f60SXin Li 			}
194*05b00f60SXin Li 			break;
195*05b00f60SXin Li 		case 4: switch (hdr_subtype) {
196*05b00f60SXin Li 				case 0: /* GeoBroadcastCircle */
197*05b00f60SXin Li 					break;
198*05b00f60SXin Li 				case 1: /* GeoBroadcastRect */
199*05b00f60SXin Li 					break;
200*05b00f60SXin Li 				case 2: /* GeoBroadcastElipse */
201*05b00f60SXin Li 					break;
202*05b00f60SXin Li 			}
203*05b00f60SXin Li 			break;
204*05b00f60SXin Li 		case 5: switch (hdr_subtype) {
205*05b00f60SXin Li 				case 0: /* TopoScopeBcast-SH */
206*05b00f60SXin Li 					hdr_size = 0;
207*05b00f60SXin Li 					break;
208*05b00f60SXin Li 				case 1: /* TopoScopeBcast-MH */
209*05b00f60SXin Li 					hdr_size = 68 - 36;
210*05b00f60SXin Li 					break;
211*05b00f60SXin Li 			}
212*05b00f60SXin Li 			break;
213*05b00f60SXin Li 		case 6: switch (hdr_subtype) {
214*05b00f60SXin Li 				case 0: /* LocService-Request */
215*05b00f60SXin Li 					break;
216*05b00f60SXin Li 				case 1: /* LocService-Reply */
217*05b00f60SXin Li 					break;
218*05b00f60SXin Li 			}
219*05b00f60SXin Li 			break;
220*05b00f60SXin Li 	}
221*05b00f60SXin Li 
222*05b00f60SXin Li 	/* Skip Extended headers */
223*05b00f60SXin Li 	if (hdr_size >= 0) {
224*05b00f60SXin Li 		if (length < (u_int)hdr_size) {
225*05b00f60SXin Li 			ND_PRINT(" (header size %d > %u)", hdr_size, length);
226*05b00f60SXin Li 			goto invalid;
227*05b00f60SXin Li 		}
228*05b00f60SXin Li 		ND_TCHECK_LEN(bp, hdr_size);
229*05b00f60SXin Li 		length -= hdr_size;
230*05b00f60SXin Li 		bp += hdr_size;
231*05b00f60SXin Li 		switch (next_hdr) {
232*05b00f60SXin Li 			case 0: /* Any */
233*05b00f60SXin Li 				break;
234*05b00f60SXin Li 			case 1:
235*05b00f60SXin Li 			case 2: /* BTP A/B */
236*05b00f60SXin Li 				if (length < 4) {
237*05b00f60SXin Li 					ND_PRINT(" (BTP length %u < 4)", length);
238*05b00f60SXin Li 					goto invalid;
239*05b00f60SXin Li 				}
240*05b00f60SXin Li 				print_btp(ndo, bp);
241*05b00f60SXin Li 				length -= 4;
242*05b00f60SXin Li 				bp += 4;
243*05b00f60SXin Li 				if (length >= 2) {
244*05b00f60SXin Li 					/*
245*05b00f60SXin Li 					 * XXX - did print_btp_body()
246*05b00f60SXin Li 					 * return if length < 2
247*05b00f60SXin Li 					 * because this is optional,
248*05b00f60SXin Li 					 * or was that just not
249*05b00f60SXin Li 					 * reporting genuine errors?
250*05b00f60SXin Li 					 */
251*05b00f60SXin Li 					print_btp_body(ndo, bp);
252*05b00f60SXin Li 				}
253*05b00f60SXin Li 				break;
254*05b00f60SXin Li 			case 3: /* IPv6 */
255*05b00f60SXin Li 				break;
256*05b00f60SXin Li 		}
257*05b00f60SXin Li 	}
258*05b00f60SXin Li 
259*05b00f60SXin Li 	/* Print user data part */
260*05b00f60SXin Li 	if (ndo->ndo_vflag)
261*05b00f60SXin Li 		ND_DEFAULTPRINT(bp, length);
262*05b00f60SXin Li 	return;
263*05b00f60SXin Li 
264*05b00f60SXin Li invalid:
265*05b00f60SXin Li 	nd_print_invalid(ndo);
266*05b00f60SXin Li 	/* XXX - print the remaining data as hex? */
267*05b00f60SXin Li }
268