1 /*
2     ettercap -- IPv6 decoder module
3 
4     Copyright (C) ALoR & NaGA
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 
20 */
21 
22 #include <ec.h>
23 #include <ec_decode.h>
24 #include <ec_inject.h>
25 #include <ec_inet.h>
26 #include <ec_session.h>
27 //#include <ec_fingerprint.h>
28 
29 #define IP6_HDR_LEN 40
30 
31 /* globals */
32 
33 struct ip6_header {
34 #ifndef WORDS_BIGENDIAN
35    u_int8   version:4;
36    u_int8   priority:4;
37 #else
38    u_int8   priority:4;
39    u_int8   version:4;
40 #endif
41    u_int8   flow_lbl[3];
42    u_int16  payload_len;
43    u_int8   next_hdr;
44    u_int8   hop_limit;
45 
46    u_int8   saddr[IP6_ADDR_LEN];
47    u_int8   daddr[IP6_ADDR_LEN];
48 };
49 
50 struct ip6_ext_header {
51     u_int8 next_hdr;
52     u_int8 hdr_len;
53 
54     /* Here must be options */
55 };
56 
57 struct ip6_ident {
58    u_int32 magic;
59 #define IP6_MAGIC    0x0306e77e
60    u_int8 flow_lbl[3];
61    struct ip_addr L3_src;
62 };
63 
64 struct ip6_data {
65    u_int8 priority :4;
66 };
67 
68 /* protos */
69 
70 void ip6_init(void);
71 FUNC_DECODER(decode_ip6);
72 FUNC_DECODER(decode_ip6_ext);
73 FUNC_INJECTOR(inject_ip6);
74 static size_t ip6_create_ident(void **i, struct packet_object *po);
75 static int ip6_match(void *ident_s, void *ident_c);
76 static void ip6_create_session(struct ec_session **s, struct packet_object *po);
77 
78 /*******************************************/
79 
80 /*
81  * this function is the initializer.
82  * it adds the entry in the table of registered decoder
83  */
84 
ip6_init(void)85 void __init ip6_init(void)
86 {
87    add_decoder(NET_LAYER, LL_TYPE_IP6, decode_ip6);
88    add_decoder(PROTO_LAYER, NL_TYPE_IP6, decode_ip6);
89    add_decoder(NET6_LAYER, LO6_TYPE_HBH, decode_ip6_ext);
90    add_decoder(NET6_LAYER, LO6_TYPE_RT, decode_ip6_ext);
91    add_decoder(NET6_LAYER, LO6_TYPE_DST, decode_ip6_ext);
92 
93    add_injector(CHAIN_LINKED, IP6_MAGIC, inject_ip6);
94 }
95 
96 
FUNC_DECODER(decode_ip6)97 FUNC_DECODER(decode_ip6)
98 {
99    FUNC_DECODER_PTR(next_decoder);
100    struct ip6_header *ip6;
101    struct ec_session *s;
102    void *ident;
103 
104    ip6 = (struct ip6_header *)DECODE_DATA;
105 
106    if (ip6->payload_len == 0) {
107       DEBUG_MSG("IPv6 jumbogram, Hop-By-Hop header should follow");
108    }
109    DECODED_LEN = IP6_HDR_LEN;
110 
111    /* IP addresses */
112    ip_addr_init(&PACKET->L3.src, AF_INET6, (u_char *)&ip6->saddr);
113    ip_addr_init(&PACKET->L3.dst, AF_INET6, (u_char *)&ip6->daddr);
114 
115    /* this is needed at upper layer to calculate the tcp payload size */
116    PACKET->L3.payload_len = ntohs(ip6->payload_len);
117 
118    /* other relevant infos */
119    PACKET->L3.header = (u_char *)DECODE_DATA;
120    PACKET->L3.len = DECODED_LEN;
121 
122    PACKET->L3.proto = htons(LL_TYPE_IP6);
123    PACKET->L3.ttl = ip6->hop_limit;
124 
125    if(PACKET->fwd_packet == NULL) {
126       EXECUTE(EC_GBL_SNIFF->check_forwarded, PACKET);
127       /* if it is already forwarded */
128       if(PACKET->flags & PO_FORWARDED)
129          return NULL;
130       EXECUTE(EC_GBL_SNIFF->set_forwardable, PACKET);
131       PACKET->fwd_packet = (u_char *)DECODE_DATA;
132       PACKET->fwd_len = PACKET->L3.payload_len + DECODED_LEN;
133    }
134 
135    /* calculate if the dest is local or not */
136    switch (ip_addr_is_local(&PACKET->L3.src, NULL)) {
137       case E_SUCCESS:
138          PACKET->PASSIVE.flags &= ~(FP_HOST_NONLOCAL);
139          PACKET->PASSIVE.flags |= FP_HOST_LOCAL;
140          break;
141       case -E_NOTFOUND:
142          PACKET->PASSIVE.flags &= ~FP_HOST_LOCAL;
143          PACKET->PASSIVE.flags |= FP_HOST_NONLOCAL;
144          break;
145       case -E_INVALID:
146          PACKET->PASSIVE.flags = FP_UNKNOWN;
147          break;
148    }
149 
150    next_decoder = get_decoder(NET6_LAYER, ip6->next_hdr);
151    if(next_decoder == NULL) {
152       PACKET->L3.options = NULL;
153       PACKET->L3.optlen = 0;
154       next_decoder = get_decoder(PROTO_LAYER, ip6->next_hdr);
155    } else {
156       PACKET->L3.options = (u_char *)&ip6[1];
157    }
158 
159    /* HOOK POINT: HOOK_PACKET_IP6 */
160    hook_point(HOOK_PACKET_IP6, po);
161 
162    if(!EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read) {
163       ip6_create_ident(&ident, PACKET);
164 
165       if(session_get(&s, ident, sizeof(struct ip6_ident)) == -E_NOTFOUND) {
166          ip6_create_session(&s, PACKET);
167          session_put(s);
168       }
169       SAFE_FREE(ident);
170 
171       SESSION_PASSTHRU(s, PACKET);
172    }
173 
174    /* passing the packet to options or upper-layer decoder */
175    EXECUTE_DECODER(next_decoder);
176 
177    /*
178     * External L3 header sets itself
179     * as the packet to be forwarded.
180     */
181    /* XXX - recheck this */
182    if(!EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read && (PACKET->flags & PO_FORWARDABLE)) {
183       if(PACKET->flags & PO_MODIFIED) {
184          ORDER_ADD_SHORT(ip6->payload_len, PACKET->DATA.delta);
185 
186          /*
187           * In case some upper level encapsulated ip6 decoder
188           * modified it ... (required for ip6 in ip6 encapsulation)
189           */
190          PACKET->L3.header = (u_char*)ip6;
191          PACKET->L3.len = IP6_HDR_LEN;
192          PACKET->L3.payload_len = ntohs(ip6->payload_len);
193 
194          PACKET->fwd_len = PACKET->L3.payload_len + PACKET->L3.len;
195       }
196    }
197 
198    return NULL;
199 }
200 
201 /* XXX - dirty stuff just to make things work.
202  * Rewrite it to handle extension headers (if needed).
203  */
FUNC_DECODER(decode_ip6_ext)204 FUNC_DECODER(decode_ip6_ext)
205 {
206    FUNC_DECODER_PTR(next_decoder);
207    struct ip6_ext_header *ext_hdr;
208 
209    ext_hdr = (struct ip6_ext_header *)DECODE_DATA;
210    PACKET->L3.optlen += ext_hdr->hdr_len + 1;
211    DECODED_LEN = ext_hdr->hdr_len + 1;
212 
213    next_decoder = get_decoder(NET6_LAYER, ext_hdr->next_hdr);
214    if(next_decoder == NULL) {
215       next_decoder = get_decoder(PROTO_LAYER, ext_hdr->next_hdr);
216    }
217 
218    EXECUTE_DECODER(next_decoder);
219 
220    return NULL;
221 }
222 
FUNC_INJECTOR(inject_ip6)223 FUNC_INJECTOR(inject_ip6)
224 {
225    struct ip6_header *ip6;
226    struct ip6_ident *ident;
227    struct ip6_data *data;
228    struct ec_session *s = NULL;
229    u_int32 magic;
230    u_int16 plen;
231    u_int16 flen;
232 
233 //   DEBUG_MSG("inject_ip6");
234 
235    /* i think im paranoid */
236    if(LENGTH + sizeof(struct ip6_header) > EC_GBL_IFACE->mtu)
237       return -E_NOTHANDLED;
238 
239    /* almost copied from ec_ip.c */
240    PACKET->packet -= sizeof(struct ip6_header);
241    ip6 = (struct ip6_header *)PACKET->packet;
242 
243    ip6->version = 6;
244    ip6->next_hdr = PACKET->L4.proto;
245    ip6->hop_limit = 64;
246    memcpy(&ip6->saddr, &PACKET->L3.src.addr, IP6_ADDR_LEN);
247    memcpy(&ip6->daddr, &PACKET->L3.dst.addr, IP6_ADDR_LEN);
248 
249    s = PACKET->session;
250    /* Renew session */
251    if(session_get(&s, s->ident, sizeof(struct ip6_ident)) == -E_NOTFOUND)
252       return -E_NOTFOUND;
253 
254    ident = s->ident;
255    memcpy(&ip6->flow_lbl, &ident->flow_lbl, 3);
256 
257    data = s->data;
258    ip6->priority = data->priority;
259 
260    flen = LENGTH;
261    LENGTH += sizeof(struct ip6_header);
262 
263    if(s->prev_session != NULL) {
264       PACKET->session = s->prev_session;
265       magic = *(u_int32 *) s->prev_session->ident;
266 
267       EXECUTE_INJECTOR(CHAIN_LINKED, magic);
268    }
269 
270    plen = EC_GBL_IFACE->mtu - LENGTH < PACKET->DATA.inject_len
271           ? EC_GBL_IFACE->mtu - LENGTH : PACKET->DATA.inject_len;
272    ip6->payload_len = htons(plen);
273 
274    PACKET->L3.len = flen + plen;
275    PACKET->L3.header = (u_char *)ip6;
276 
277    if(s->prev_session == NULL) {
278       PACKET->fwd_packet = PACKET->packet;
279       PACKET->fwd_len = PACKET->L3.len;
280    }
281 
282    return E_SUCCESS;
283 }
284 
ip6_create_ident(void ** i,struct packet_object * po)285 static size_t ip6_create_ident(void **i, struct packet_object *po)
286 {
287    struct ip6_header *ip6;
288    struct ip6_ident *ident;
289 
290    SAFE_CALLOC(ident, 1, sizeof(struct ip6_ident));
291 
292    ip6 = (struct ip6_header *)po->L3.header;
293 
294    ident->magic = IP6_MAGIC;
295    memcpy(&ident->flow_lbl, ip6->flow_lbl, 3);
296    memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr));
297 
298    *i = ident;
299 
300    return sizeof(struct ip6_ident);
301 }
302 
ip6_match(void * ident_s,void * ident_c)303 static int ip6_match(void *ident_s, void *ident_c)
304 {
305    struct ip6_ident *ids = ident_s;
306    struct ip6_ident *idc = ident_c;
307 
308    if(ids->magic != idc->magic)
309       return 0;
310 
311    if(memcmp(&ids->flow_lbl, &idc->flow_lbl, 3))
312       return 0;
313    if(ip_addr_cmp(&ids->L3_src, &idc->L3_src))
314       return 0;
315 
316    return 1;
317 }
318 
ip6_create_session(struct ec_session ** s,struct packet_object * po)319 static void ip6_create_session(struct ec_session **s, struct packet_object *po)
320 {
321    void *ident;
322 
323    DEBUG_MSG("ip6_create_session");
324 
325    SAFE_CALLOC(*s, 1, sizeof(struct ec_session));
326    SAFE_CALLOC((*s)->data, 1, sizeof(struct ip6_data));
327 
328    (*s)->data_len = sizeof(struct ip6_data);
329    (*s)->ident_len = ip6_create_ident(&ident, po);
330    (*s)->ident = ident;
331    (*s)->match = &ip6_match;
332 
333    return;
334 }
335 
336 /* EOF */
337 
338 // vim:ts=3:expandtab
339 
340