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