2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
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.
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
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
26 // Callback functions for the commands.
27 // __FUNCTION__ contains the name of the current callback function (for troubleshootig)
30 ////////////////////////////////////////////////////////////////////////////////
31 int cmd_test(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
33 cli_print(cli
, "called %s with %s\r\n", __FUNCTION__
, command
);
39 ////////////////////////////////////////////////////////////////////////////////
40 int debug_all (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
42 if ( strncmp(argv
[argc
-1], "?", 1) == 0)
44 cli_print(cli
, "Will debug everything. (Be careful!)\n");
50 cli_print(cli
, "Debug all enabled - stop with undebug all\r");
51 cli_print(cli
, "Note: _Already_ active packets will not be omitted!\n");
53 if (mz_strcmp(argv
[argc
-1], "dev", 3)==0)
55 cli_print(cli
, "*** Developer mode debugging enabled ***\n");
65 ////////////////////////////////////////////////////////////////////////////////
66 // Clear all _legacy_ Mausezahn settings (reinitialize anything)
67 int clear_all(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
70 cli_print(cli
, "No argument required! Try again.\n");
75 cli_print(cli
, "All legacy Mausezahn parts have been reinitialized.\r");
76 mops_delete_all(mp_head
);
77 mops_reset_packet (mp_head
);
78 cli_print(cli
, "MOPS has been reinitialized.\n");
83 int clear_packet(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
89 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) )
91 cli_print(cli
, "Delete a single packet (i. e. MOPS entry).\r");
92 cli_print(cli
, "Expects a single argument which is either a packet's ID or name.\r");
93 cli_print(cli
, "NOTE: If the name matches an ID then the name has higher preference.\n");
99 cli_print(cli
, "Please specify only the packets ID or name\n");
103 cur
= mops_search_name (mp_head
, argv
[0]);
105 i
= (u_int32_t
) str2int (argv
[0]);
106 cur
= mops_search_id (mp_head
, i
);
108 cli_print(cli
, "No packet found with that ID or name!\n");
112 clipkt
= mops_delete_packet(cur
);
113 cli_print(cli
, "Packet deleted.\n");
118 int cmd_reset_packet(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
123 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) )
125 cli_print(cli
, "Resets a single packet (i. e. MOPS entry).\r");
126 cli_print(cli
, "Expects a single argument which is either a packet's ID or name.\r");
127 cli_print(cli
, "NOTE: If the name matches an ID then the name has higher preference.\n");
133 cli_print(cli
, "Please specify only the packets ID or name\n");
137 cur
= mops_search_name (mp_head
, argv
[0]);
139 i
= (u_int32_t
) str2int (argv
[0]);
140 cur
= mops_search_id (mp_head
, i
);
142 cli_print(cli
, "No packet found with that ID or name!\n");
147 mops_reset_packet(cur
);
148 cli_print(cli
, "New packet name: %s\n", cur
->packet_name
);
155 int show_system(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
157 cli_print(cli
, "Not supported in this version\n");
164 ////////////////////////////////////////////////////////////////////////////////
165 // Run through packet list and print some details about existing packets.
169 // show packet MyPacket
171 int show_packets(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
173 int a
=0, i
, j
=0, k
, v
, active_only
=0;
176 char name
[32], ds
[16], pr
[16], ps
[16];
177 char myframe
[MAX_MOPS_FRAME_SIZE
*3];
179 char line
[150], line2
[150], line3
[150];
181 unsigned char *x0
, *x1
, *x2
, *x3
;
183 struct mops
*head
= mp_head
;
184 struct mops
*mp
= mp_head
;
187 if (strncmp(argv
[argc
-1], "?", 2)==0) {
188 cli_print(cli
, "<CR> Show list of all defined packets\r");
189 cli_print(cli
, "active Only show active packets\r");
190 cli_print(cli
, "<PKT_ID> Show detailed info about given packet\r");
191 //TODO cli_print(cli, "type <proto> Only list packets r");
192 cli_print(cli
, "\n");
197 if (mz_strcmp(argv
[0], "active", 1)==0) {
202 if ((argc
==0) || (active_only
)) // show packet summary
204 cli_print(cli
, "Packet layer flags: E=Ethernet, S=SNAP, Q=802.1Q, M=MPLS, I/i=IP/delivery_off, U=UDP, T=TCP\n");
205 cli_print(cli
, "PktID PktName Layers Proto Size State Device Delay Count/CntX\n");
210 if (mp
->state
< MOPS_STATE_ACTIVE
) {
221 if (mp
->use_ETHER
) strcat(ds
,"E"); else strcat(ds
,"-");
222 if (mp
->use_SNAP
) strcat(ds
,"S"); else strcat(ds
,"-");
223 if (mp
->use_dot1Q
) strcat(ds
,"Q"); else strcat(ds
,"-");
224 if (mp
->use_MPLS
) strcat(ds
,"M"); else strcat(ds
,"-");
226 if (mp
->auto_delivery_off
)
230 } else strcat(ds
,"-");
235 (mp
->use_TCP
) strcat(ds
,"T");
240 switch (mp
->p_desc_type
)
243 strncpy(pr
, "ARP", 8);
246 strncpy(pr
, "BPDU", 8);
249 strncpy(pr
, "CDP", 8);
252 strncpy(pr
, "DNS", 8);
255 strncpy(pr
, "ICMP", 8);
258 strncpy(pr
, "IGMP", 8);
261 strncpy(pr
, "LLDP", 8);
264 strncpy(pr
, "RTP", 8);
267 strncpy(pr
, "SYSLOG", 8);
274 switch (mops_state(mp
))
276 case MOPS_STATE_NULL
:
277 strcat(ps
, "NULL"); // should never happen!
279 case MOPS_STATE_INIT
:
282 case MOPS_STATE_CONFIG
:
283 strcat(ps
, "config");
285 case MOPS_STATE_ACTIVE
:
286 strcat(ps
, "active");
289 case MOPS_STATE_SEQACT
:
290 strcat(ps
, "actseq");
294 strcat(ps
, "unknown");
298 switch (mp
->interval_used
) {
299 case 1: // interval only configured, not started
300 strncat(ps
, "-i", 2);
304 strncat(ps
, "+I", 2);
311 strncpy (name
, mp
->packet_name
, 13); // only show first 13 chars
313 if (strnlen(mp
->packet_name
, MAX_MOPS_PACKET_NAME_LEN
)>13)
319 // To determine the actual packet length ***
320 // we must reassemble everything: ***
321 mops_ext_update (mp
);
324 timespec2str(&mp
->ndelay
, delay_str
);
326 // ID name lrs prot size state dev del count/cntx/%
327 sprintf(line
, "%5i %-16s %s %-8s %4i %-9s %-6s %10s%9lu/%lu (%i%%)\r",
334 mp
->device
, // device
336 mp
->count
, // Configured count value
337 mp
->cntx
, // Current count
338 (mp
->count
) ? (int) (100 * (mp
->count
- mp
->cntx
)/mp
->count
) : 0 );
339 cli_print(cli
, "%s\r", line
);
345 cli_print(cli
, "\r");
346 cli_print(cli
, "%i packets defined, %i active.\n", j
, a
);
348 //////////////////////////////////////////////////////////////////////////////////////////////////////////
350 //////////////////////////////////////////////////////////////////////////////////////////////////////////
351 else if (argc
== 1) // show details about a specific packet **********************************************
353 if ( (mp
= mops_search_name (mp_head
, argv
[0])) == NULL
)// not found
355 if ( (mp
= mops_search_id (mp_head
, (int) str2int(argv
[0]))) == NULL
)// not found
357 cli_print (cli
, "Packet not in list.\n");
362 // To determine the actual packet length ***
363 // we must reassemble everything: ***
364 mops_ext_update (mp
);
367 cli_print(cli
, "Packet [%i] %s\r", mp
->id
, mp
->packet_name
);
368 cli_print(cli
, " Description: %s \r",
369 (strnlen(mp
->description
, MAX_MOPS_DESCRIPTION_LEN
)) ? mp
->description
: "(no description)");
373 case MOPS_STATE_NULL
:
374 sprintf(mystate
, "NULL");
376 case MOPS_STATE_INIT
:
377 sprintf(mystate
, "init");
379 case MOPS_STATE_CONFIG
:
380 sprintf(mystate
, "config");
382 case MOPS_STATE_ACTIVE
:
383 sprintf(mystate
, "active(tx)");
386 sprintf(mystate
, "unknown");
389 timespec2str(&mp
->ndelay
, delay_str
);
390 if (mp
->interval_used
)
391 timespec2str(&mp
->interval
, line2
);
393 sprintf(line2
, "(undefined)");
395 sprintf(line
, "State: %s, Count=%lu, delay=%s (%lu s %lu nsec), interval= %s\r",
402 cli_print(cli
, " %s\r", line
);
404 cli_print(cli
, " Headers:\r");
408 if (mp
->eth_src_israndom
)
410 cli_print(cli
, " Ethernet: *** RANDOMIZED SMAC *** => %02x-%02x-%02x-%02x-%02x-%02x [%04x%s]\r",
411 mp
->eth_dst
[0],mp
->eth_dst
[1],mp
->eth_dst
[2],mp
->eth_dst
[3],mp
->eth_dst
[4],mp
->eth_dst
[5],
412 mp
->eth_type
, (mp
->use_dot1Q
) ? " after 802.1Q tag" : "");
416 cli_print(cli
, " Ethernet: %02x-%02x-%02x-%02x-%02x-%02x => %02x-%02x-%02x-%02x-%02x-%02x [%04x%s]\r",
417 mp
->eth_src
[0],mp
->eth_src
[1],mp
->eth_src
[2],mp
->eth_src
[3],mp
->eth_src
[4],mp
->eth_src
[5],
418 mp
->eth_dst
[0],mp
->eth_dst
[1],mp
->eth_dst
[2],mp
->eth_dst
[3],mp
->eth_dst
[4],mp
->eth_dst
[5],
419 mp
->eth_type
, (mp
->use_dot1Q
) ? " after 802.1Q tag" : "");
423 if (mp
->auto_delivery_off
)
424 cli_print(cli
, " NOTE: Auto-delivery is OFF (that is, the destination MAC is fixed)\r");
426 cli_print(cli
, " Auto-delivery is ON (that is, the actual MAC is determined upon transmission)\r");
432 bs2str(clipkt
->eth_snap
, line
, clipkt
->eth_snap_s
);
433 cli_print(cli
, " LLC/SNAP: %s\r", line
);
438 k
= clipkt
->dot1Q_s
/4; // number of tags
439 sprintf(line
, "%i tag(s); ", k
);
441 { // tag format = 0x81 0x00 cosTvvvv vvvvvvvv
443 x0
= (unsigned char*) &clipkt
->dot1Q
[(j
*4)+2];
444 x1
= (unsigned char*) &clipkt
->dot1Q
[(j
*4)+3];
445 v
= (*x0
& 0x0f)*256 + *x1
; // VLAN
446 // c = *x0 & 0xe0; // CoS e0=11100000
448 sprintf(ds
, "%i:%i%s",
451 (*x0
& 0x10) ? "[CFI]" : ""); // CFI
452 strncat(line
, ds
, 14);
453 if (j
<(k
-1)) strcat(line
, ", ");
456 cli_print(cli
, " 802.1Q: %s (VLAN:CoS)\r", line
);
461 k
= clipkt
->mpls_s
/4; // number of tags
462 sprintf(line
, "%i tag(s); ", k
);
464 { // tag format = llllllll llllllll llllcccB TTTTTTTT
465 x0
= (unsigned char*) &clipkt
->mpls
[(j
*4)+0];
466 x1
= (unsigned char*) &clipkt
->mpls
[(j
*4)+1];
467 x2
= (unsigned char*) &clipkt
->mpls
[(j
*4)+2];
468 x3
= (unsigned char*) &clipkt
->mpls
[(j
*4)+3];
472 t
+= (*x2
& 0xf0) >> 4;
473 c
= (*x2
& 0x0e) >> 1;
475 sprintf(ds
, "%i:%i:%i%s",
479 (*x2
& 0x01) ? "[BoS]" : ""); // Bottom of Stack?
480 strncat(line
, ds
, 20);
481 if (j
<(k
-1)) strcat(line
, ", ");
484 cli_print(cli
, " MPLS: %s (Label:CoS:TTL)\r", line
);
490 // Source IP settings:
491 x0
= (unsigned char*) & clipkt
->ip_src
;
493 if (clipkt
->ip_src_isrange
)
495 x1
= (unsigned char*) & clipkt
->ip_src_start
;
496 x2
= (unsigned char*) & clipkt
->ip_src_stop
;
497 sprintf(line2
, "%u.%u.%u.%u-%u.%u.%u.%u",
498 (unsigned char) *(x1
+3), (unsigned char) *(x1
+2), (unsigned char) *(x1
+1) , (unsigned char) *x1
,
499 (unsigned char) *(x2
+3), (unsigned char) *(x2
+2), (unsigned char) *(x2
+1) , (unsigned char) *x2
);
501 sprintf(line
, "SA=%u.%u.%u.%u %s %s %s",
502 (unsigned char) *(x0
+3), (unsigned char) *(x0
+2), (unsigned char) *(x0
+1) , (unsigned char) *x0
,
503 (clipkt
->ip_src_israndom
) ? "RANDOM" : "(not random)",
504 (clipkt
->ip_src_isrange
) ? "RANGE:" : "(no range)",
507 cli_print(cli
, " IP: %s\r", line
);
508 //Destination IP settings:
509 x0
= (unsigned char*) & clipkt
->ip_dst
;
511 if (clipkt
->ip_dst_isrange
)
513 x1
= (unsigned char*) & clipkt
->ip_dst_start
;
514 x2
= (unsigned char*) & clipkt
->ip_dst_stop
;
515 sprintf(line2
, "%u.%u.%u.%u-%u.%u.%u.%u",
516 (unsigned char) *(x1
+3), (unsigned char) *(x1
+2), (unsigned char) *(x1
+1) , (unsigned char) *x1
,
517 (unsigned char) *(x2
+3), (unsigned char) *(x2
+2), (unsigned char) *(x2
+1) , (unsigned char) *x2
);
520 sprintf(line
, "DA=%u.%u.%u.%u %s %s",
521 (unsigned char) *(x0
+3), (unsigned char) *(x0
+2), (unsigned char) *(x0
+1) , (unsigned char) *x0
,
522 (clipkt
->ip_dst_isrange
) ? "RANGE:" : "(no range)",
524 cli_print(cli
, " %s\r", line
);
526 sprintf(line
, "ToS=0x%02x proto=%u TTL=%u ID=%u offset=%u flags: %s|%s|%s",
527 clipkt
->ip_tos
, clipkt
->ip_proto
, clipkt
->ip_ttl
, clipkt
->ip_id
, clipkt
->ip_frag_offset
,
528 (clipkt
->ip_flags_RS
) ? "RS" : "-",
529 (clipkt
->ip_flags_DF
) ? "DF" : "-",
530 (clipkt
->ip_flags_MF
) ? "MF" : "-");
532 cli_print(cli
, " %s\r", line
);
534 if (clipkt
->ip_fragsize
) {
535 sprintf(line
, "NOTE: Auto-fragmentation is ON! Fragment size %u bytes, overlap %u",
537 clipkt
->ip_frag_overlap
);
538 cli_print(cli
, " %s\r", line
);
541 sprintf(line
, "len=%u(%s) checksum=0x%02x%02x(%s)",
542 clipkt
->frame
[clipkt
->begin_IP
+2]*256+clipkt
->frame
[clipkt
->begin_IP
+3],
543 (clipkt
->ip_len_false
) ? "false" : "correct",
544 clipkt
->frame
[clipkt
->begin_IP
+10],
545 clipkt
->frame
[clipkt
->begin_IP
+11],
546 (clipkt
->ip_sum_false
) ? "false" : "correct");
548 cli_print(cli
, " %s\r", line
);
554 if (clipkt
->sp_isrange
)
555 sprintf(line2
, "RANGE: %u-%u", clipkt
->sp_start
, clipkt
->sp_stop
);
557 sprintf(line2
, "(norange)");
558 if (clipkt
->dp_isrange
)
559 sprintf(line3
, "RANGE: %u-%u", clipkt
->dp_start
, clipkt
->dp_stop
);
561 sprintf(line3
, "(norange)");
562 sprintf(line
, "SP=%i %s %s, DP=%i %s %s\r",
565 (clipkt
->sp_isrand
) ? "RANDOM" : "(not random)",
568 (clipkt
->dp_isrand
) ? "RANDOM" : "(not random)");
569 cli_print(cli
, " UDP: %s\r", line
);
570 sprintf(line
, "checksum= %04x (%s), length= %u (%s)",
571 clipkt
->udp_sum
, (clipkt
->udp_sum_false
) ? "false" : "correct",
572 clipkt
->udp_len
, (clipkt
->udp_len_false
) ? "false" : "correct");
573 cli_print(cli
, " %s\r", line
);
578 sprintf(line
, "%u bytes segment size (including TCP header)", mp
->tcp_len
);
579 cli_print(cli
, " TCP: %s\r", line
);
580 if (clipkt
->sp_isrange
)
581 sprintf(line2
, "RANGE: %u-%u", clipkt
->sp_start
, clipkt
->sp_stop
);
583 sprintf(line2
, "(norange)");
584 if (clipkt
->dp_isrange
)
585 sprintf(line3
, "RANGE: %u-%u", clipkt
->dp_start
, clipkt
->dp_stop
);
587 sprintf(line3
, "(norange)");
588 sprintf(line
, "SP=%i %s %s, DP=%i %s %s\r",
591 (clipkt
->sp_isrand
) ? "RANDOM" : "(not random)",
594 (clipkt
->dp_isrand
) ? "RANDOM" : "(not random)");
595 cli_print(cli
, " %s\r", line
);
596 sprintf(line
, "SQNR=%u (start %u, stop %u, delta %u) -- ACKNR=%u %s",
598 clipkt
->tcp_seq_start
,
599 clipkt
->tcp_seq_stop
,
600 clipkt
->tcp_seq_delta
,
602 (clipkt
->tcp_ctrl_ACK
) ? "(valid)" : "(invalid)");
603 cli_print(cli
, " %s\r", line
);
604 mops_tcp_flags2str(clipkt
,line2
);
605 sprintf(line
, "Flags: %s, reserved field is %02x, urgent pointer= %u",
609 cli_print(cli
, " %s\r", line
);
610 sprintf(line
, "Announced window size= %u", clipkt
->tcp_win
);
611 cli_print(cli
, " %s\r", line
);
612 sprintf(line
, "Offset= %u (times 32 bit; value is %s), checksum= %04x (%s)",
614 (clipkt
->tcp_offset_false
) ? "FALSE" : "valid",
616 (clipkt
->tcp_sum_false
) ? "FALSE" : "valid");
617 cli_print(cli
, " %s\r", line
);
618 sprintf(line
, "%s - %u bytes defined",
619 (clipkt
->tcp_option_used
) ? "TCP options attached" : "(No TCP options attached)",
620 clipkt
->tcp_option_s
);
621 cli_print(cli
, " %s\r", line
);
625 if (!i
) cli_print(cli
, " No headers defined.\r");
628 cli_print(cli
, " Payload size: %i bytes\r", mp
->msg_s
);
631 cli_print(cli
, " Frame size: %i bytes\n", mp
->frame_s
);
633 mops_print_frame(mp
, myframe
);
634 cli_print(cli
, "%s\n", myframe
);
641 ////////////////////////////////////////////////////////////////////////////////
642 int show_interfaces (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
649 if (strncmp(argv
[argc
-1], "?", 2)==0) {
650 cli_print(cli
, "<CR> Show summary list of all interfaces found\r");
651 cli_print(cli
, "detailed Additionally show network, mask, default gatway, and MTU\r");
652 cli_print(cli
, "\n");
656 // Some safety checks
657 if (argc
>1) return CLI_OK
;
659 if (mz_strcmp(argv
[0], "detailed", 1)!=0) {
660 cli_print(cli
, "invalid keyword (use ?)\n");
665 /* Refresh interface data */
669 for (i
=0; i
<device_list_entries
; i
++) {
670 get_dev_params(device_list
[i
].dev
);
675 /* No additional keyword */
677 cli_print(cli
, "Available network interfaces:\n");
678 cli_print(cli
, " real real used (fake) used (fake)\r");
679 cli_print(cli
, " device IPv4 address MAC address IPv4 address MAC address\r");
680 cli_print(cli
, "---------------------------------------------------------------------------------------\r");
681 for (i
=0; i
<device_list_entries
; i
++) {
682 sprintf(ip
,"%u.%u.%u.%u",
683 device_list
[i
].ip_mops
[0],
684 device_list
[i
].ip_mops
[1],
685 device_list
[i
].ip_mops
[2],
686 device_list
[i
].ip_mops
[3]);
688 sprintf(line
, "%-10s %-15s %02x:%02x:%02x:%02x:%02x:%02x %-15s %02x:%02x:%02x:%02x:%02x:%02x",
689 device_list
[i
].dev
, device_list
[i
].ip_str
,
690 device_list
[i
].mac
[0],
691 device_list
[i
].mac
[1],
692 device_list
[i
].mac
[2],
693 device_list
[i
].mac
[3],
694 device_list
[i
].mac
[4],
695 device_list
[i
].mac
[5],
697 device_list
[i
].mac_mops
[0],
698 device_list
[i
].mac_mops
[1],
699 device_list
[i
].mac_mops
[2],
700 device_list
[i
].mac_mops
[3],
701 device_list
[i
].mac_mops
[4],
702 device_list
[i
].mac_mops
[5]
706 if (strncmp(device_list
[i
].dev
, tx
.device
, 16)==0) {
707 cli_print(cli
, "%s%s> %s\r",
708 (device_list
[i
].cli
) ? "C" : " ",
709 (device_list
[i
].mgmt_only
) ? "!" : "",
714 cli_print(cli
, "%s%s %s\r",
715 (device_list
[i
].cli
) ? "C" : " ",
716 (device_list
[i
].mgmt_only
) ? "M" : "",
720 /////////////////////////
723 /* keyword detailed used */
724 if (mz_strcmp(argv
[0], "detailed", 1)==0) {
725 cli_print(cli
, "Detailed interface list:\n");
726 for (i
=0; i
<device_list_entries
; i
++) {
727 sprintf(line
, "interface %s [%i] %s%stype %s, MTU=%i bytes", // general HW info
729 device_list
[i
].index
,
730 (device_list
[i
].cli
) ? "[cli] " : "",
731 (device_list
[i
].mgmt_only
) ? "[management-only] " : "",
732 (device_list
[i
].phy
) ? "physical" : "software",
734 cli_print(cli
,"%s\r",line
);
735 sprintf(line
, "MAC bia: %02x:%02x:%02x:%02x:%02x:%02x\n MAC fake: %02x:%02x:%02x:%02x:%02x:%02x",
736 device_list
[i
].mac
[0],
737 device_list
[i
].mac
[1],
738 device_list
[i
].mac
[2],
739 device_list
[i
].mac
[3],
740 device_list
[i
].mac
[4],
741 device_list
[i
].mac
[5],
742 device_list
[i
].mac_mops
[0],
743 device_list
[i
].mac_mops
[1],
744 device_list
[i
].mac_mops
[2],
745 device_list
[i
].mac_mops
[3],
746 device_list
[i
].mac_mops
[4],
747 device_list
[i
].mac_mops
[5]);
748 cli_print(cli
," %s\r",line
);
749 sprintf(line
,"IP addr: %s mask %u.%u.%u.%u (net %u.%u.%u.%u)",
750 device_list
[i
].ip_str
,
751 device_list
[i
].mask
[0],
752 device_list
[i
].mask
[1],
753 device_list
[i
].mask
[2],
754 device_list
[i
].mask
[3],
755 device_list
[i
].net
[0],
756 device_list
[i
].net
[1],
757 device_list
[i
].net
[2],
758 device_list
[i
].net
[3]);
759 cli_print(cli
," %s\r",line
);
760 sprintf(line
,"IP fake: %u.%u.%u.%u",
761 device_list
[i
].ip_mops
[0],
762 device_list
[i
].ip_mops
[1],
763 device_list
[i
].ip_mops
[2],
764 device_list
[i
].ip_mops
[3]);
765 cli_print(cli
, " %s\r", line
);
766 sprintf(line
,"GW addr: %u.%u.%u.%u (%02x:%02x:%02x:%02x:%02x:%02x)",
767 device_list
[i
].ip_gw
[0],
768 device_list
[i
].ip_gw
[1],
769 device_list
[i
].ip_gw
[2],
770 device_list
[i
].ip_gw
[3],
771 device_list
[i
].mac_gw
[0],
772 device_list
[i
].mac_gw
[1],
773 device_list
[i
].mac_gw
[2],
774 device_list
[i
].mac_gw
[3],
775 device_list
[i
].mac_gw
[4],
776 device_list
[i
].mac_gw
[5]);
777 cli_print(cli
," %s\n",line
);
781 /* In any case, print final summary line: */
782 cli_print(cli
, "\n%i interfaces found.\nDefault interface is %s.\n",
783 device_list_entries
, device_list
[j
].dev
);
790 ////////////////////////////////////////////////////////////////////////////////
791 int show_set(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
794 char hexload
[3*MAX_PAYLOAD_SIZE
];
796 cli_print(cli
, "----- Packet parameters: ------ -------- Value: ----------\r");
797 cli_print(cli
, "Source MAC address (sa) %02x:%02x:%02x:%02x:%02x:%02x [%s]\r",
798 tx
.eth_src
[0], tx
.eth_src
[1], tx
.eth_src
[2],
799 tx
.eth_src
[3], tx
.eth_src
[4], tx
.eth_src
[5],
800 (tx
.eth_src_rand
) ? "rand" : "spec");
801 cli_print(cli
, "Basic MAC address %02x:%02x:%02x:%02x:%02x:%02x\r",
802 tx
.eth_mac_own
[0], tx
.eth_mac_own
[1], tx
.eth_mac_own
[2],
803 tx
.eth_mac_own
[3], tx
.eth_mac_own
[4], tx
.eth_mac_own
[5]);
804 cli_print(cli
, "Destination MAC address (da) %02x:%02x:%02x:%02x:%02x:%02x [%s]\r",
805 tx
.eth_dst
[0], tx
.eth_dst
[1], tx
.eth_dst
[2],
806 tx
.eth_dst
[3], tx
.eth_dst
[4], tx
.eth_dst
[5],
807 (tx
.eth_dst_rand
) ? "rand" : "spec");
808 cli_print(cli
, "\r");
809 x
= (unsigned char *) &tx
.ip_src
;
810 cli_print(cli
, "Source IP address (SA) %i.%i.%i.%i [%s]\r",
811 *x
,*(x
+1),*(x
+2),*(x
+3),
812 (tx
.ip_src_rand
) ? "rand" : "spec");
814 if (tx
.ip_src_isrange
)
816 x
= (unsigned char *) &tx
.ip_src_start
;
817 cli_print(cli
, "Source IP range start: %i.%i.%i.%i\r",
818 *(x
+3), *(x
+2), *(x
+1), *x
);
819 x
= (unsigned char *) &tx
.ip_src_stop
;
820 cli_print(cli
, "Source IP range stop: %i.%i.%i.%i\r",
821 *(x
+3), *(x
+2), *(x
+1), *x
);
825 cli_print(cli
, "No source IP range specified\r");
827 x
= (unsigned char *) &tx
.ip_dst
;
828 cli_print(cli
, "Destination IP address (DA) %i.%i.%i.%i\r",
829 *x
,*(x
+1),*(x
+2),*(x
+3));
831 if (tx
.ip_dst_isrange
)
833 x
= (unsigned char *) &tx
.ip_dst_start
;
834 cli_print(cli
, "Destination IP range start: %i.%i.%i.%i\r",
835 *(x
+3), *(x
+2), *(x
+1), *x
);
836 x
= (unsigned char *) &tx
.ip_dst_stop
;
837 cli_print(cli
, "Destination IP range stop: %i.%i.%i.%i\r",
838 *(x
+3), *(x
+2), *(x
+1), *x
);
842 cli_print(cli
, "No destination IP range specified\r");
847 cli_print(cli
, "802.1Q tags specified: %s\r", tx
.dot1Q_txt
);
852 cli_print(cli
, "MPLS labels specified: %s\r", tx
.mpls_txt
);
856 { cli_print(cli
, "\r");
857 cli_print(cli
, "---- ASCII payload is set: ----- \r");
858 cli_print(cli
, ">>>%s<<<\r", tx
.ascii_payload
);
859 cli_print(cli
, "-------------------------------- \n");
862 if (tx
.hex_payload_s
)
863 { cli_print(cli
, "\r");
864 cli_print(cli
, "---- Hexadecimal payload is set: ----- \r");
865 bs2str(tx
.hex_payload
, hexload
, tx
.hex_payload_s
);
866 cli_print(cli
, "%s\r", hexload
);
867 cli_print(cli
, "-------------------------------------- \n");
872 cli_print(cli
, "Configured padding: %u\r", tx
.padding
);
875 cli_print(cli
, "\r");
876 cli_print(cli
, "Packet count value %u\r", tx
.count
);
877 cli_print(cli
, "Interpacket delay (usec) %u\r", tx
.delay
);
878 cli_print(cli
, "\r");
879 cli_print(cli
, "Used network device(s): %s\r", tx
.device
);
880 cli_print(cli
, "\n");
890 ////////////////////////////////////////////////////////////////////////////////
891 int stop_mausezahn (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
893 if (strncmp(argv
[argc
-1], "?", 2)==0) {
894 cli_print(cli
, "now Terminate the mausezahn server! BEWARE!\n");
899 cli_print(cli
, "The only allowed argument is 'now' -- anything else is ignored\n");
903 if (mz_strcmp(argv
[0], "now", 3)==0) {
904 cli_print(cli
, "Good bye...\n");
909 cli_print(cli
, "Invalid argument. If you want to stop the Mausezahn server then\r");
910 cli_print(cli
, "enter 'terminate now'. You cannot abbreviate the argument 'now'. \n");
919 int cmd_run_id (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
925 cli_print(cli
, "Specify one or more packet identifiers to run.\n");
929 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
930 cli_print(cli
, "Run packet transmission processes for given list of packet identifiers\n");
934 // User provided packet id numbers
936 for (i
=0; i
<argc
; i
++) {
937 slot
= (int) str2int(argv
[i
]);
938 if ( (mp
= mops_search_id (mp_head
, slot
)) == NULL
) { // not found
939 cli_print (cli
, "Packet %i not in list.\n", slot
);
943 switch (mops_tx_simple (mp
)) {
945 cli_print(cli
, "Cannot create sending process.\r");
949 cli_print(cli
, "Packet [%i] has already an active sending process\r", mp
->id
);
953 cli_print (cli
, "Activate [%i] ", slot
);
958 cli_print (cli
, "\n");
964 int cmd_run_name (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
970 cli_print(cli
, "Specify one or more packet name(s) to run.\n");
974 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
975 cli_print(cli
, "Run packet transmission processes for specified packet name(s).\n");
980 for (i
=0; i
<argc
; i
++) {
981 if ( (mp
= mops_search_name (mp_head
, argv
[i
])) == NULL
) { // not found
982 cli_print (cli
, "Packet %s not in list.\n", argv
[i
]);
986 switch (mops_tx_simple (mp
)) {
988 cli_print(cli
, "Cannot create sending process.\r");
992 cli_print(cli
, "Packet [%i] has already an active sending process\r", mp
->id
);
996 cli_print (cli
, "Activate [%i] ", mp
->id
);
1001 cli_print (cli
, "\n");
1007 int cmd_run_sequence (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1012 cli_print(cli
, "Specify one (and only one) packet sequence name to run.\n");
1016 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
1017 cli_print(cli
, "Run sequence transmission processes for specified sequence name.\n");
1021 cur
= mz_ll_search_name (packet_sequences
, argv
[0]);
1022 if (cur
==NULL
) { // NOT FOUND !!!
1023 cli_print(cli
, "Sequence %s does not exist.", argv
[0]);
1026 ret
= mops_tx_sequence(cur
);
1028 case 0: cli_print(cli
, "Sequence %s is running\n", cur
->name
);
1030 case 1: cli_print(cli
, "Cannot run sequence: All packets must be in config state!\n");
1032 case 2: cli_print(cli
, "Cannot run sequence: All packets must have a finite count!\n");
1034 case 3: cli_print(cli
, "Cannot run sequence: Unable to start sequence transmission process.\n");
1042 int cmd_run_all (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1048 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
1049 cli_print(cli
, "Run all user-specified packets.\n");
1054 cli_print(cli
, "No arguments expected!\n");
1058 // Send all valid packets
1063 if ((mp
->mz_system
==0) && (mops_state(mp
) == MOPS_STATE_CONFIG
)) {
1064 switch (mops_tx_simple (mp
)) {
1066 cli_print(cli
, "Cannot create sending process.\r");
1070 cli_print(cli
, "Packet [%i] has already an active sending process\r", mp
->id
);
1077 cli_print (cli
, "Activate [%i] %s\r", mp
->id
, mp
->packet_name
);
1083 cli_print (cli
, "No valid packets found\n");
1085 cli_print (cli
, "\r");
1086 cli_print (cli
, "Activated %i packets \n", i
);
1093 int cmd_stop (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1096 int i
, ret
=0, slot
=0;
1098 struct mops
*head
= mp_head
;
1099 struct mops
*cur
= mp_head
;
1101 if ((strncmp(argv
[argc
-1], "?", 2)==0) || (argc
==0)) {
1102 cli_print(cli
, "Stop transmission process(es) or an active sequence.\r");
1103 cli_print(cli
, "SYNTAX: 1) Either specify one or more packet-ids or packet names of active packets\r");
1104 cli_print(cli
, " 2) Or enter 'sequence <seq-name>' to stop an active sequence and its associated packets.\n");
1108 // Did the user specify a sequence? (ONE SEQUENCE ONLY)
1109 if ((mz_strcmp(argv
[0], "sequence", 3)==0) && (argc
==2)) {
1110 ret
= stop_sequence (argv
[1]);
1113 cli_print(cli
, "Sequence '%s' stopped.\n", argv
[1]);
1117 cli_print(cli
, "Sequence '%s' does not exist!\n", argv
[1]);
1120 cli_print(cli
, "Sequence '%s' is not active. Nothing to stop.\n", argv
[1]);
1127 if (((mz_strcmp(argv
[0], "all", 3)==0) || (mz_strcmp(argv
[0], "*", 1)==0)) && (argc
==1)) {
1129 cli_print(cli
, "Stopping ");
1131 if (mops_destroy_thread (cur
)==0) {
1133 cli_print(cli
, "[%i] %s", cur
->id
, cur
->packet_name
);
1137 while (head
!= cur
);
1138 cli_print(cli
, "\n");
1140 cli_print(cli
, "Stopped %i transmission processe(s)\r", i
);
1143 cli_print(cli
, "No active transmission processes found.\r");
1146 i
= stop_all_sequences ();
1148 cli_print(cli
, "Stopped %i sequence(s)\n", i
);
1151 cli_print(cli
, "No active sequences found.\n");
1157 // Stop all specified packets:
1159 for (i
=0; i
<argc
; i
++) {
1161 // is argv[i] a numerical pkt-id?
1162 if (mz_strisnum(argv
[i
])) {
1163 slot
= (int) str2int(argv
[i
]);
1164 mp
= mops_search_id (mp_head
, slot
);
1166 // still not found? Is it a name?
1167 if (mp
==NULL
) mp
= mops_search_name (mp_head
, argv
[i
]);
1168 if (mp
==NULL
) cli_print(cli
, "Packet '%s' not in list!\r",argv
[i
]);
1169 else { // packet found:
1170 if (mops_destroy_thread (mp
)) {
1171 cli_print(cli
, "Packet [%i] '%s' has no associated transmission process (nothing to stop).\r", mp
->id
, mp
->packet_name
);
1173 cli_print (cli
, "Stopped transission process for packet [%i] '%s'.\r", mp
->id
, mp
->packet_name
);
1177 cli_print(cli
, "\r");
1183 int show_mops(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1187 if (strncmp(argv
[argc
-1], "?", 2)==0) {
1188 cli_print(cli
, "<ENTER> Check MOPS version and details\n");
1192 cli_print(cli
, "-----------------------------------------------------\r");
1193 cli_print(cli
, "Mops version %s [%s]\n", MOPS_VERSION
, MOPS_CODENAME
);
1194 cli_print(cli
, "Maximum packet sequence length is %i packets\r", MAX_PACKET_SEQUENCE_LEN
);
1195 cli_print(cli
, "Maximum frame size is %i bytes\r", MAX_MOPS_FRAME_SIZE
);
1196 cli_print(cli
, "Minimum frame size is %i bytes\r", MIN_MOPS_FRAME_SIZE
);
1197 cli_print(cli
, "PCAP readout delay is %i msec\r", PCAP_READ_TIMEOUT_MSEC
);
1198 cli_print(cli
, "Maximum payload size is %i bytes\r", MAX_MOPS_MSG_SIZE
);
1199 cli_print(cli
, "Maximum chunk size is %i bytes\r", MAX_MOPS_MSG_CHUNK_SIZE
);
1200 cli_print(cli
, "Maximum counters per packet is %i\r", MAX_MOPS_COUNTERS_PER_PACKET
);
1201 cli_print(cli
, "Maximum number of 802.1Q tags is %i\r", MAX_MOPS_DOT1Q_TAGS
);
1202 cli_print(cli
, "Maximum number of MPLS tags is %i\r", MAX_MOPS_MPLS_TAGS
);
1203 cli_print(cli
, "Maximum length of packet names is %i characters\r", MAX_MOPS_PACKET_NAME_LEN
);
1204 cli_print(cli
, "Maximum length of packet descriptions is %i characters\r", MAX_MOPS_DESCRIPTION_LEN
);
1205 cli_print(cli
, "Bytes per line for formatted frame output %i\r", MAX_CLI_LINE_BYTES
);
1206 cli_print(cli
, "Maximum LLDP optional section length is %i bytes\r", MAX_LLDP_OPT_TLVS
);
1207 if (AUTOMOPS_ENABLED
) {
1208 cli_print(cli
, "Auto-MOPS subsystem is enabled\r");
1209 cli_print(cli
, " Maximum nesting depth is %i\r", XN_MAX_STACK
);
1210 cli_print(cli
, " Maximum file size for protocol definitions is %i\r", AUTOMOPS_MAX_FILE_SIZE
);
1211 cli_print(cli
, " Maximum names length is %i\r", AUTOMOPS_MAX_NAME_LEN
);
1212 cli_print(cli
, " Maximum short description length is %i\r", AUTOMOPS_MAX_SHORTDESC_LEN
);
1213 cli_print(cli
, " Maximum XML tag length is %i\r", XML_MAX_TAG_LEN
);
1214 } else cli_print(cli
, "Auto-MOPS subsystem is disabled\r");
1216 if (mops_dump_all(mp_head
, tmp
)) {
1217 cli_print(cli
, "No mopses found.\n"); // keine Möpse gefunden ;-)
1219 cli_print(cli
, "%s\n", tmp
);
1228 int cmd_reset_interface (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1232 if (strncmp(argv
[argc
-1], "?", 2)==0) {
1233 cli_print(cli
, "<ENTER> Check MOPS version and details\n");
1238 cli_print(cli
, "Unknown parameter\n");
1244 for (i
=0; i
<device_list_entries
; i
++) {
1245 get_dev_params(device_list
[i
].dev
);
1246 // refresh ARP table i. e. MAC addresses of default GWs
1247 service_arp(device_list
[i
].dev
, device_list
[i
].ip_gw
, device_list
[i
].mac_gw
);
1256 int conf_frame_limit (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1260 if (strncmp(argv
[argc
-1], "?", 2)==0)
1262 cli_print(cli
, "Configure global frame size limits:\n");
1263 cli_print(cli
, " <min-frame-size> [max-frame-size]\n");
1269 cli_print(cli
, "Two arguments allowed: <min-frame-size> [max-frame-size]\n");
1273 tmp
= (unsigned int) str2int (argv
[0]);
1274 if (tmp
< MIN_MOPS_FRAME_SIZE
)
1276 cli_print(cli
, "This Mausezahn requires that the minimum frame size is at least %i bytes\n", MIN_MOPS_FRAME_SIZE
);
1280 if (tmp
>(max_frame_s
-2))
1282 cli_print(cli
, "The minimum frame size must be below %i bytes\n", max_frame_s
-1);
1290 tmp
= (unsigned int) str2int (argv
[1]);
1292 if (tmp
> MAX_MOPS_FRAME_SIZE
-MOPS_SIZE_MARGIN
)
1294 cli_print(cli
, "This Mausezahn requires that the maximum frame size is not greater than %i bytes\n",
1295 MAX_MOPS_FRAME_SIZE
-MOPS_SIZE_MARGIN
);
1299 if (tmp
<(min_frame_s
+2))
1301 cli_print(cli
, "The maximum frame size must be greater than %i bytes\n", min_frame_s
+1);
1314 int cmd_load (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1319 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) ) {
1320 cli_print(cli
, "Load commands from one or more specified file(s)\r");
1321 cli_print(cli
, "\n");
1326 cli_print(cli
, "Specify one or more configuration files\n");
1330 for (i
=0; i
<argc
; i
++) {
1331 fp
= fopen(argv
[i
], "r");
1333 cli_print(cli
, "Warning: Cannot read %s\n", argv
[i
]);
1336 cli_print(cli
, "Read commands from %s...\n", argv
[i
]);
1337 cli_file (cli
, fp
, PRIVILEGE_PRIVILEGED
, MODE_EXEC
);
1338 if (fclose(fp
) == EOF
)
1340 cli_print(cli
, "Warning: problems closing %s (errno=%i)\n", argv
[i
],errno
);
1348 int show_arp (struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1351 struct arp_table_struct
*cur
;
1352 char s
[128], ip
[20], uc
[16], bc
[16], ch
[16];
1353 struct mz_timestamp now
, prev
, result
;
1357 if (strcmp(argv
[argc
-1],"?")==0) {
1358 cli_print(cli
, "<CR> shows the advanced Mausezahn ARP table\n");
1363 cli_print(cli
, "Unknown parameter\n");
1368 cli_print(cli
, "Intf Index IP address MAC address last Ch UCast BCast Info\r");
1369 cli_print(cli
, "----------------------------------------------------------------------------------\r");
1370 // ------------------------------------------------------------------------------
1371 // wlan0 [1] DL 192.168.0.1 at 00:09:5b:9a:15:84 3'42'' 1
1373 for (i
=0; i
<device_list_entries
; i
++) {
1374 cur
=device_list
[i
].arp_table
;
1376 sprintf(ip
,"%i.%i.%i.%i",cur
->sip
[0],cur
->sip
[1],cur
->sip
[2],cur
->sip
[3]);
1377 if (cur
->changed
>99999) mz_strncpy(ch
,"ALERT",6); else sprintf(ch
,"%lu", cur
->changed
);
1378 if (cur
->uni_resp
>99999) mz_strncpy(uc
,"ALERT",6); else sprintf(uc
,"%lu", cur
->uni_resp
);
1379 if (cur
->bc_resp
>99999) mz_strncpy(bc
,"ALERT",6); else sprintf(bc
,"%lu", cur
->bc_resp
);
1380 sprintf(s
, "%-7s [%i] %s%s %15s %02x:%02x:%02x:%02x:%02x:%02x %8s %5s %5s %5s %04x",
1383 (cur
->dynamic
) ? "D" : "U",
1384 (cur
->locked
) ? "L" : "",
1397 cli_print(cli
, "%s\r", s
);
1398 if (cur
->changed
>1) {
1400 now
.nsec
= cur
->nsec
;
1401 prev
.sec
= cur
->sec_prev
;
1402 prev
.nsec
= cur
->nsec_prev
;
1403 printf("sec=%u nsec=%u sec=%u nsec=%u\n", cur
->sec
, cur
->nsec
, cur
->sec_prev
, cur
->nsec_prev
);
1404 timestamp_subtract(&now
, &prev
, &result
);
1405 sprintf(s
," previous MAC was: %02x:%02x:%02x:%02x:%02x:%02x time delta: %u sec %u msec",
1412 (unsigned int) result
.sec
, (unsigned int) result
.nsec
/1000000);
1413 cli_print(cli
, " %s\r", s
);
1423 // general 'end' command to return to global config mode
1424 int cmd_end_to_config(struct cli_def
*cli
, const char *command
, char *argv
[], int argc
)
1426 cli_set_configmode(cli
, MODE_CONFIG
, NULL
);