proto_ipv6_mobility_hdr.h: Headerfixing
[netsniff-ng.git] / src / proto_ipv6_mobility_hdr.h
blob3dac3ee60d0ac9b1ffbcff10716c3c698d10829e
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
4 * Subject to the GPL, version 2.
6 * IPv6 Mobility Header described in RFC6275
7 */
9 #ifndef PROTO_IPV6_MOBILITY_HDR_H
10 #define PROTO_IPV6_MOBILITY_HDR_H
12 #include <stdio.h>
13 #include <stdint.h>
14 #include <netinet/in.h> /* for ntohs() */
16 #include "proto_struct.h"
17 #include "dissector_eth.h"
18 #include "built_in.h"
20 #define BINDING_REFRESH_REQUEST_MESSAGE 0x00
21 #define HOME_TEST_INIT_MESSAGE 0x01
22 #define CARE_OF_TEST_INIT_MESSAGE 0x02
23 #define HOME_TEST_MESSAGE 0x03
24 #define CARE_OF_TEST_MESSAGE 0x04
25 #define BINDING_UPDATE_MESSAGE 0x05
26 #define BINDING_ACKNOWLEDGEMENT_MESSAGE 0x06
27 #define BINDING_ERROR_MESSAGE 0x07
30 struct mobilityhdr {
31 uint8_t payload_proto;
32 uint8_t hdr_len;
33 uint8_t MH_type;
34 uint8_t reserved;
35 uint16_t chksum;
36 uint8_t msgdata[0];
37 } __packed;
39 struct bin_refr_req_msg {
40 uint16_t reserved;
41 uint8_t mobility_opt[0];
42 } __packed;
44 /* for 0x01 and 0x02 */
45 struct tst_init_msg {
46 uint16_t reserved;
47 uint64_t init_cookie;
48 uint8_t mobility_opt[0];
49 } __packed;
51 /* for 0x03 and 0x04 */
52 struct tst_msg {
53 uint16_t nonce_index;
54 uint64_t init_cookie;
55 uint64_t keygen_token;
56 uint8_t mobility_opt[0];
57 } __packed;
59 struct bind_upd_msg {
60 uint16_t sequence;
61 uint16_t ahlk_res;
62 uint16_t lifetime;
63 uint8_t mobility_opt[0];
64 } __packed;
66 struct bind_ack_msg {
67 uint8_t status;
68 uint8_t k_res;
69 uint16_t sequence;
70 uint16_t lifetime;
71 uint8_t mobility_opt[0];
72 } __packed;
74 struct bind_err_msg {
75 uint8_t status;
76 uint8_t res;
77 uint64_t home_addr;
78 uint8_t mobility_opt[0];
79 } __packed;
82 static inline void jmp_to_mh_end(struct pkt_buff *pkt,
83 uint8_t *message_data_len)
85 pkt_pull(pkt, *message_data_len);
88 static inline void dissect_mobility_options(struct pkt_buff *pkt,
89 uint8_t *message_data_len)
91 /* Have to been upgraded.
92 * http://tools.ietf.org/html/rfc6275#section-6.2.1
94 if (*message_data_len)
95 tprintf("MH Option(s) recognized ");
98 static inline void dissect_mobilityhdr_type_0(struct pkt_buff *pkt,
99 uint8_t *message_data_len)
101 struct bin_refr_req_msg *type_0;
103 type_0 = (struct bin_refr_req_msg *) pkt_pull(pkt, sizeof(*type_0));
104 *message_data_len -= sizeof(*type_0);
105 if (type_0 == NULL || *message_data_len > pkt_len(pkt))
106 return;
109 dissect_mobility_options(pkt, message_data_len);
112 static inline void dissect_mobilityhdr_type_1_2(struct pkt_buff *pkt,
113 uint8_t *message_data_len)
115 struct tst_init_msg *type_1_2;
117 type_1_2 = (struct tst_init_msg *) pkt_pull(pkt, sizeof(*type_1_2));
118 *message_data_len -= sizeof(*type_1_2);
119 if (type_1_2 == NULL || *message_data_len > pkt_len(pkt))
120 return;
122 tprintf("Init Cookie (0x%x)", ntohll(type_1_2->init_cookie));
125 dissect_mobility_options(pkt, message_data_len);
128 static inline void dissect_mobilityhdr_type_3_4(struct pkt_buff *pkt,
129 uint8_t *message_data_len)
131 struct tst_msg *type_3_4;
133 type_3_4 = (struct tst_msg *) pkt_pull(pkt, sizeof(*type_3_4));
134 *message_data_len -= sizeof(*type_3_4);
135 if (type_3_4 == NULL || *message_data_len > pkt_len(pkt))
136 return;
138 tprintf("HN Index (%u) ", ntohs(type_3_4->nonce_index));
139 tprintf("Init Cookie (0x%x) ", ntohll(type_3_4->init_cookie));
140 tprintf("Keygen Token (0x%x)", ntohll(type_3_4->keygen_token));
143 dissect_mobility_options(pkt, message_data_len);
146 static inline void dissect_mobilityhdr_type_5(struct pkt_buff *pkt,
147 uint8_t *message_data_len)
149 struct bind_upd_msg *type_5;
151 type_5 = (struct bind_upd_msg *) pkt_pull(pkt, sizeof(*type_5));
152 *message_data_len -= sizeof(*type_5);
153 if (type_5 == NULL || *message_data_len > pkt_len(pkt))
154 return;
156 tprintf("Sequence (0x%x) ", ntohs(type_5->sequence));
157 tprintf("A|H|L|K (0x%x) ", ntohs(type_5->ahlk_res) >> 12);
158 tprintf("Lifetime (%us)", ntohs(type_5->lifetime) * 4);
161 dissect_mobility_options(pkt, message_data_len);
164 static inline void dissect_mobilityhdr_type_6(struct pkt_buff *pkt,
165 uint8_t *message_data_len)
167 struct bind_ack_msg *type_6;
169 type_6 = (struct bind_ack_msg *) pkt_pull(pkt, sizeof(*type_6));
170 *message_data_len -= sizeof(*type_6);
171 if (type_6 == NULL || *message_data_len > pkt_len(pkt))
172 return;
174 tprintf("Status (0x%x) ", type_6->status);
175 tprintf("K (%u) ", type_6->k_res >> 7);
176 tprintf("Sequence (0x%x)", ntohs(type_6->sequence));
177 tprintf("Lifetime (%us)", ntohs(type_6->lifetime) * 4);
180 dissect_mobility_options(pkt, message_data_len);
183 static inline void dissect_mobilityhdr_type_7(struct pkt_buff *pkt,
184 uint8_t *message_data_len)
186 char address[INET6_ADDRSTRLEN];
187 uint64_t addr;
188 struct bind_err_msg *type_7;
190 type_7 = (struct bind_err_msg *) pkt_pull(pkt, sizeof(*type_7));
191 *message_data_len -= sizeof(*type_7);
192 addr = ntohll(type_7->home_addr);
193 if (type_7 == NULL || *message_data_len > pkt_len(pkt))
194 return;
196 tprintf("Status (0x%x) ", type_7->status);
197 tprintf("Home Addr (%s)",
198 inet_ntop(AF_INET6, &addr, address,
199 sizeof(address)));
202 dissect_mobility_options(pkt, message_data_len);
205 static inline void get_mh_type(struct pkt_buff *pkt,
206 uint8_t *message_data_len, uint8_t *mh_type)
208 switch (*mh_type) {
209 case BINDING_REFRESH_REQUEST_MESSAGE:
210 tprintf("Binding Refresh Request Message ");
211 dissect_mobilityhdr_type_0(pkt, message_data_len);
212 break;
213 case HOME_TEST_INIT_MESSAGE:
214 tprintf("Home Test Init Message ");
215 dissect_mobilityhdr_type_1_2(pkt, message_data_len);
216 break;
217 case CARE_OF_TEST_INIT_MESSAGE:
218 tprintf("Care-of Test Init Message ");
219 dissect_mobilityhdr_type_1_2(pkt, message_data_len);
220 break;
221 case HOME_TEST_MESSAGE:
222 tprintf("Binding Refresh Request Message ");
223 dissect_mobilityhdr_type_3_4(pkt, message_data_len);
224 break;
225 case CARE_OF_TEST_MESSAGE:
226 tprintf("Binding Refresh Request Message ");
227 dissect_mobilityhdr_type_3_4(pkt, message_data_len);
228 break;
229 case BINDING_UPDATE_MESSAGE:
230 tprintf("Binding Refresh Request Message ");
231 dissect_mobilityhdr_type_5(pkt, message_data_len);
232 break;
233 case BINDING_ACKNOWLEDGEMENT_MESSAGE:
234 tprintf("Binding Refresh Request Message ");
235 dissect_mobilityhdr_type_6(pkt, message_data_len);
236 break;
237 case BINDING_ERROR_MESSAGE:
238 tprintf("Binding Refresh Request Message ");
239 dissect_mobilityhdr_type_7(pkt, message_data_len);
240 break;
241 default:
242 tprintf("Type %u is unknown. Error", *mh_type);
245 jmp_to_mh_end(pkt, message_data_len);
248 static inline void mobility(struct pkt_buff *pkt)
250 uint8_t hdr_ext_len, message_data_len;
251 struct mobilityhdr *mobility;
253 mobility = (struct mobilityhdr *) pkt_pull(pkt, sizeof(*mobility));
255 /* Total Header Length in Bytes */
256 hdr_ext_len = (mobility->hdr_len + 1) * 8;
257 /* Total Message Data length in Bytes*/
258 message_data_len = (hdr_ext_len - sizeof(*mobility));
259 if (mobility == NULL || message_data_len > pkt_len(pkt))
260 return;
262 tprintf("\t [ Mobility ");
263 tprintf("NextHdr (%u), ", mobility->payload_proto);
264 tprintf("HdrExtLen (%u, %u Bytes), ", mobility->hdr_len,
265 hdr_ext_len);
266 tprintf("MH Type (%u), ", mobility->MH_type);
267 tprintf("Res (0x%x), ", mobility->reserved);
268 tprintf("Chks (0x%x), ", ntohs(mobility->chksum));
269 tprintf("MH Data ");
271 get_mh_type(pkt, &message_data_len, &mobility->MH_type);
273 tprintf(" ]\n");
275 pkt_set_proto(pkt, &eth_lay3, mobility->payload_proto);
278 static inline void mobility_less(struct pkt_buff *pkt)
280 struct mobilityhdr *mobility;
282 mobility = (struct mobilityhdr *) pkt_pull(pkt, sizeof(*mobility));
283 if (mobility == NULL)
284 return;
286 tprintf(" Mobility Type (%u), ", mobility->MH_type);
288 pkt_set_proto(pkt, &eth_lay3, mobility->payload_proto);
291 struct protocol ipv6_mobility_ops = {
292 .key = 0x87,
293 .print_full = mobility,
294 .print_less = mobility_less,
297 #endif /* PROTO_IPV6_MOBILITY_HDR_H */