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
, 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
, 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
, 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
, 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
, 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 ////////////////////////////////////////////////////////////////////////////////
156 int warranty(struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
158 cli_print(cli
, MZ_WARRANTY_TEXT
);
163 int show_system(struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
165 cli_print(cli
, "Not supported in this version\n");
172 ////////////////////////////////////////////////////////////////////////////////
173 // Run through packet list and print some details about existing packets.
177 // show packet MyPacket
179 int show_packets(struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
181 int a
=0, i
, j
=0, k
, v
, active_only
=0;
184 char name
[32], ds
[16], pr
[16], ps
[16];
185 char myframe
[MAX_MOPS_FRAME_SIZE
*3];
187 char line
[150], line2
[150], line3
[150];
189 unsigned char *x0
, *x1
, *x2
, *x3
;
191 struct mops
*head
= mp_head
;
192 struct mops
*mp
= mp_head
;
195 if (strncmp(argv
[argc
-1], "?", 2)==0) {
196 cli_print(cli
, "<CR> Show list of all defined packets\r");
197 cli_print(cli
, "active Only show active packets\r");
198 cli_print(cli
, "<PKT_ID> Show detailed info about given packet\r");
199 //TODO cli_print(cli, "type <proto> Only list packets r");
200 cli_print(cli
, "\n");
205 if (mz_strcmp(argv
[0], "active", 1)==0) {
210 if ((argc
==0) || (active_only
)) // show packet summary
212 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");
213 cli_print(cli
, "PktID PktName Layers Proto Size State Device Delay Count/CntX\n");
218 if (mp
->state
< MOPS_STATE_ACTIVE
) {
229 if (mp
->use_ETHER
) strcat(ds
,"E"); else strcat(ds
,"-");
230 if (mp
->use_SNAP
) strcat(ds
,"S"); else strcat(ds
,"-");
231 if (mp
->use_dot1Q
) strcat(ds
,"Q"); else strcat(ds
,"-");
232 if (mp
->use_MPLS
) strcat(ds
,"M"); else strcat(ds
,"-");
234 if (mp
->auto_delivery_off
)
238 } else strcat(ds
,"-");
243 (mp
->use_TCP
) strcat(ds
,"T");
248 switch (mp
->p_desc_type
)
251 strncpy(pr
, "ARP", 8);
254 strncpy(pr
, "BPDU", 8);
257 strncpy(pr
, "CDP", 8);
260 strncpy(pr
, "DNS", 8);
263 strncpy(pr
, "ICMP", 8);
266 strncpy(pr
, "IGMP", 8);
269 strncpy(pr
, "LLDP", 8);
272 strncpy(pr
, "RTP", 8);
275 strncpy(pr
, "SYSLOG", 8);
282 switch (mops_state(mp
))
284 case MOPS_STATE_NULL
:
285 strcat(ps
, "NULL"); // should never happen!
287 case MOPS_STATE_INIT
:
290 case MOPS_STATE_CONFIG
:
291 strcat(ps
, "config");
293 case MOPS_STATE_ACTIVE
:
294 strcat(ps
, "active");
297 case MOPS_STATE_SEQACT
:
298 strcat(ps
, "actseq");
302 strcat(ps
, "unknown");
306 switch (mp
->interval_used
) {
307 case 1: // interval only configured, not started
308 strncat(ps
, "-i", 2);
312 strncat(ps
, "+I", 2);
319 strncpy (name
, mp
->packet_name
, 13); // only show first 13 chars
321 if (strnlen(mp
->packet_name
, MAX_MOPS_PACKET_NAME_LEN
)>13)
327 // To determine the actual packet length ***
328 // we must reassemble everything: ***
329 mops_ext_update (mp
);
332 timespec2str(&mp
->ndelay
, delay_str
);
334 // ID name lrs prot size state dev del count/cntx/%
335 sprintf(line
, "%5i %-16s %s %-8s %4i %-9s %-6s %10s%9lu/%lu (%i%%)\r",
342 mp
->device
, // device
344 mp
->count
, // Configured count value
345 mp
->cntx
, // Current count
346 (mp
->count
) ? (int) (100 * (mp
->count
- mp
->cntx
)/mp
->count
) : 0 );
347 cli_print(cli
, "%s\r", line
);
353 cli_print(cli
, "\r");
354 cli_print(cli
, "%i packets defined, %i active.\n", j
, a
);
356 //////////////////////////////////////////////////////////////////////////////////////////////////////////
358 //////////////////////////////////////////////////////////////////////////////////////////////////////////
359 else if (argc
== 1) // show details about a specific packet **********************************************
361 if ( (mp
= mops_search_name (mp_head
, argv
[0])) == NULL
)// not found
363 if ( (mp
= mops_search_id (mp_head
, (int) str2int(argv
[0]))) == NULL
)// not found
365 cli_print (cli
, "Packet not in list.\n");
370 // To determine the actual packet length ***
371 // we must reassemble everything: ***
372 mops_ext_update (mp
);
375 cli_print(cli
, "Packet [%i] %s\r", mp
->id
, mp
->packet_name
);
376 cli_print(cli
, " Description: %s \r",
377 (strnlen(mp
->description
, MAX_MOPS_DESCRIPTION_LEN
)) ? mp
->description
: "(no description)");
381 case MOPS_STATE_NULL
:
382 sprintf(mystate
, "NULL");
384 case MOPS_STATE_INIT
:
385 sprintf(mystate
, "init");
387 case MOPS_STATE_CONFIG
:
388 sprintf(mystate
, "config");
390 case MOPS_STATE_ACTIVE
:
391 sprintf(mystate
, "active(tx)");
394 sprintf(mystate
, "unknown");
397 timespec2str(&mp
->ndelay
, delay_str
);
398 if (mp
->interval_used
)
399 timespec2str(&mp
->interval
, line2
);
401 sprintf(line2
, "(undefined)");
403 sprintf(line
, "State: %s, Count=%lu, delay=%s (%lu s %lu nsec), interval= %s\r",
410 cli_print(cli
, " %s\r", line
);
412 cli_print(cli
, " Headers:\r");
416 if (mp
->eth_src_israndom
)
418 cli_print(cli
, " Ethernet: *** RANDOMIZED SMAC *** => %02x-%02x-%02x-%02x-%02x-%02x [%04x%s]\r",
419 mp
->eth_dst
[0],mp
->eth_dst
[1],mp
->eth_dst
[2],mp
->eth_dst
[3],mp
->eth_dst
[4],mp
->eth_dst
[5],
420 mp
->eth_type
, (mp
->use_dot1Q
) ? " after 802.1Q tag" : "");
424 cli_print(cli
, " Ethernet: %02x-%02x-%02x-%02x-%02x-%02x => %02x-%02x-%02x-%02x-%02x-%02x [%04x%s]\r",
425 mp
->eth_src
[0],mp
->eth_src
[1],mp
->eth_src
[2],mp
->eth_src
[3],mp
->eth_src
[4],mp
->eth_src
[5],
426 mp
->eth_dst
[0],mp
->eth_dst
[1],mp
->eth_dst
[2],mp
->eth_dst
[3],mp
->eth_dst
[4],mp
->eth_dst
[5],
427 mp
->eth_type
, (mp
->use_dot1Q
) ? " after 802.1Q tag" : "");
431 if (mp
->auto_delivery_off
)
432 cli_print(cli
, " NOTE: Auto-delivery is OFF (that is, the destination MAC is fixed)\r");
434 cli_print(cli
, " Auto-delivery is ON (that is, the actual MAC is determined upon transmission)\r");
440 bs2str(clipkt
->eth_snap
, line
, clipkt
->eth_snap_s
);
441 cli_print(cli
, " LLC/SNAP: %s\r", line
);
446 k
= clipkt
->dot1Q_s
/4; // number of tags
447 sprintf(line
, "%i tag(s); ", k
);
449 { // tag format = 0x81 0x00 cosTvvvv vvvvvvvv
451 x0
= (unsigned char*) &clipkt
->dot1Q
[(j
*4)+2];
452 x1
= (unsigned char*) &clipkt
->dot1Q
[(j
*4)+3];
453 v
= (*x0
& 0x0f)*256 + *x1
; // VLAN
454 // c = *x0 & 0xe0; // CoS e0=11100000
456 sprintf(ds
, "%i:%i%s",
459 (*x0
& 0x10) ? "[CFI]" : ""); // CFI
460 strncat(line
, ds
, 14);
461 if (j
<(k
-1)) strcat(line
, ", ");
464 cli_print(cli
, " 802.1Q: %s (VLAN:CoS)\r", line
);
469 k
= clipkt
->mpls_s
/4; // number of tags
470 sprintf(line
, "%i tag(s); ", k
);
472 { // tag format = llllllll llllllll llllcccB TTTTTTTT
473 x0
= (unsigned char*) &clipkt
->mpls
[(j
*4)+0];
474 x1
= (unsigned char*) &clipkt
->mpls
[(j
*4)+1];
475 x2
= (unsigned char*) &clipkt
->mpls
[(j
*4)+2];
476 x3
= (unsigned char*) &clipkt
->mpls
[(j
*4)+3];
480 t
+= (*x2
& 0xf0) >> 4;
481 c
= (*x2
& 0x0e) >> 1;
483 sprintf(ds
, "%i:%i:%i%s",
487 (*x2
& 0x01) ? "[BoS]" : ""); // Bottom of Stack?
488 strncat(line
, ds
, 20);
489 if (j
<(k
-1)) strcat(line
, ", ");
492 cli_print(cli
, " MPLS: %s (Label:CoS:TTL)\r", line
);
498 // Source IP settings:
499 x0
= (unsigned char*) & clipkt
->ip_src
;
501 if (clipkt
->ip_src_isrange
)
503 x1
= (unsigned char*) & clipkt
->ip_src_start
;
504 x2
= (unsigned char*) & clipkt
->ip_src_stop
;
505 sprintf(line2
, "%u.%u.%u.%u-%u.%u.%u.%u",
506 (unsigned char) *(x1
+3), (unsigned char) *(x1
+2), (unsigned char) *(x1
+1) , (unsigned char) *x1
,
507 (unsigned char) *(x2
+3), (unsigned char) *(x2
+2), (unsigned char) *(x2
+1) , (unsigned char) *x2
);
509 sprintf(line
, "SA=%u.%u.%u.%u %s %s %s",
510 (unsigned char) *(x0
+3), (unsigned char) *(x0
+2), (unsigned char) *(x0
+1) , (unsigned char) *x0
,
511 (clipkt
->ip_src_israndom
) ? "RANDOM" : "(not random)",
512 (clipkt
->ip_src_isrange
) ? "RANGE:" : "(no range)",
515 cli_print(cli
, " IP: %s\r", line
);
516 //Destination IP settings:
517 x0
= (unsigned char*) & clipkt
->ip_dst
;
519 if (clipkt
->ip_dst_isrange
)
521 x1
= (unsigned char*) & clipkt
->ip_dst_start
;
522 x2
= (unsigned char*) & clipkt
->ip_dst_stop
;
523 sprintf(line2
, "%u.%u.%u.%u-%u.%u.%u.%u",
524 (unsigned char) *(x1
+3), (unsigned char) *(x1
+2), (unsigned char) *(x1
+1) , (unsigned char) *x1
,
525 (unsigned char) *(x2
+3), (unsigned char) *(x2
+2), (unsigned char) *(x2
+1) , (unsigned char) *x2
);
528 sprintf(line
, "DA=%u.%u.%u.%u %s %s",
529 (unsigned char) *(x0
+3), (unsigned char) *(x0
+2), (unsigned char) *(x0
+1) , (unsigned char) *x0
,
530 (clipkt
->ip_dst_isrange
) ? "RANGE:" : "(no range)",
532 cli_print(cli
, " %s\r", line
);
534 sprintf(line
, "ToS=0x%02x proto=%u TTL=%u ID=%u offset=%u flags: %s|%s|%s",
535 clipkt
->ip_tos
, clipkt
->ip_proto
, clipkt
->ip_ttl
, clipkt
->ip_id
, clipkt
->ip_frag_offset
,
536 (clipkt
->ip_flags_RS
) ? "RS" : "-",
537 (clipkt
->ip_flags_DF
) ? "DF" : "-",
538 (clipkt
->ip_flags_MF
) ? "MF" : "-");
540 cli_print(cli
, " %s\r", line
);
542 if (clipkt
->ip_fragsize
) {
543 sprintf(line
, "NOTE: Auto-fragmentation is ON! Fragment size %u bytes, overlap %u",
545 clipkt
->ip_frag_overlap
);
546 cli_print(cli
, " %s\r", line
);
549 sprintf(line
, "len=%u(%s) checksum=0x%02x%02x(%s)",
550 clipkt
->frame
[clipkt
->begin_IP
+2]*256+clipkt
->frame
[clipkt
->begin_IP
+3],
551 (clipkt
->ip_len_false
) ? "false" : "correct",
552 clipkt
->frame
[clipkt
->begin_IP
+10],
553 clipkt
->frame
[clipkt
->begin_IP
+11],
554 (clipkt
->ip_sum_false
) ? "false" : "correct");
556 cli_print(cli
, " %s\r", line
);
562 if (clipkt
->sp_isrange
)
563 sprintf(line2
, "RANGE: %u-%u", clipkt
->sp_start
, clipkt
->sp_stop
);
565 sprintf(line2
, "(norange)");
566 if (clipkt
->dp_isrange
)
567 sprintf(line3
, "RANGE: %u-%u", clipkt
->dp_start
, clipkt
->dp_stop
);
569 sprintf(line3
, "(norange)");
570 sprintf(line
, "SP=%i %s %s, DP=%i %s %s\r",
573 (clipkt
->sp_isrand
) ? "RANDOM" : "(not random)",
576 (clipkt
->dp_isrand
) ? "RANDOM" : "(not random)");
577 cli_print(cli
, " UDP: %s\r", line
);
578 sprintf(line
, "checksum= %04x (%s), length= %u (%s)",
579 clipkt
->udp_sum
, (clipkt
->udp_sum_false
) ? "false" : "correct",
580 clipkt
->udp_len
, (clipkt
->udp_len_false
) ? "false" : "correct");
581 cli_print(cli
, " %s\r", line
);
586 sprintf(line
, "%u bytes segment size (including TCP header)", mp
->tcp_len
);
587 cli_print(cli
, " TCP: %s\r", line
);
588 if (clipkt
->sp_isrange
)
589 sprintf(line2
, "RANGE: %u-%u", clipkt
->sp_start
, clipkt
->sp_stop
);
591 sprintf(line2
, "(norange)");
592 if (clipkt
->dp_isrange
)
593 sprintf(line3
, "RANGE: %u-%u", clipkt
->dp_start
, clipkt
->dp_stop
);
595 sprintf(line3
, "(norange)");
596 sprintf(line
, "SP=%i %s %s, DP=%i %s %s\r",
599 (clipkt
->sp_isrand
) ? "RANDOM" : "(not random)",
602 (clipkt
->dp_isrand
) ? "RANDOM" : "(not random)");
603 cli_print(cli
, " %s\r", line
);
604 sprintf(line
, "SQNR=%u (start %u, stop %u, delta %u) -- ACKNR=%u %s",
606 clipkt
->tcp_seq_start
,
607 clipkt
->tcp_seq_stop
,
608 clipkt
->tcp_seq_delta
,
610 (clipkt
->tcp_ctrl_ACK
) ? "(valid)" : "(invalid)");
611 cli_print(cli
, " %s\r", line
);
612 mops_tcp_flags2str(clipkt
,line2
);
613 sprintf(line
, "Flags: %s, reserved field is %02x, urgent pointer= %u",
617 cli_print(cli
, " %s\r", line
);
618 sprintf(line
, "Announced window size= %u", clipkt
->tcp_win
);
619 cli_print(cli
, " %s\r", line
);
620 sprintf(line
, "Offset= %u (times 32 bit; value is %s), checksum= %04x (%s)",
622 (clipkt
->tcp_offset_false
) ? "FALSE" : "valid",
624 (clipkt
->tcp_sum_false
) ? "FALSE" : "valid");
625 cli_print(cli
, " %s\r", line
);
626 sprintf(line
, "%s - %u bytes defined",
627 (clipkt
->tcp_option_used
) ? "TCP options attached" : "(No TCP options attached)",
628 clipkt
->tcp_option_s
);
629 cli_print(cli
, " %s\r", line
);
633 if (!i
) cli_print(cli
, " No headers defined.\r");
636 cli_print(cli
, " Payload size: %i bytes\r", mp
->msg_s
);
639 cli_print(cli
, " Frame size: %i bytes\n", mp
->frame_s
);
641 mops_print_frame(mp
, myframe
);
642 cli_print(cli
, "%s\n", myframe
);
649 ////////////////////////////////////////////////////////////////////////////////
650 int show_interfaces (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
657 if (strncmp(argv
[argc
-1], "?", 2)==0) {
658 cli_print(cli
, "<CR> Show summary list of all interfaces found\r");
659 cli_print(cli
, "detailed Additionally show network, mask, default gatway, and MTU\r");
660 cli_print(cli
, "\n");
664 // Some safety checks
665 if (argc
>1) return CLI_OK
;
667 if (mz_strcmp(argv
[0], "detailed", 1)!=0) {
668 cli_print(cli
, "invalid keyword (use ?)\n");
673 /* Refresh interface data */
677 for (i
=0; i
<device_list_entries
; i
++) {
678 get_dev_params(device_list
[i
].dev
);
683 /* No additional keyword */
685 cli_print(cli
, "Available network interfaces:\n");
686 cli_print(cli
, " real real used (fake) used (fake)\r");
687 cli_print(cli
, " device IPv4 address MAC address IPv4 address MAC address\r");
688 cli_print(cli
, "---------------------------------------------------------------------------------------\r");
689 for (i
=0; i
<device_list_entries
; i
++) {
690 sprintf(ip
,"%u.%u.%u.%u",
691 device_list
[i
].ip_mops
[0],
692 device_list
[i
].ip_mops
[1],
693 device_list
[i
].ip_mops
[2],
694 device_list
[i
].ip_mops
[3]);
696 sprintf(line
, "%-10s %-15s %02x:%02x:%02x:%02x:%02x:%02x %-15s %02x:%02x:%02x:%02x:%02x:%02x",
697 device_list
[i
].dev
, device_list
[i
].ip_str
,
698 device_list
[i
].mac
[0],
699 device_list
[i
].mac
[1],
700 device_list
[i
].mac
[2],
701 device_list
[i
].mac
[3],
702 device_list
[i
].mac
[4],
703 device_list
[i
].mac
[5],
705 device_list
[i
].mac_mops
[0],
706 device_list
[i
].mac_mops
[1],
707 device_list
[i
].mac_mops
[2],
708 device_list
[i
].mac_mops
[3],
709 device_list
[i
].mac_mops
[4],
710 device_list
[i
].mac_mops
[5]
714 if (strncmp(device_list
[i
].dev
, tx
.device
, 16)==0) {
715 cli_print(cli
, "%s%s> %s\r",
716 (device_list
[i
].cli
) ? "C" : " ",
717 (device_list
[i
].mgmt_only
) ? "!" : "",
722 cli_print(cli
, "%s%s %s\r",
723 (device_list
[i
].cli
) ? "C" : " ",
724 (device_list
[i
].mgmt_only
) ? "M" : "",
728 /////////////////////////
731 /* keyword detailed used */
732 if (mz_strcmp(argv
[0], "detailed", 1)==0) {
733 cli_print(cli
, "Detailed interface list:\n");
734 for (i
=0; i
<device_list_entries
; i
++) {
735 sprintf(line
, "interface %s [%i] %s%stype %s, MTU=%i bytes", // general HW info
737 device_list
[i
].index
,
738 (device_list
[i
].cli
) ? "[cli] " : "",
739 (device_list
[i
].mgmt_only
) ? "[management-only] " : "",
740 (device_list
[i
].phy
) ? "physical" : "software",
742 cli_print(cli
,"%s\r",line
);
743 sprintf(line
, "MAC bia: %02x:%02x:%02x:%02x:%02x:%02x\n MAC fake: %02x:%02x:%02x:%02x:%02x:%02x",
744 device_list
[i
].mac
[0],
745 device_list
[i
].mac
[1],
746 device_list
[i
].mac
[2],
747 device_list
[i
].mac
[3],
748 device_list
[i
].mac
[4],
749 device_list
[i
].mac
[5],
750 device_list
[i
].mac_mops
[0],
751 device_list
[i
].mac_mops
[1],
752 device_list
[i
].mac_mops
[2],
753 device_list
[i
].mac_mops
[3],
754 device_list
[i
].mac_mops
[4],
755 device_list
[i
].mac_mops
[5]);
756 cli_print(cli
," %s\r",line
);
757 sprintf(line
,"IP addr: %s mask %u.%u.%u.%u (net %u.%u.%u.%u)",
758 device_list
[i
].ip_str
,
759 device_list
[i
].mask
[0],
760 device_list
[i
].mask
[1],
761 device_list
[i
].mask
[2],
762 device_list
[i
].mask
[3],
763 device_list
[i
].net
[0],
764 device_list
[i
].net
[1],
765 device_list
[i
].net
[2],
766 device_list
[i
].net
[3]);
767 cli_print(cli
," %s\r",line
);
768 sprintf(line
,"IP fake: %u.%u.%u.%u",
769 device_list
[i
].ip_mops
[0],
770 device_list
[i
].ip_mops
[1],
771 device_list
[i
].ip_mops
[2],
772 device_list
[i
].ip_mops
[3]);
773 cli_print(cli
, " %s\r", line
);
774 sprintf(line
,"GW addr: %u.%u.%u.%u (%02x:%02x:%02x:%02x:%02x:%02x)",
775 device_list
[i
].ip_gw
[0],
776 device_list
[i
].ip_gw
[1],
777 device_list
[i
].ip_gw
[2],
778 device_list
[i
].ip_gw
[3],
779 device_list
[i
].mac_gw
[0],
780 device_list
[i
].mac_gw
[1],
781 device_list
[i
].mac_gw
[2],
782 device_list
[i
].mac_gw
[3],
783 device_list
[i
].mac_gw
[4],
784 device_list
[i
].mac_gw
[5]);
785 cli_print(cli
," %s\n",line
);
789 /* In any case, print final summary line: */
790 cli_print(cli
, "\n%i interfaces found.\nDefault interface is %s.\n",
791 device_list_entries
, device_list
[j
].dev
);
798 ////////////////////////////////////////////////////////////////////////////////
799 int show_set(struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
802 char hexload
[3*MAX_PAYLOAD_SIZE
];
804 cli_print(cli
, "----- Packet parameters: ------ -------- Value: ----------\r");
805 cli_print(cli
, "Source MAC address (sa) %02x:%02x:%02x:%02x:%02x:%02x [%s]\r",
806 tx
.eth_src
[0], tx
.eth_src
[1], tx
.eth_src
[2],
807 tx
.eth_src
[3], tx
.eth_src
[4], tx
.eth_src
[5],
808 (tx
.eth_src_rand
) ? "rand" : "spec");
809 cli_print(cli
, "Basic MAC address %02x:%02x:%02x:%02x:%02x:%02x\r",
810 tx
.eth_mac_own
[0], tx
.eth_mac_own
[1], tx
.eth_mac_own
[2],
811 tx
.eth_mac_own
[3], tx
.eth_mac_own
[4], tx
.eth_mac_own
[5]);
812 cli_print(cli
, "Destination MAC address (da) %02x:%02x:%02x:%02x:%02x:%02x [%s]\r",
813 tx
.eth_dst
[0], tx
.eth_dst
[1], tx
.eth_dst
[2],
814 tx
.eth_dst
[3], tx
.eth_dst
[4], tx
.eth_dst
[5],
815 (tx
.eth_dst_rand
) ? "rand" : "spec");
816 cli_print(cli
, "\r");
817 x
= (unsigned char *) &tx
.ip_src
;
818 cli_print(cli
, "Source IP address (SA) %i.%i.%i.%i [%s]\r",
819 *x
,*(x
+1),*(x
+2),*(x
+3),
820 (tx
.ip_src_rand
) ? "rand" : "spec");
822 if (tx
.ip_src_isrange
)
824 x
= (unsigned char *) &tx
.ip_src_start
;
825 cli_print(cli
, "Source IP range start: %i.%i.%i.%i\r",
826 *(x
+3), *(x
+2), *(x
+1), *x
);
827 x
= (unsigned char *) &tx
.ip_src_stop
;
828 cli_print(cli
, "Source IP range stop: %i.%i.%i.%i\r",
829 *(x
+3), *(x
+2), *(x
+1), *x
);
833 cli_print(cli
, "No source IP range specified\r");
835 x
= (unsigned char *) &tx
.ip_dst
;
836 cli_print(cli
, "Destination IP address (DA) %i.%i.%i.%i\r",
837 *x
,*(x
+1),*(x
+2),*(x
+3));
839 if (tx
.ip_dst_isrange
)
841 x
= (unsigned char *) &tx
.ip_dst_start
;
842 cli_print(cli
, "Destination IP range start: %i.%i.%i.%i\r",
843 *(x
+3), *(x
+2), *(x
+1), *x
);
844 x
= (unsigned char *) &tx
.ip_dst_stop
;
845 cli_print(cli
, "Destination IP range stop: %i.%i.%i.%i\r",
846 *(x
+3), *(x
+2), *(x
+1), *x
);
850 cli_print(cli
, "No destination IP range specified\r");
855 cli_print(cli
, "802.1Q tags specified: %s\r", tx
.dot1Q_txt
);
860 cli_print(cli
, "MPLS labels specified: %s\r", tx
.mpls_txt
);
864 { cli_print(cli
, "\r");
865 cli_print(cli
, "---- ASCII payload is set: ----- \r");
866 cli_print(cli
, ">>>%s<<<\r", tx
.ascii_payload
);
867 cli_print(cli
, "-------------------------------- \n");
870 if (tx
.hex_payload_s
)
871 { cli_print(cli
, "\r");
872 cli_print(cli
, "---- Hexadecimal payload is set: ----- \r");
873 bs2str(tx
.hex_payload
, hexload
, tx
.hex_payload_s
);
874 cli_print(cli
, "%s\r", hexload
);
875 cli_print(cli
, "-------------------------------------- \n");
880 cli_print(cli
, "Configured padding: %u\r", tx
.padding
);
883 cli_print(cli
, "\r");
884 cli_print(cli
, "Packet count value %u\r", tx
.count
);
885 cli_print(cli
, "Interpacket delay (usec) %u\r", tx
.delay
);
886 cli_print(cli
, "\r");
887 cli_print(cli
, "Used network device(s): %s\r", tx
.device
);
888 cli_print(cli
, "\n");
898 ////////////////////////////////////////////////////////////////////////////////
899 int stop_mausezahn (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
901 if (strncmp(argv
[argc
-1], "?", 2)==0) {
902 cli_print(cli
, "now Terminate the mausezahn server! BEWARE!\n");
907 cli_print(cli
, "The only allowed argument is 'now' -- anything else is ignored\n");
911 if (mz_strcmp(argv
[0], "now", 3)==0) {
912 cli_print(cli
, "Good bye...\n");
917 cli_print(cli
, "Invalid argument. If you want to stop the Mausezahn server then\r");
918 cli_print(cli
, "enter 'terminate now'. You cannot abbreviate the argument 'now'. \n");
927 int cmd_run_id (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
933 cli_print(cli
, "Specify one or more packet identifiers to run.\n");
937 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
938 cli_print(cli
, "Run packet transmission processes for given list of packet identifiers\n");
942 // User provided packet id numbers
944 for (i
=0; i
<argc
; i
++) {
945 slot
= (int) str2int(argv
[i
]);
946 if ( (mp
= mops_search_id (mp_head
, slot
)) == NULL
) { // not found
947 cli_print (cli
, "Packet %i not in list.\n", slot
);
951 switch (mops_tx_simple (mp
)) {
953 cli_print(cli
, "Cannot create sending process.\r");
957 cli_print(cli
, "Packet [%i] has already an active sending process\r", mp
->id
);
961 cli_print (cli
, "Activate [%i] ", slot
);
966 cli_print (cli
, "\n");
972 int cmd_run_name (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
978 cli_print(cli
, "Specify one or more packet name(s) to run.\n");
982 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
983 cli_print(cli
, "Run packet transmission processes for specified packet name(s).\n");
988 for (i
=0; i
<argc
; i
++) {
989 if ( (mp
= mops_search_name (mp_head
, argv
[i
])) == NULL
) { // not found
990 cli_print (cli
, "Packet %s not in list.\n", argv
[i
]);
994 switch (mops_tx_simple (mp
)) {
996 cli_print(cli
, "Cannot create sending process.\r");
1000 cli_print(cli
, "Packet [%i] has already an active sending process\r", mp
->id
);
1004 cli_print (cli
, "Activate [%i] ", mp
->id
);
1009 cli_print (cli
, "\n");
1015 int cmd_run_sequence (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1020 cli_print(cli
, "Specify one (and only one) packet sequence name to run.\n");
1024 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
1025 cli_print(cli
, "Run sequence transmission processes for specified sequence name.\n");
1029 cur
= mz_ll_search_name (packet_sequences
, argv
[0]);
1030 if (cur
==NULL
) { // NOT FOUND !!!
1031 cli_print(cli
, "Sequence %s does not exist.", argv
[0]);
1034 ret
= mops_tx_sequence(cur
);
1036 case 0: cli_print(cli
, "Sequence %s is runnning\n", cur
->name
);
1038 case 1: cli_print(cli
, "Cannot run sequence: All packets must be in config state!\n");
1040 case 2: cli_print(cli
, "Cannot run sequence: All packets must have a finite count!\n");
1042 case 3: cli_print(cli
, "Cannot run sequence: Unable to start sequence transmission process.\n");
1050 int cmd_run_all (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1056 if ( strncmp(argv
[argc
-1], "?", 1) == 0) {
1057 cli_print(cli
, "Run all user-specified packets.\n");
1062 cli_print(cli
, "No arguments expected!\n");
1066 // Send all valid packets
1071 if ((mp
->mz_system
==0) && (mops_state(mp
) == MOPS_STATE_CONFIG
)) {
1072 switch (mops_tx_simple (mp
)) {
1074 cli_print(cli
, "Cannot create sending process.\r");
1078 cli_print(cli
, "Packet [%i] has already an active sending process\r", mp
->id
);
1085 cli_print (cli
, "Activate [%i] %s\r", mp
->id
, mp
->packet_name
);
1091 cli_print (cli
, "No valid packets found\n");
1093 cli_print (cli
, "\r");
1094 cli_print (cli
, "Activated %i packets \n", i
);
1101 int cmd_stop (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1104 int i
, ret
=0, slot
=0;
1106 struct mops
*head
= mp_head
;
1107 struct mops
*cur
= mp_head
;
1109 if ((strncmp(argv
[argc
-1], "?", 2)==0) || (argc
==0)) {
1110 cli_print(cli
, "Stop transmission process(es) or an active sequence.\r");
1111 cli_print(cli
, "SYNTAX: 1) Either specify one or more packet-ids or packet names of active packets\r");
1112 cli_print(cli
, " 2) Or enter 'sequence <seq-name>' to stop an active sequence and its associated packets.\n");
1116 // Did the user specify a sequence? (ONE SEQUENCE ONLY)
1117 if ((mz_strcmp(argv
[0], "sequence", 3)==0) && (argc
==2)) {
1118 ret
= stop_sequence (argv
[1]);
1121 cli_print(cli
, "Sequence '%s' stopped.\n", argv
[1]);
1125 cli_print(cli
, "Sequence '%s' does not exist!\n", argv
[1]);
1128 cli_print(cli
, "Sequence '%s' is not active. Nothing to stop.\n", argv
[1]);
1135 if (((mz_strcmp(argv
[0], "all", 3)==0) || (mz_strcmp(argv
[0], "*", 1)==0)) && (argc
==1)) {
1137 cli_print(cli
, "Stopping ");
1139 if (mops_destroy_thread (cur
)==0) {
1141 cli_print(cli
, "[%i] %s", cur
->id
, cur
->packet_name
);
1145 while (head
!= cur
);
1146 cli_print(cli
, "\n");
1148 cli_print(cli
, "Stopped %i transmission processe(s)\r", i
);
1151 cli_print(cli
, "No active transmission processes found.\r");
1154 i
= stop_all_sequences ();
1156 cli_print(cli
, "Stopped %i sequence(s)\n", i
);
1159 cli_print(cli
, "No active sequences found.\n");
1165 // Stop all specified packets:
1167 for (i
=0; i
<argc
; i
++) {
1169 // is argv[i] a numerical pkt-id?
1170 if (mz_strisnum(argv
[i
])) {
1171 slot
= (int) str2int(argv
[i
]);
1172 mp
= mops_search_id (mp_head
, slot
);
1174 // still not found? Is it a name?
1175 if (mp
==NULL
) mp
= mops_search_name (mp_head
, argv
[i
]);
1176 if (mp
==NULL
) cli_print(cli
, "Packet '%s' not in list!\r",argv
[i
]);
1177 else { // packet found:
1178 if (mops_destroy_thread (mp
)) {
1179 cli_print(cli
, "Packet [%i] '%s' has no associated transmission process (nothing to stop).\r", mp
->id
, mp
->packet_name
);
1181 cli_print (cli
, "Stopped transission process for packet [%i] '%s'.\r", mp
->id
, mp
->packet_name
);
1185 cli_print(cli
, "\r");
1191 int show_mops(struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1195 if (strncmp(argv
[argc
-1], "?", 2)==0) {
1196 cli_print(cli
, "<ENTER> Check MOPS version and details\n");
1200 cli_print(cli
, "-----------------------------------------------------\r");
1201 cli_print(cli
, "Mops version %s [%s]\n", MOPS_VERSION
, MOPS_CODENAME
);
1202 cli_print(cli
, "Maximum packet sequence length is %i packets\r", MAX_PACKET_SEQUENCE_LEN
);
1203 cli_print(cli
, "Maximum frame size is %i bytes\r", MAX_MOPS_FRAME_SIZE
);
1204 cli_print(cli
, "Minimum frame size is %i bytes\r", MIN_MOPS_FRAME_SIZE
);
1205 cli_print(cli
, "PCAP readout delay is %i msec\r", PCAP_READ_TIMEOUT_MSEC
);
1206 cli_print(cli
, "Maximum payload size is %i bytes\r", MAX_MOPS_MSG_SIZE
);
1207 cli_print(cli
, "Maximum chunk size is %i bytes\r", MAX_MOPS_MSG_CHUNK_SIZE
);
1208 cli_print(cli
, "Maximum counters per packet is %i\r", MAX_MOPS_COUNTERS_PER_PACKET
);
1209 cli_print(cli
, "Maximum number of 802.1Q tags is %i\r", MAX_MOPS_DOT1Q_TAGS
);
1210 cli_print(cli
, "Maximum number of MPLS tags is %i\r", MAX_MOPS_MPLS_TAGS
);
1211 cli_print(cli
, "Maximum length of packet names is %i characters\r", MAX_MOPS_PACKET_NAME_LEN
);
1212 cli_print(cli
, "Maximum length of packet descriptions is %i characters\r", MAX_MOPS_DESCRIPTION_LEN
);
1213 cli_print(cli
, "Bytes per line for formatted frame output %i\r", MAX_CLI_LINE_BYTES
);
1214 cli_print(cli
, "Maximum LLDP optional section length is %i bytes\r", MAX_LLDP_OPT_TLVS
);
1215 if (AUTOMOPS_ENABLED
) {
1216 cli_print(cli
, "Auto-MOPS subsystem is enabled\r");
1217 cli_print(cli
, " Maximum nesting depth is %i\r", XN_MAX_STACK
);
1218 cli_print(cli
, " Maximum file size for protocol definitions is %i\r", AUTOMOPS_MAX_FILE_SIZE
);
1219 cli_print(cli
, " Maximum names length is %i\r", AUTOMOPS_MAX_NAME_LEN
);
1220 cli_print(cli
, " Maximum short description length is %i\r", AUTOMOPS_MAX_SHORTDESC_LEN
);
1221 cli_print(cli
, " Maximum XML tag length is %i\r", XML_MAX_TAG_LEN
);
1222 } else cli_print(cli
, "Auto-MOPS subsystem is disabled\r");
1224 if (mops_dump_all(mp_head
, tmp
)) {
1225 cli_print(cli
, "No mopses found.\n"); // keine Möpse gefunden ;-)
1227 cli_print(cli
, "%s\n", tmp
);
1236 int cmd_reset_interface (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1240 if (strncmp(argv
[argc
-1], "?", 2)==0) {
1241 cli_print(cli
, "<ENTER> Check MOPS version and details\n");
1246 cli_print(cli
, "Unknown parameter\n");
1252 for (i
=0; i
<device_list_entries
; i
++) {
1253 get_dev_params(device_list
[i
].dev
);
1254 // refresh ARP table i. e. MAC addresses of default GWs
1255 service_arp(device_list
[i
].dev
, device_list
[i
].ip_gw
, device_list
[i
].mac_gw
);
1264 int conf_frame_limit (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1268 if (strncmp(argv
[argc
-1], "?", 2)==0)
1270 cli_print(cli
, "Configure global frame size limits:\n");
1271 cli_print(cli
, " <min-frame-size> [max-frame-size]\n");
1277 cli_print(cli
, "Two arguments allowed: <min-frame-size> [max-frame-size]\n");
1281 tmp
= (unsigned int) str2int (argv
[0]);
1282 if (tmp
< MIN_MOPS_FRAME_SIZE
)
1284 cli_print(cli
, "This Mausezahn requires that the minimum frame size is at least %i bytes\n", MIN_MOPS_FRAME_SIZE
);
1288 if (tmp
>(max_frame_s
-2))
1290 cli_print(cli
, "The minimum frame size must be below %i bytes\n", max_frame_s
-1);
1298 tmp
= (unsigned int) str2int (argv
[1]);
1300 if (tmp
> MAX_MOPS_FRAME_SIZE
-MOPS_SIZE_MARGIN
)
1302 cli_print(cli
, "This Mausezahn requires that the maximum frame size is not greater than %i bytes\n",
1303 MAX_MOPS_FRAME_SIZE
-MOPS_SIZE_MARGIN
);
1307 if (tmp
<(min_frame_s
+2))
1309 cli_print(cli
, "The maximum frame size must be greater than %i bytes\n", min_frame_s
+1);
1322 int cmd_load (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1327 if ( (strcmp(argv
[argc
-1],"?")==0) || (argc
!=1) ) {
1328 cli_print(cli
, "Load commands from one or more specified file(s)\r");
1329 cli_print(cli
, "\n");
1334 cli_print(cli
, "Specify one or more configuration files\n");
1338 for (i
=0; i
<argc
; i
++) {
1339 fp
= fopen(argv
[i
], "r");
1341 cli_print(cli
, "Warning: Cannot read %s\n", argv
[i
]);
1344 cli_print(cli
, "Read commands from %s...\n", argv
[i
]);
1345 cli_file (cli
, fp
, PRIVILEGE_PRIVILEGED
, MODE_EXEC
);
1346 if (fclose(fp
) == EOF
)
1348 cli_print(cli
, "Warning: problems closing %s (errno=%i)\n", argv
[i
],errno
);
1356 int show_arp (struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1359 struct arp_table_struct
*cur
;
1360 char s
[128], ip
[20], uc
[16], bc
[16], ch
[16];
1361 struct mz_timestamp now
, prev
, result
;
1365 if (strcmp(argv
[argc
-1],"?")==0) {
1366 cli_print(cli
, "<CR> shows the advanced Mausezahn ARP table\n");
1371 cli_print(cli
, "Unknown parameter\n");
1376 cli_print(cli
, "Intf Index IP address MAC address last Ch UCast BCast Info\r");
1377 cli_print(cli
, "----------------------------------------------------------------------------------\r");
1378 // ------------------------------------------------------------------------------
1379 // wlan0 [1] DL 192.168.0.1 at 00:09:5b:9a:15:84 3'42'' 1
1381 for (i
=0; i
<device_list_entries
; i
++) {
1382 cur
=device_list
[i
].arp_table
;
1384 sprintf(ip
,"%i.%i.%i.%i",cur
->sip
[0],cur
->sip
[1],cur
->sip
[2],cur
->sip
[3]);
1385 if (cur
->changed
>99999) mz_strncpy(ch
,"ALERT",6); else sprintf(ch
,"%lu", cur
->changed
);
1386 if (cur
->uni_resp
>99999) mz_strncpy(uc
,"ALERT",6); else sprintf(uc
,"%lu", cur
->uni_resp
);
1387 if (cur
->bc_resp
>99999) mz_strncpy(bc
,"ALERT",6); else sprintf(bc
,"%lu", cur
->bc_resp
);
1388 sprintf(s
, "%-7s [%i] %s%s %15s %02x:%02x:%02x:%02x:%02x:%02x %8s %5s %5s %5s %04x",
1391 (cur
->dynamic
) ? "D" : "U",
1392 (cur
->locked
) ? "L" : "",
1405 cli_print(cli
, "%s\r", s
);
1406 if (cur
->changed
>1) {
1408 now
.nsec
= cur
->nsec
;
1409 prev
.sec
= cur
->sec_prev
;
1410 prev
.nsec
= cur
->nsec_prev
;
1411 printf("sec=%u nsec=%u sec=%u nsec=%u\n", cur
->sec
, cur
->nsec
, cur
->sec_prev
, cur
->nsec_prev
);
1412 timestamp_subtract(&now
, &prev
, &result
);
1413 sprintf(s
," previous MAC was: %02x:%02x:%02x:%02x:%02x:%02x time delta: %u sec %u msec",
1420 (unsigned int) result
.sec
, (unsigned int) result
.nsec
/1000000);
1421 cli_print(cli
, " %s\r", s
);
1431 // general 'end' command to return to global config mode
1432 int cmd_end_to_config(struct cli_def
*cli
, char *command
, char *argv
[], int argc
)
1434 cli_set_configmode(cli
, MODE_CONFIG
, NULL
);