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
9 #ifndef PROTO_IPV6_MOBILITY_HDR_H
10 #define PROTO_IPV6_MOBILITY_HDR_H
14 #include <netinet/in.h> /* for ntohs() */
16 #include "proto_struct.h"
17 #include "dissector_eth.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
31 uint8_t payload_proto
;
39 struct bin_refr_req_msg
{
41 uint8_t mobility_opt
[0];
44 /* for 0x01 and 0x02 */
48 uint8_t mobility_opt
[0];
51 /* for 0x03 and 0x04 */
55 uint64_t keygen_token
;
56 uint8_t mobility_opt
[0];
63 uint8_t mobility_opt
[0];
71 uint8_t mobility_opt
[0];
78 uint8_t mobility_opt
[0];
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
))
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
))
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
))
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
))
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
))
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
];
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
))
196 tprintf("Status (0x%x) ", type_7
->status
);
197 tprintf("Home Addr (%s)",
198 inet_ntop(AF_INET6
, &addr
, 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
)
209 case BINDING_REFRESH_REQUEST_MESSAGE
:
210 tprintf("Binding Refresh Request Message ");
211 dissect_mobilityhdr_type_0(pkt
, message_data_len
);
213 case HOME_TEST_INIT_MESSAGE
:
214 tprintf("Home Test Init Message ");
215 dissect_mobilityhdr_type_1_2(pkt
, message_data_len
);
217 case CARE_OF_TEST_INIT_MESSAGE
:
218 tprintf("Care-of Test Init Message ");
219 dissect_mobilityhdr_type_1_2(pkt
, message_data_len
);
221 case HOME_TEST_MESSAGE
:
222 tprintf("Binding Refresh Request Message ");
223 dissect_mobilityhdr_type_3_4(pkt
, message_data_len
);
225 case CARE_OF_TEST_MESSAGE
:
226 tprintf("Binding Refresh Request Message ");
227 dissect_mobilityhdr_type_3_4(pkt
, message_data_len
);
229 case BINDING_UPDATE_MESSAGE
:
230 tprintf("Binding Refresh Request Message ");
231 dissect_mobilityhdr_type_5(pkt
, message_data_len
);
233 case BINDING_ACKNOWLEDGEMENT_MESSAGE
:
234 tprintf("Binding Refresh Request Message ");
235 dissect_mobilityhdr_type_6(pkt
, message_data_len
);
237 case BINDING_ERROR_MESSAGE
:
238 tprintf("Binding Refresh Request Message ");
239 dissect_mobilityhdr_type_7(pkt
, message_data_len
);
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
))
262 tprintf("\t [ Mobility ");
263 tprintf("NextHdr (%u), ", mobility
->payload_proto
);
264 tprintf("HdrExtLen (%u, %u Bytes), ", mobility
->hdr_len
,
266 tprintf("MH Type (%u), ", mobility
->MH_type
);
267 tprintf("Res (0x%x), ", mobility
->reserved
);
268 tprintf("Chks (0x%x), ", ntohs(mobility
->chksum
));
271 get_mh_type(pkt
, &message_data_len
, &mobility
->MH_type
);
275 pkt_set_proto(pkt
, ð_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
)
286 tprintf(" Mobility Type (%u), ", mobility
->MH_type
);
288 pkt_set_proto(pkt
, ð_lay3
, mobility
->payload_proto
);
291 struct protocol ipv6_mobility_ops
= {
293 .print_full
= mobility
,
294 .print_less
= mobility_less
,
297 #endif /* PROTO_IPV6_MOBILITY_HDR_H */