trafgen: allow to schedule packets on specific CPUs
[netsniff-ng.git] / src / cdp.c
blobd198d965425bbe2bf51f79ef1dd1a1b452d81883
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008 Herbert Haas
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
19 /////////////////////////////////////////////////////////////////////
21 // Send CDP packets
23 /////////////////////////////////////////////////////////////////////
26 #include "mz.h"
27 #include "cli.h"
30 #define MZ_CDP_HELP \
31 "| CDP type: Send arbitrary CDP packets.\n" \
32 "| Note:\n" \
33 "| - The Ethernet dst and src MAC addresses can be specified but can be also 'rand'.\n" \
34 "| - If dst and src are NOT specified then practical defaults are used (src=own MAC, dst=01:00:0C:CC:CC:CC).\n" \
35 "|\n" \
36 "| ARGUMENT SYNTAX: -t cdp [arguments]\n" \
37 "|\n" \
38 "| ARGUMENTS:\n" \
39 "|\n" \
40 "| version ...... 0-255, default: 2\n" \
41 "| ttl ...... 0-255, default: 180 s\n" \
42 "| sum ...... 0000-ffff, default: automatically computed\n" \
43 "|\n" \
44 "| TLVs: Description: Example:\n" \
45 "|\n" \
46 "| tlv_id ....... Device ID Mausezahn station\n" \
47 "| tlv_address ....... Sending interface address 10.1.1.2\n" \
48 "| tlv_portid ....... Port Identifier 2/23\n" \
49 "| tlv_cap ....... Capabilities (hex<7f) 2a\n" \
50 "| tlv_version ....... Software Version ver3.0\n" \
51 "| tlv_platform ....... Hardware Platform WS-C6509-E\n" \
52 "| tlv_vtpdomain ....... VTP Management Domain MyVTPdomain\n" \
53 "| tlv_native ....... Native VLAN number (0-4095) 42\n" \
54 "| tlv_duplex ....... Full or half duplex full\n" \
55 "| tlv_mgmt ....... Management IP address 192.168.1.2\n" \
56 "|\n" \
57 "| tlv .......... Create ANY TLV using the format: tlv=<type>/<value>, such as tlv=42/mausezahn\n" \
58 "| Note: Currently you must omit spaces within <value>! Use underscore instead.\n" \
59 "| tlvhex .......... Create ANY TLV and specify the value in hexformat, such as tlv=42/ca:fe:ba:be\n" \
60 "| payload|p .......... Optional additional TLVs or any other bytes specified in hex\n" \
61 "|\n" \
62 "| When the tlv* arguments are used, the TLV length parameter is automatically set.\n" \
63 "|\n" \
64 "| The capability flags from MSB to LSB are:\n" \
65 "| 0 - Repeater - IGMP - Host - Switch - SrcRouteBrdg - TranspBrdg - Router\n" \
66 "|\n" \
67 "| Optionally the keyword 'change' will create a different System name TLV every time a CDP\n" \
68 "| packet is sent. This can be used to fill up a CDP database with different test values.\n" \
69 "| Additionally use the '-a rand' command to use different source MAC addresses.\n" \
70 "|\n" \
71 "| EXAMPLES:\n" \
72 "|\n" \
73 "| Announce Device ID 'Espresso3000', Capabilities: Router, native VLAN 301:\n" \
74 "| mz eth0 -t cdp \"tlv_id=Espresso3000, tlv_cap=01, tlv_native=301\"\n" \
75 "|\n" \
76 "| Create another TLV using the payload interface (here voice VLAN 400):\n" \
77 "| mz eth0 -t cdp p=00:0e:00:07:01:01:90\n"
83 u_int16_t checksum16 (u_int16_t len, u_int8_t buff[])
86 u_int16_t word16;
87 u_int32_t sum=0;
88 u_int16_t i;
90 // make 16 bit words out of every two adjacent 8 bit words in the packet and add them up
91 for (i=0; i<len; i=i+2)
93 word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
94 sum = sum + (u_int32_t) word16;
97 // take only 16 bits out of the 32 bit sum and add up the carries
98 while (sum>>16)
99 sum = (sum & 0xFFFF)+(sum >> 16);
101 // one's complement the result
102 sum = ~sum;
104 return ((u_int16_t) sum);
108 // Creates a TLV and returns the whole length of the TLV
109 unsigned int create_tlv (u_int16_t type, // The 16-bit TYPE number
110 u_int8_t *value, // The VALUE as prepared hex-array
111 unsigned int value_len, // needed because VALUE maybe not \0 terminated
112 u_int8_t *target) // the RESULT i. e. the complete TLV
114 unsigned int tlvlen;
115 u_int8_t *x;
117 x = (u_int8_t*) &type; // set TYPE
118 target[0] = *(x+1);
119 target[1] = *(x);
121 tlvlen = value_len + 4; // set VALUE
122 x = (u_int8_t*) &tlvlen;
123 target[2] = *(x+1);
124 target[3] = *(x);
126 target+=4;
127 memcpy((void*) target, (void*) value, (size_t) value_len);
129 return tlvlen;
135 // NOTE: The Length field indicates the total length, in bytes, of the type, length, and value fields!
137 // Interesting TLVs:
139 // TYPE VALUE
140 // 0001 Device-ID
141 // 0002 IP Addresses
142 // 0003 Port ID such as 2/22
143 // 0004 Capabilities (Len=8, consists of flags only: Router, TBrdg, SRBrdgm, Switch, Host, IGMP, Repeater)
144 // 0005 SW Version
145 // 0006 Platform
146 // 0009 VTP Domain
147 // 000a Native VLAN, e.g. 00:0a 00:06 01:2d identifies native VLAN number 301 (=01:2d)
148 // 000b Duplex
149 // 000e VoIP VLAN, e.g. 00:0e 00:07 01 01:90 identifies DATA (=01) and VLAN 400 (=01:90)
150 // 0012 Trust Bitmap
151 // 0013 Untrusted Port CoS
152 // 0014 System Name (!!!)
153 // 0015 System Object Identifier
154 // 0016 Management Address (!!!), e.g. 0016 0011(=len 17) 00-00-00-01(=one IP only) 01-01-cc-00-04-90-fe-f8-10(=144.254.248.16)
155 // 0017 Location
156 // 001a Unknown (???)
158 // The IP address format is a bit strange as 0016 for example demonstrates...
162 int send_cdp ()
164 libnet_t *l;
165 libnet_ptag_t t;
166 char
167 errbuf[LIBNET_ERRBUF_SIZE],
168 argval[1024];
170 u_int8_t
171 packet[MAX_PAYLOAD_SIZE], // this one will finally contain the whole cdp packet (without LLC/SNAP!)
173 value[1024], // USE THIS FOR ANYTHING YOU LIKE !!!
174 value1[1024], // This one is reserved for some code - Don't use it again!
175 value2[1024], // This one is reserved for some code - Don't use it again!
176 tlv[1024],
177 default_id[15] = "Mausezahn rules",
178 llcsnap[8]=
180 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x0c, 0x20, 0x00
183 unsigned int
184 len=0,
185 len1=0,
186 len2=0,
187 type1,
188 type2;
190 u_int16_t
191 dummy16=0,
192 tlv_len=0;
194 u_int32_t
195 next_pbyte=0, // points to the next free byte in tx.cdp_payload
196 dummy32=0,
197 packet_s;
199 char
200 pld[2048];
203 unsigned int i=0, count, delay;
204 int
205 eth_src_rand=0,
206 change_value=0;
207 long int j=0;
210 if (tx.dot1Q)
212 fprintf(stderr," Note: CDP mode does not support 802.1Q builder.\n");
213 exit(1);
216 if (tx.mpls)
218 fprintf(stderr," Note: CDP mode does not support MPLS builder.\n");
219 exit(1);
223 if (getarg(tx.arg_string,"help", NULL)==1)
225 if (mz_port)
227 cli_print(gcli, "%s", MZ_CDP_HELP);
228 return -1;
230 else
232 fprintf(stderr,"\n"
233 MAUSEZAHN_VERSION
234 "\n%s", MZ_CDP_HELP);
235 exit(0);
240 ///////////////////////////////////////////////////////////////////////
241 // initial defaults:
242 if (tx.cdp_ttl==0) tx.cdp_ttl=0xb4; // 180 seconds
244 if (tx.cdp_version==0) tx.cdp_version = 0x02;
246 // The ID is the only required TLV
247 // If another function already specified it then it must also set the lenght:
248 if (tx.cdp_tlv_id_len==0) // not set
250 memcpy((void*) tx.cdp_tlv_id, (void*) default_id, 15);
251 tx.cdp_tlv_id_len=15;
257 ///////////////////////////////////////////////////////////////////////
259 // Now check for user arguments:
262 if ( (getarg(tx.arg_string,"version", argval)==1) || (getarg(tx.arg_string,"ver", argval)==1) )
264 if (str2int(argval)>255)
266 fprintf(stderr," mz/send_cdp: version range exceeded, adjusted to max value.\n");
267 tx.cdp_version = 0xff;
269 else
271 tx.cdp_version = (u_int8_t) str2int(argval);
276 if (getarg(tx.arg_string,"ttl", argval)==1)
278 if (str2int(argval)>255)
280 fprintf(stderr," mz/send_cdp: TTL range exceeded, adjusted to max value.\n");
281 tx.cdp_ttl = 0xff;
283 else
285 tx.cdp_ttl = (u_int8_t) str2int(argval);
289 if (getarg(tx.arg_string,"sum", argval)==1)
292 if (strtol(argval,NULL,16)>65535)
294 fprintf(stderr," mz/send_cdp: checksum range exceeded, adjusted to max value.\n");
295 tx.cdp_sum = 0xffff;
297 else
299 tx.cdp_sum = (u_int16_t) strtol(argval,NULL,16);
303 ////////
305 // Provide a basic interface for the most important TLVs:
308 if (getarg(tx.arg_string,"tlv_id", argval)==1)
310 // simply overwrite current content in tx.cdp_tlv_id
311 tx.cdp_tlv_id[0] = '\0';
312 strncpy((char*) tx.cdp_tlv_id, argval,2048);
313 tx.cdp_tlv_id_len = strlen ((char*)tx.cdp_tlv_id);
318 // This is something ugly ;-)
321 if (getarg(tx.arg_string,"change", NULL)==1)
323 memcpy((void*) tx.cdp_tlv_id, (void*) "Mausezahn 00000000000", 21);
324 tx.cdp_tlv_id_len=21;
325 change_value = 1;
330 // NOW write the ID-TLV; this is the only REQUIRED TLV !!!
331 // and this TLV should be the FIRST one - that's why we
332 // write it immediately here now:
334 tlv_len = create_tlv (1, tx.cdp_tlv_id, tx.cdp_tlv_id_len, tlv);
335 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
336 next_pbyte += tlv_len;
339 // Now the other TLVs may follow:
342 // Format: Type=2, Len=17, NrOfAddr=00:00:00:01, Protocol=01:01:cc:00, AddrLen=4, IP_Address
343 // Example: tlv_address = 192.168.1.10
344 // Note: currently only one address supported
345 if (getarg(tx.arg_string,"tlv_address", argval)==1)
347 dummy32 = str2ip32 (argval);
348 x = (u_int8_t*) &dummy32;
349 value[0] = 0x00; // NrOfAddr
350 value[1] = 0x00;
351 value[2] = 0x00;
352 value[3] = 0x01;
354 value[4] = 0x01; // Protocol
355 value[5] = 0x01;
356 value[6] = 0xcc;
357 value[7] = 0x00;
359 value[8] = 0x04; // AddrLen
361 value[9] = *(x+3);
362 value[10] = *(x+2);
363 value[11] = *(x+1);
364 value[12] = *(x);
366 tlv_len = create_tlv (2, value, 13, tlv);
367 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
368 next_pbyte += tlv_len;
373 // Format: Type=3
374 // Example: tlv_portid = 2/23
375 // Note:
376 if (getarg(tx.arg_string,"tlv_portid", argval)==1)
378 tlv_len = create_tlv (3, (u_int8_t*) argval, strlen(argval), tlv);
379 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
380 next_pbyte += tlv_len;
383 // Format: Type=4
384 // Example: "tlv_cap = 2a" (= 0010 1010)
385 // Flags: MSB=0 - Repeater - IGMP - Host - Switch - SrcRouteBrdg - TranspBrdg - Router(LSB)
386 if (getarg(tx.arg_string,"tlv_cap", argval)==1)
388 if (strlen(argval)>2)
390 fprintf(stderr," mz/send_cdp: Capability value must be specified as a two-digit hexadecimal value!\n");
391 exit(1);
393 else
395 str2hex(argval, value+3, 1020);
396 if (value[3]>0x7f)
398 fprintf(stderr," mz/send_cdp: Capability value must not exceed 7F(hex)\n");
399 exit(1);
403 value[0]=0x00;
404 value[1]=0x00;
405 value[2]=0x00;
406 tlv_len = create_tlv (4, value, 4, tlv);
407 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
408 next_pbyte += tlv_len;
412 // Format: Type=5
413 // Example: tlv_version = Mausezahn_version_xyz
414 // Note: Avoid spaces, use underscore instead
415 if (getarg(tx.arg_string,"tlv_version", argval)==1)
417 tlv_len = create_tlv (5, (u_int8_t*) argval, strlen(argval), tlv);
418 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
419 next_pbyte += tlv_len;
423 // Format: Type=6
424 // Example: tlv_platform = WS-C6509-E
425 // Note:
426 if (getarg(tx.arg_string,"tlv_platform", argval)==1)
428 tlv_len = create_tlv (6, (u_int8_t*) argval, strlen(argval), tlv);
429 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
430 next_pbyte += tlv_len;
433 // Format: Type=9
434 // Example: tlv_vtpdomain = MyVTPdomain
435 // Note:
436 if (getarg(tx.arg_string,"tlv_vtpdomain", argval)==1)
438 tlv_len = create_tlv (9, (u_int8_t*) argval, strlen(argval), tlv);
439 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
440 next_pbyte += tlv_len;
444 // Format: Type=10, Len=17
445 // Example: tlv_native = 100
446 // Note:
447 if (getarg(tx.arg_string,"tlv_native", argval)==1)
449 dummy16 = (u_int16_t) str2int(argval);
450 if (dummy16>4095)
452 fprintf(stderr," mz/WARNING: native VLAN value exceeds max value (4095) - hope you know what you do!\n");
455 x = (u_int8_t*) &dummy16;
456 value[0] = *(x+1);
457 value[1] = *(x);
458 tlv_len = create_tlv (10, value, 2, tlv);
459 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
460 next_pbyte += tlv_len;
463 // Format: Type=11
464 // Example: tlv_duplex = full | half
465 // Note:
466 if (getarg(tx.arg_string,"tlv_duplex", argval)==1)
468 if (strncmp(argval,"full",10)==0)
470 value[0]=0x01;
472 else if (strncmp(argval,"half",10)==0)
474 value[0]=0x00;
476 else
478 value[0]=(u_int8_t) str2int(argval);
479 if (!quiet)
481 fprintf(stderr," mz/Warning: Only keywords 'half' or 'full' supported."
482 " Will interprete input as integer.\n");
487 tlv_len = create_tlv (11, value, 1, tlv);
488 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
489 next_pbyte += tlv_len;
492 // Format: Type=22, Len=17, NrOfAddr=00:00:00:01, Protocol=01:01:cc:00, AddrLen=4, IP_Address
493 // Example: tlv_mgmt = 10.1.1.99
494 // Note: Same format as tlv_address
495 if (getarg(tx.arg_string,"tlv_mgmt", argval)==1)
497 dummy32 = str2ip32 (argval);
498 x = (u_int8_t*) &dummy32;
499 value[0] = 0x00; // NrOfAddr
500 value[1] = 0x00;
501 value[2] = 0x00;
502 value[3] = 0x01;
504 value[4] = 0x01; // Protocol
505 value[5] = 0x01;
506 value[6] = 0xcc;
507 value[7] = 0x00;
509 value[8] = 0x04; // AddrLen
511 value[9] = *(x+3);
512 value[10] = *(x+2);
513 value[11] = *(x+1);
514 value[12] = *(x);
516 tlv_len = create_tlv (22, value, 13, tlv);
517 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
518 next_pbyte += tlv_len;
525 // Eventually there are two generic TLV interfaces: tlv and tlvhex
528 if (getarg(tx.arg_string,"tlv", argval)==1)
530 // split in TYPE and VALUE
531 sscanf(argval, "%u/%s", &type1, value1);
532 len1 = strlen((const char*) value1);
536 if (getarg(tx.arg_string,"tlvhex", argval)==1)
538 // split in TYPE and VALUE
539 sscanf(argval, "%u/%s", &type2, pld);
540 len2 = str2hex(pld, value2, 1023);
545 // Finally the optional payload interface allows to specify subsequent TLVs or any other bytes:
547 if ( (getarg(tx.arg_string,"payload", argval)==1) || (getarg(tx.arg_string,"p", argval)==1))
549 len = str2hex (argval, value, 1023);
550 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) value, len);
551 next_pbyte += len;
556 ///////////////////////////////////////////////////////////////
560 // Write other TLVs: First the ASCII specified:
561 if (len1)
563 tlv_len = create_tlv (type1, value1, len1 , tlv);
564 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
565 next_pbyte += tlv_len;
568 // Write other TLVs: Then the HEX specified:
569 if (len2)
571 tlv_len = create_tlv (type2, value2, len2 , tlv);
572 memcpy((void*) tx.cdp_payload+next_pbyte, (void*) tlv, tlv_len);
573 next_pbyte += tlv_len;
577 tx.cdp_payload_s = next_pbyte;
579 // CHECK:
580 // bs2str(tx.cdp_payload, pld, tx.cdp_payload_s);
581 // printf("PAYLOAD= %s\n",pld);
584 ////////////////////////////
587 // Open the link - for the intermediate CDP/LLC frame
588 l = libnet_init(LIBNET_LINK_ADV, tx.device, errbuf);
590 if (l == NULL)
592 fprintf(stderr, "%s", errbuf);
593 exit(EXIT_FAILURE);
596 if (check_eth_mac_txt(ETH_DST)) // if '1' then user did not set MAC address (or problem occurred)
598 str2hex("01:00:0C:CC:CC:CC", tx.eth_dst, 6);
601 if (check_eth_mac_txt(ETH_SRC)) // if '1' then user did not set MAC address (or problem occurred)
603 // own mac per default (see init.c)
606 count = tx.count;
607 eth_src_rand = tx.eth_src_rand;
608 delay = tx.delay;
610 // ---------------------------------------------------
611 // If you want to change CDP fields during a LOOP then
612 // START the loop from HERE:
615 ////////////////////////////////////
616 // Now create the whole CDP packet:
618 packet[0] = tx.cdp_version; // VERSION
619 packet[1] = tx.cdp_ttl; // TTL
620 packet[2] = 0x00; // CHECKSUM
621 packet[3] = 0x00;
623 // Now add the TLVs
624 memcpy ((void*) packet+4, (void*) tx.cdp_payload, tx.cdp_payload_s);
625 packet_s = tx.cdp_payload_s + 4;
627 // Check whether packet is an even length (i.e. is a multiple of 16 bits = 2 bytes);
628 if (packet_s%2>0)
630 packet[packet_s++]=0x00;
631 packet[packet_s++]=0x17;
632 packet[packet_s++]=0x00;
633 packet[packet_s++]=0x05;
634 packet[packet_s++]=0x00;
638 // Now update the checksum:
639 if (tx.cdp_sum == 0) // Otherwise user specified the checksum (usually a wrong one ;-))
641 tx.cdp_sum = checksum16(packet_s, packet);
643 x = (u_int8_t *) &tx.cdp_sum;
644 packet[2] = *(x+1);
645 packet[3] = *(x);
647 // CHECK the CDP packet
648 //bs2str(packet, pld, packet_s);
649 //printf("CDP= %s\n",pld);
652 // printf("Len = %u Checksum = %04x \n", packet_s-8, tx.cdp_sum);
655 ///////////////////////////////////////////////////////////////
656 // Now create the whole tx.eth_payload = LLC/SNAP + CDP packet
657 // First the LLC/SNAP header:
658 memcpy ((void*) tx.eth_payload, (void*) llcsnap, 8);
659 memcpy ((void*) tx.eth_payload+8, (void*) packet, packet_s);
660 tx.eth_payload_s = packet_s +8;
663 // CHECK the whole 802.3 payload
664 // bs2str(tx.eth_payload, pld, tx.eth_payload_s);
665 // printf("PACKET = %s\n",pld);
668 t = libnet_build_802_3 (tx.eth_dst,
669 tx.eth_src,
670 tx.eth_payload_s,
671 tx.eth_payload,
672 tx.eth_payload_s,
678 // this is for the statistics:
679 mz_start = clock();
680 total_d = tx.count;
682 if (!count) goto AGAIN;
684 for (i=0; i<count; i++)
686 AGAIN:
688 if (eth_src_rand)
690 tx.eth_src[0] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256) & 0xFE; // keeps bcast-bit zero
691 tx.eth_src[1] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
692 tx.eth_src[2] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
693 tx.eth_src[3] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
694 tx.eth_src[4] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
695 tx.eth_src[5] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
697 t = libnet_build_802_3 (tx.eth_dst,
698 tx.eth_src,
699 tx.eth_payload_s,
700 tx.eth_payload,
701 tx.eth_payload_s,
708 libnet_write(l);
710 if (verbose)
712 bs2str(tx.eth_payload+8, pld, tx.eth_payload_s-8);
713 fprintf(stderr," Sent CDP: (Ver=%u, TTL=%u) %s\n", tx.cdp_version, tx.cdp_ttl, pld);
716 if (delay) SLEEP (delay);
718 if (change_value)
720 // Note: this only works when default_id has been used
721 // because otherwise the TLV with the ID might be too short!!!
723 // Offset 26-36 contains 00000000000 (of the default id)
724 // ASCII 0x30-0x39 contain numbers 0-9
726 tx.eth_payload[26] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
727 tx.eth_payload[27] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
728 tx.eth_payload[28] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
729 tx.eth_payload[29] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
730 tx.eth_payload[30] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
731 tx.eth_payload[31] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
732 tx.eth_payload[32] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
733 tx.eth_payload[33] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
734 tx.eth_payload[34] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
735 tx.eth_payload[35] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
736 tx.eth_payload[36] = (u_int8_t) (0x30+ ((float) rand()/RAND_MAX)*10);
738 tx.eth_payload[10] = 0x00; // reset the checksum
739 tx.eth_payload[11] = 0x00;
740 tx.cdp_sum = checksum16(tx.eth_payload_s-8, tx.eth_payload+8);
741 x = (u_int8_t *) &tx.cdp_sum;
742 tx.eth_payload[10] = *(x+1);
743 tx.eth_payload[11] = *(x);
745 t = libnet_build_802_3 (tx.eth_dst,
746 tx.eth_src,
747 tx.eth_payload_s,
748 tx.eth_payload,
749 tx.eth_payload_s,
753 j++;
757 if (!count) goto AGAIN;
761 // Destroy contexts
762 libnet_destroy(l);
766 return t;