ring_tx: handle EINTR from sendto
[netsniff-ng-new.git] / proto_ipv6_routing.c
blobf56f32ff0512143c877cc1cb530ff74270772533
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>, Deutsche Flugsicherung GmbH
4 * Subject to the GPL, version 2.
6 * IPv6 Routing Header described in RFC2460
7 */
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <netinet/in.h> /* for ntohs() and "struct in6_addr" */
12 #include <arpa/inet.h> /* for inet_ntop() */
14 #include "proto.h"
15 #include "dissector_eth.h"
16 #include "built_in.h"
17 #include "pkt_buff.h"
19 #define ROUTING_HEADER_TYPE_0 0x00
21 struct routinghdr {
22 uint8_t h_next_header;
23 uint8_t h_hdr_ext_len;
24 uint8_t h_routing_type;
25 uint8_t h_segments_left;
26 } __packed;
28 struct routinghdr_0 {
29 uint32_t reserved;
30 uint32_t addresses[0];
31 } __packed;
33 static void dissect_routinghdr_type_0(struct pkt_buff *pkt,
34 ssize_t *data_len, int less)
36 uint8_t num_addr;
37 char address[INET6_ADDRSTRLEN];
38 struct in6_addr *addr;
39 struct routinghdr_0 *routing_0;
41 routing_0 = (struct routinghdr_0 *) pkt_pull(pkt, sizeof(*routing_0));
42 *data_len -= sizeof(*routing_0);
43 if (routing_0 == NULL || *data_len > pkt_len(pkt) || *data_len < 0)
44 return;
46 if (less) {
47 tprintf("Addresses (%zu)", *data_len / sizeof(struct in6_addr));
48 return;
51 tprintf("Res (0x%x)", routing_0->reserved);
53 num_addr = *data_len / sizeof(*addr);
55 while (num_addr--) {
56 addr = (struct in6_addr *) pkt_pull(pkt, sizeof(*addr));
57 *data_len -= sizeof(*addr);
58 if (addr == NULL || *data_len > pkt_len(pkt) || *data_len < 0)
59 return;
61 tprintf("\n\t Address: %s",
62 inet_ntop(AF_INET6, addr, address,
63 sizeof(address)));
67 static inline void dissect_routinghdr_type_0_norm(struct pkt_buff *pkt,
68 ssize_t *data_len)
70 dissect_routinghdr_type_0(pkt, data_len, 0);
73 static inline void dissect_routinghdr_type_0_less(struct pkt_buff *pkt,
74 ssize_t *data_len)
76 dissect_routinghdr_type_0(pkt, data_len, 1);
79 static void routing(struct pkt_buff *pkt)
81 uint16_t hdr_ext_len;
82 ssize_t data_len;
83 struct routinghdr *routing;
85 routing = (struct routinghdr *) pkt_pull(pkt, sizeof(*routing));
86 if (routing == NULL)
87 return;
89 /* Total Header Length in Bytes */
90 hdr_ext_len = (routing->h_hdr_ext_len + 1) * 8;
91 /* Data length in Bytes */
92 data_len = hdr_ext_len - sizeof(*routing);
94 tprintf("\t [ Routing ");
95 tprintf("NextHdr (%u), ", routing->h_next_header);
96 if (data_len > pkt_len(pkt) || data_len < 0){
97 tprintf("HdrExtLen (%u, %u Bytes %s), ", routing->h_hdr_ext_len,
98 hdr_ext_len, colorize_start_full(black, red)
99 "invalid" colorize_end());
100 return;
102 tprintf("HdrExtLen (%u, %u Bytes), ", routing->h_hdr_ext_len,
103 hdr_ext_len);
104 tprintf("Type (%u), ", routing->h_routing_type);
105 tprintf("Left (%u), ", routing->h_segments_left);
107 switch (routing->h_routing_type) {
108 case ROUTING_HEADER_TYPE_0:
109 dissect_routinghdr_type_0_norm(pkt, &data_len);
110 break;
111 default:
112 tprintf("Type %u is unknown", routing->h_routing_type);
115 tprintf(" ]\n");
117 if (data_len > pkt_len(pkt) || data_len < 0)
118 return;
120 pkt_pull(pkt, data_len);
121 pkt_set_dissector(pkt, &eth_lay3, routing->h_next_header);
124 static void routing_less(struct pkt_buff *pkt)
126 uint16_t hdr_ext_len;
127 ssize_t data_len;
128 struct routinghdr *routing;
130 routing = (struct routinghdr *) pkt_pull(pkt, sizeof(*routing));
131 if (routing == NULL)
132 return;
134 /* Total Header Length in Bytes */
135 hdr_ext_len = (routing->h_hdr_ext_len + 1) * 8;
136 /* Data length in Bytes */
137 data_len = hdr_ext_len - sizeof(*routing);
138 if (data_len > pkt_len(pkt) || data_len < 0)
139 return;
141 tprintf(" Routing ");
143 switch (routing->h_routing_type) {
144 case ROUTING_HEADER_TYPE_0:
145 dissect_routinghdr_type_0_less(pkt, &data_len);
146 break;
147 default:
148 tprintf("Type %u is unknown", routing->h_routing_type);
151 if (data_len > pkt_len(pkt) || data_len < 0)
152 return;
154 pkt_pull(pkt, data_len);
155 pkt_set_dissector(pkt, &eth_lay3, routing->h_next_header);
158 struct protocol ipv6_routing_ops = {
159 .key = 0x2B,
160 .print_full = routing,
161 .print_less = routing_less,