void pktgen_set_theme_item( char * item, char * fg_color, char * bg_color, char * attr) { theme_color_map_t * elem; color_e fg, bg; attr_e at; elem = lookup_item(item); if ( elem == NULL ) { pktgen_log_error("Unknown item name (%s)\n", item); return; } fg = get_color_by_name(fg_color); bg = get_color_by_name(bg_color); at = get_attr_by_name(attr); if ( (fg == UNKNOWN_COLOR) || (bg == UNKNOWN_COLOR) || (at == UNKNOWN_ATTR) ) { pktgen_log_error("Unknown color or attribute (%s, %s, %s)\n", fg_color, bg_color, attr); return; } elem->fg_color = fg; elem->bg_color = bg; elem->attr = at; }
/* Changes the color to the color of the specified element */ void pktgen_display_set_color(const char *elem) { theme_color_map_t *theme_color; if ( scrn->theme == THEME_OFF ) return; theme_color = lookup_item(elem); if (theme_color == NULL) { pktgen_log_error("Unknown color '%s'", elem); return; } scrn_color(theme_color->fg_color, theme_color->bg_color, theme_color->attr); }
void pktgen_theme_save(char * filename) { FILE * f; int i; f = fopen(filename, "w+"); if ( f == NULL ) { pktgen_log_error("Unable to open file %s\n", filename); return; } for(i = 0; theme_color_map[i].name; i++) { fprintf(f, "theme %s %s %s %s\n", theme_color_map[i].name, get_name_by_color(theme_color_map[i].fg_color), get_name_by_color(theme_color_map[i].bg_color), get_name_by_attr(theme_color_map[i].attr)); } fprintf(f, "cls\n"); fclose(f); }
/* String to use as prompt, with proper ANSI color codes */ const char * pktgen_get_prompt(void) { theme_color_map_t *def, *prompt; // Set default return value. snprintf(prompt_str, sizeof(prompt_str), "%s> ", PKTGEN_APP_NAME); if ( scrn->theme == THEME_ON ) { // Look up the default and prompt values def = lookup_item(NULL); prompt = lookup_item("pktgen.prompt"); if ( (def == NULL) || (prompt == NULL) ) pktgen_log_error("Prompt and/or default color undefined"); else snprintf(prompt_str, sizeof(prompt_str), "\033[%d;%d;%dm%s>\033[%d;%d;%dm ", prompt->attr, 30 + prompt->fg_color, 40 + prompt->bg_color, PKTGEN_APP_NAME, def->attr, 30 + def->fg_color, 40 + def->bg_color); } return prompt_str; }
int main(int argc, char **argv) { uint32_t i; int32_t ret; printf("\n%s %s\n", wr_copyright_msg(), wr_powered_by()); fflush(stdout); wr_scrn_setw(1);/* Reset the window size */ /* call before the rte_eal_init() */ (void)rte_set_application_usage_hook(pktgen_usage); memset(&pktgen, 0, sizeof(pktgen)); pktgen.flags = PRINT_LABELS_FLAG; pktgen.ident = 0x1234; pktgen.nb_rxd = DEFAULT_RX_DESC; pktgen.nb_txd = DEFAULT_TX_DESC; pktgen.nb_ports_per_page = DEFAULT_PORTS_PER_PAGE; if ( (pktgen.l2p = wr_l2p_create()) == NULL) pktgen_log_panic("Unable to create l2p"); pktgen.portdesc_cnt = wr_get_portdesc(pktgen.portlist, pktgen.portdesc, RTE_MAX_ETHPORTS, 0); /* Initialize the screen and logging */ pktgen_init_log(); pktgen_cpu_init(); /* initialize EAL */ ret = rte_eal_init(argc, argv); if (ret < 0) return -1; argc -= ret; argv += ret; pktgen.hz = rte_get_timer_hz(); /* Get the starting HZ value. */ /* parse application arguments (after the EAL ones) */ ret = pktgen_parse_args(argc, argv); if (ret < 0) return -1; pktgen_init_screen((pktgen.flags & ENABLE_THEME_FLAG) ? THEME_ON : THEME_OFF); rte_delay_ms(100); /* Wait a bit for things to settle. */ wr_print_copyright(PKTGEN_APP_NAME, PKTGEN_CREATED_BY); lua_newlib_add(_lua_openlib); /* Open the Lua script handler. */ if ( (pktgen.L = lua_create_instance()) == NULL) { pktgen_log_error("Failed to open Lua pktgen support library"); return -1; } pktgen_log_info(">>> Packet Burst %d, RX Desc %d, TX Desc %d, mbufs/port %d, mbuf cache %d", DEFAULT_PKT_BURST, DEFAULT_RX_DESC, DEFAULT_TX_DESC, MAX_MBUFS_PER_PORT, MBUF_CACHE_SIZE); /* Configure and initialize the ports */ pktgen_config_ports(); pktgen_log_info(""); pktgen_log_info("=== Display processing on lcore %d", rte_lcore_id()); /* launch per-lcore init on every lcore except master and master + 1 lcores */ for (i = 0; i < RTE_MAX_LCORE; i++) { if ( (i == rte_get_master_lcore()) || !rte_lcore_is_enabled(i) ) continue; ret = rte_eal_remote_launch(pktgen_launch_one_lcore, NULL, i); if (ret != 0) pktgen_log_error("Failed to start lcore %d, return %d", i, ret); } rte_delay_ms(1000); /* Wait for the lcores to start up. */ /* Disable printing log messages of level info and below to screen, */ /* erase the screen and start updating the screen again. */ pktgen_log_set_screen_level(LOG_LEVEL_WARNING); wr_scrn_erase(pktgen.scrn->nrows); wr_logo(3, 16, PKTGEN_APP_NAME); wr_splash_screen(3, 16, PKTGEN_APP_NAME, PKTGEN_CREATED_BY); wr_scrn_resume(); pktgen_redisplay(1); rte_timer_setup(); if (pktgen.flags & ENABLE_GUI_FLAG) { if (!wr_scrn_is_paused() ) { wr_scrn_pause(); wr_scrn_cls(); wr_scrn_setw(1); wr_scrn_pos(pktgen.scrn->nrows, 1); } lua_init_socket(pktgen.L, &pktgen.thread, pktgen.hostname, pktgen.socket_port); } pktgen_cmdline_start(); execute_lua_close(pktgen.L); pktgen_stop_running(); wr_scrn_pause(); wr_scrn_setw(1); wr_scrn_printf(100, 1, "\n"); /* Put the cursor on the last row and do a newline. */ /* Wait for all of the cores to stop running and exit. */ rte_eal_mp_wait_lcore(); return 0; }
static int pktgen_parse_args(int argc, char **argv) { int opt, ret, port; char **argvopt; int option_index; char *prgname = argv[0], *p; static struct option lgopts[] = { {NULL, 0, 0, 0} }; argvopt = argv; pktgen.hostname = (char *)strdupf(pktgen.hostname, "localhost"); pktgen.socket_port = 0x5606; pktgen.argc = argc; for (opt = 0; opt < argc; opt++) pktgen.argv[opt] = strdup(argv[opt]); while ((opt = getopt_long(argc, argvopt, "p:m:f:l:s:g:hPNGT", lgopts, &option_index)) != EOF) switch (opt) { case 'p': /* Port mask not used anymore */ break; case 'f': /* Command file or Lua script. */ pktgen.cmd_filename = strdup(optarg); break; case 'l': /* Log file */ pktgen_log_set_file(optarg); break; case 'm': /* Matrix for port mapping. */ if (wr_parse_matrix(pktgen.l2p, optarg) == -1) { pktgen_log_error("invalid matrix string (%s)", optarg); pktgen_usage(prgname); return -1; } break; case 's': /* Read a PCAP packet capture file (stream) */ port = strtol(optarg, NULL, 10); p = strchr(optarg, ':'); if ( (p == NULL) || (pktgen.info[port].pcap = wr_pcap_open(++p, port)) == NULL) { pktgen_log_error("Invalid PCAP filename (%s) must include port number as P:filename", optarg); pktgen_usage(prgname); return -1; } break; case 'P': /* Enable promiscuous mode on the ports */ pktgen.flags |= PROMISCUOUS_ON_FLAG; break; case 'N': /* Enable NUMA support. */ pktgen.flags |= NUMA_SUPPORT_FLAG; break; case 'G': pktgen.flags |= (ENABLE_GUI_FLAG | IS_SERVER_FLAG); break; case 'g': /* Define the port number and IP address used for the socket connection. */ pktgen.flags |= (ENABLE_GUI_FLAG | IS_SERVER_FLAG); p = strchr(optarg, ':'); if (p == NULL) /* No : symbol means pktgen is a server application. */ pktgen.hostname = (char *)strdupf(pktgen.hostname, optarg); else { char c = *p; *p = '\0'; if (p != optarg) pktgen.hostname = (char *)strdupf(pktgen.hostname, optarg); pktgen.socket_port = strtol(++p, NULL, 0); pktgen_log_info(">>> Socket GUI support %s%c0x%x", pktgen.hostname, c, pktgen.socket_port); } break; case 'T': pktgen.flags |= ENABLE_THEME_FLAG; break; case 'h': /* print out the help message */ pktgen_usage(prgname); return -1; case 0: /* Long options */ default: pktgen_usage(prgname); return -1; } /* Setup the program name */ if (optind >= 0) argv[optind - 1] = prgname; ret = optind - 1; optind = 0; /* reset getopt lib */ return ret; }
void pktgen_process_ping4( struct rte_mbuf * m, uint32_t pid, uint32_t vlan ) { port_info_t * info = &pktgen.info[pid]; pkt_seq_t * pkt; struct ether_hdr *eth = rte_pktmbuf_mtod(m, struct ether_hdr *); ipHdr_t * ip = (ipHdr_t *)ð[1]; char buff[24]; /* Adjust for a vlan header if present */ if ( vlan ) ip = (ipHdr_t *)((char *)ip + sizeof(struct vlan_hdr)); // Look for a ICMP echo requests, but only if enabled. if ( (rte_atomic32_read(&info->port_flags) & ICMP_ECHO_ENABLE_FLAG) && (ip->proto == PG_IPPROTO_ICMP) ) { #if !defined(RTE_ARCH_X86_64) icmpv4Hdr_t * icmp = (icmpv4Hdr_t *)((uint32_t)ip + sizeof(ipHdr_t)); #else icmpv4Hdr_t * icmp = (icmpv4Hdr_t *)((uint64_t)ip + sizeof(ipHdr_t)); #endif // We do not handle IP options, which will effect the IP header size. if ( unlikely(cksum(icmp, (m->data_len - sizeof(struct ether_hdr) - sizeof(ipHdr_t)), 0)) ) { pktgen_log_error("ICMP checksum failed"); return; } if ( unlikely(icmp->type == ICMP4_ECHO) ) { if ( ntohl(ip->dst) == INADDR_BROADCAST ) { pktgen_log_warning("IP address %s is a Broadcast", inet_ntop4(buff, sizeof(buff), ip->dst, INADDR_BROADCAST)); return; } // Toss all broadcast addresses and requests not for this port pkt = pktgen_find_matching_ipsrc(info, ip->dst); // ARP request not for this interface. if ( unlikely(pkt == NULL) ) { pktgen_log_warning("IP address %s not found", inet_ntop4(buff, sizeof(buff), ip->dst, INADDR_BROADCAST)); return; } info->stats.echo_pkts++; icmp->type = ICMP4_ECHO_REPLY; /* Recompute the ICMP checksum */ icmp->cksum = 0; icmp->cksum = cksum(icmp, (m->data_len - sizeof(struct ether_hdr) - sizeof(ipHdr_t)), 0); // Swap the IP addresses. inetAddrSwap(&ip->src, &ip->dst); // Bump the ident value ip->ident = htons(ntohs(ip->ident) + m->data_len); // Recompute the IP checksum ip->cksum = 0; ip->cksum = cksum(ip, sizeof(ipHdr_t), 0); // Swap the MAC addresses ethAddrSwap(ð->d_addr, ð->s_addr); pktgen_send_mbuf(m, pid, 0); pktgen_set_q_flags(info, 0, DO_TX_FLUSH); // No need to free mbuf as it was reused. return; } else if ( unlikely(icmp->type == ICMP4_ECHO_REPLY) ) { info->stats.echo_pkts++; } } }