// // Created by xajhuang on 2023/4/12. // #include #include #include "main.h" #include "misc.h" #include "task_manager.h" #include "user_errno.h" #include "zlog_module.h" #include "dhcp_network.h" #include "dhcp_options.h" #include "ipaddr.h" #include "zvector/zvector.h" #define DHCP_STEP_TIMEOUT (30) #define DHCP_PKG_RETRY (3) #define MAIN_WND_WIDTH (1024) #define MAIN_WND_HEIGHT (768) #define ZLOG_CFG_PATH "./config/zlog.conf" static GtkBuilder *g_mainBuilder = NULL; static PDHCP_INFO g_pDhcpInfo = NULL; static GThread *g_pEvLoopThread = NULL; static int g_runTask = FALSE; static U32 g_endTask = 0; static c_vector g_pFinishTask = NULL; static c_vector g_pErrTask = NULL; static struct timeval g_StartTm; const char *dhcp_step_to_string(DHCP_STEP step) { const char *stepName[] = {"STEP_BEGIN", "STEP_DISCOVER", "STEP_OFFER", "STEP_REQUEST", "STEP_ACK", "STEP_END"}; if (step > 0 && step < ARRAY_SIZE(stepName)) { return stepName[step]; } else { return "Unknown Step"; } } GtkBuilder *get_main_builder() { return g_mainBuilder; } U32 rand_number() { GRand *pRand = g_rand_new_with_seed(time(NULL)); return g_rand_int(pRand); } PDHCP_INFO get_dhcp_info_by_id(U32 xid) { PDHCP_INFO pInfo; U32 index = xid & 0x00FFFFFF; HASH_FIND_INT(g_pDhcpInfo, &index, pInfo); return pInfo; } static void load_css(void) { GtkCssProvider *provider; GdkDisplay *display; GdkScreen *screen; GFile *css_fp = g_file_new_for_path("./res/style.css"); GError *error = 0; provider = gtk_css_provider_new(); display = gdk_display_get_default(); screen = gdk_display_get_default_screen(display); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_css_provider_load_from_file(provider, css_fp, &error); } static double calc_total_progress(PDHCP_INFO pInfo) { double pre_cnt = 0.0; pre_cnt += pInfo->step * 20; pre_cnt += pInfo->status * 5; return MIN(pre_cnt, 100.0); } static gboolean calc_step_progress(PDHCP_INFO pInfo, DHCP_STEP step) { if (pInfo->step >= step) { return TRUE; } return FALSE; } static void get_task_result(PDHCP_INFO pInfo, char *pInBuf, int maxBuf) { if (pInfo->status == STA_ERROR) { snprintf(pInBuf, maxBuf, "Error at %s", dhcp_step_to_string(pInfo->step)); } else if (pInfo->step == STEP_END) { int ret; DHCP_OPT opt; const char *pIp = NULL, *pNetmask = NULL, *pDns1 = NULL, *pDns2 = NULL; U32 optSize = 0; PDHCP_PROTO pDhcp = get_dhcp_date(pInfo->pAckBuf.p, &optSize, pInfo->pAckBuf.buf_size); pIp = u32_to_str_ip_safe(pDhcp->yiaddr); ret = dhcp_get_option(OPT_NETMASK, pDhcp->options, optSize, &opt); if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) { pNetmask = u32_to_str_ip_safe(*((U32 *)opt.pValue)); } ret = dhcp_get_option(OPT_DNS, pDhcp->options, optSize, &opt); if (ret == ERR_SUCCESS && opt.len >= sizeof(U32)) { U32 *pVal = (U32 *)opt.pValue; pDns1 = u32_to_str_ip_safe(*pVal); if (opt.len > sizeof(U32)) { pVal++; pDns2 = u32_to_str_ip_safe(*pVal); } } snprintf(pInBuf, maxBuf, "IP: %s/%u, DNS: [%s, %s]", pIp, ipv4_mask_to_cidr(pNetmask), pDns1, pDns2); if (pIp) { free((void *)pIp); } if (pDns1) { free((void *)pDns1); } if (pDns2) { free((void *)pDns2); } if (pNetmask) { free((void *)pNetmask); } } else { pInBuf[0] = 0; } } void view_popup_menu_onStatistics(GtkWidget *UNUSED(menuitem), gpointer userdata) { //PDHCP_INFO pInfo = (PDHCP_INFO)userdata; //hex_wnd_show(pInfo); } void view_popup_menu_onBinaryPkg(GtkWidget *UNUSED(menuitem), gpointer userdata) { PDHCP_INFO pInfo = (PDHCP_INFO)userdata; //GtkWidget *deatilWnd = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "wndDetails")); // //g_print("Do something of %s\n", pInfo->treeId); //gtk_notebook_set_current_page(GTK_NOTEBOOK(tab), 0); //gtk_widget_show(deatilWnd); details_wnd_show(pInfo); } void view_popup_menu(GtkWidget *UNUSED(treeview), GdkEventButton *event, gpointer userdata) { GtkWidget *menu, *menuitem; menu = gtk_menu_new(); menuitem = gtk_menu_item_new_with_label("数据包详情"); g_signal_connect(menuitem, "activate", (GCallback)view_popup_menu_onBinaryPkg, userdata); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); menuitem = gtk_menu_item_new_with_label("统计信息"); g_signal_connect(menuitem, "activate", (GCallback)view_popup_menu_onStatistics, userdata); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); gtk_widget_show_all(menu); gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event); } gboolean view_onButtonPressed(GtkWidget *treeview, GdkEventButton *event, gpointer UNUSED(userdata)) { gboolean showMenu = FALSE; PDHCP_INFO p = NULL; GtkTreeIter iter; GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); /* single click with the right mouse button? */ if (event->type == GDK_BUTTON_PRESS && event->button == 3) { /* optional: select row if no row is selected or only * one other row is selected (will only do something * if you set a tree selection mode as described later * in the tutorial) */ GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); /* Note: gtk_tree_selection_count_selected_rows() does not * exist in gtk+-2.0, only in gtk+ >= v2.2 ! */ if (gtk_tree_selection_count_selected_rows(selection) <= 1) { GtkTreePath *path; /* Get tree path for row that was clicked */ if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL)) { gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_path(selection, path); if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) { gchar *index; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, COL_INDEX, &index, -1); if (index[0] != 'V') { U32 id = strtoul(index, NULL, 10); HASH_FIND_INT(g_pDhcpInfo, &id, p); if (p) { showMenu = TRUE; } } g_free(index); } gtk_tree_path_free(path); } } if (showMenu) { view_popup_menu(treeview, event, p); } return TRUE; /* we handled this */ } return FALSE; /* we did not handle this */ } gboolean view_onPopupMenu(GtkWidget *treeview, gpointer userdata) { view_popup_menu(treeview, NULL, userdata); return TRUE; /* we handled this */ } static void tree_view_data_store_create() { int i, j; PDHCP_INFO pInfo, pTemp; GtkTreeIter iter, iter_child; GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkWidget *vniStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkWidget *numRequest = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); int nRequest = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numRequest)); int nVni = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vniStart)); gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); gtk_tree_store_clear(store); for (i = 0; i < nRequest; i++) { int isCreateRoot = FALSE; j = 0; HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { if (pInfo->vni == (nVni + i)) { char idx[64] = {0}; char mac[24] = {0}; sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", pInfo->mac[0], pInfo->mac[1], pInfo->mac[2], pInfo->mac[3], pInfo->mac[4], pInfo->mac[5]); if (!isCreateRoot) { sprintf(idx, "VNI %d", nVni + i); // 创建根节点 gtk_tree_store_append(store, &iter, NULL); // clang-format off gtk_tree_store_set(store, &iter, COL_INDEX, idx, COL_RESULT, "", COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, COL_ATTR_VISIABLE, FALSE, -1); // clang-format on isCreateRoot = TRUE; } gtk_tree_store_append(store, &iter_child, &iter); // clang-format off // 创建子节点 memset(idx, 0, 64); sprintf(idx, "%u", pInfo->index); gtk_tree_store_set(store, &iter_child, COL_INDEX, idx, COL_MAC, mac, COL_HOSTNAME, pInfo->hostname, COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), COL_ACK, calc_step_progress(pInfo, STEP_ACK), COL_RESULT, "", COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, COL_ATTR_VISIABLE, TRUE, -1); // clang-format on memset(pInfo->treeId, 0, 32); sprintf(pInfo->treeId, "%d:%d", i, j++); } } } gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_signal_connect(view, "button-press-event", (GCallback)view_onButtonPressed, NULL); g_signal_connect(view, "popup-menu", (GCallback)view_onPopupMenu, NULL); #if 0 for (i = 0; i < 1000; i++) { char buf[24] = {0}; char bufHost[32] = {0}; char bufVni[16] = {0}; sprintf(bufVni, "%d", i); sprintf(bufHost, "hostname%d", i); sprintf(buf, "06:01:02:%02X:%02X:%02X", (i & 0xFF0000) >> 16, (i & 0xFF00) >> 8, (i & 0xFF)); gtk_tree_store_append(store, &iter, NULL); // clang-format off gtk_tree_store_set(store, &iter, COL_INDEX, bufVni, COL_MAC, buf, COL_HOSTNAME, bufHost, COL_STATUS, 20.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Discover", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Offer", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Request", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "ACK", COL_RESULT, "", COL_STATUS, 10.0, -1); // clang-format on } #endif } static gboolean upgrade_status_bar_msg(gpointer UNUSED(pInfo)) { int tolTask = HASH_COUNT(g_pDhcpInfo); char buf[1024] = {0}; static S32 tmdiff = 0; GtkWidget *statusBar = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "labMsg")); GtkWidget *prgBar = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "prgTotal")); double percnt = vect_size(g_pErrTask) + vect_size(g_pFinishTask); if (g_runTask) { struct timeval tvNow; gettimeofday(&tvNow, NULL); tmdiff = MAX(0, (tvNow.tv_sec * 1000000 + tvNow.tv_usec) - (g_StartTm.tv_sec * 1000000 + g_StartTm.tv_usec)); } sprintf(buf, "Statistics: total %d | successed %d | error %d | total time %d.%03d(seconds)", tolTask, MIN(vect_size(g_pFinishTask), tolTask), vect_size(g_pErrTask), tmdiff / 1000000, (tmdiff % 1000000) / 1000); gtk_label_set_text(GTK_LABEL(statusBar), buf); if (tolTask > 0) { gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prgBar), percnt / tolTask); } else { gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prgBar), 0.0); } return FALSE; } static gboolean upgade_task(gpointer pInfo) { return FALSE; } static void tree_view_data_store_upgade(gpointer pInfo) { GtkTreeIter iter; GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkTreeModel *model; PDHCP_INFO p = (PDHCP_INFO)pInfo; if (!pInfo || !store || !g_runTask) { return; } model = GTK_TREE_MODEL(store); if (model && gtk_tree_model_get_iter_from_string(model, &iter, p->treeId)) { char info[256] = {0}; get_task_result(p, info, 256); // clang-format off gtk_tree_store_set(store, &iter, COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), COL_ACK, calc_step_progress(pInfo, STEP_ACK), COL_RESULT, info, COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, COL_ATTR_VISIABLE, TRUE, -1); // clang-format on if (strlen(info) > 0 && p->close == FALSE) { p->close = TRUE; g_endTask++; } } if (g_endTask == HASH_COUNT(g_pDhcpInfo)) { GtkWidget *startButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); GtkWidget *stoptButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); GtkWidget *tbExpand = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbExpand")); g_runTask = FALSE; gtk_widget_set_sensitive(GTK_WIDGET(stoptButton), FALSE); gtk_widget_set_sensitive(startButton, TRUE); gtk_widget_set_sensitive(nicSelect, TRUE); g_object_set(G_OBJECT(tbExpand), "stock_id", "gtk-indent", NULL); upgrade_status_bar_msg(NULL); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 0, "Finish test, successed %d, error %d\n", vect_size(g_pFinishTask), vect_size(g_pErrTask)); } } static void mainWnd_on_destroy(GObject *UNUSED(object), gpointer UNUSED(user_data)) { task_manager_exit(); g_thread_unref(g_pEvLoopThread); gtk_main_quit(); } int cacheDhcpOfferBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size) { pInfo->pOfferBuf.p = (U8 *)malloc(size); if (pInfo->pOfferBuf.p) { memcpy(pInfo->pOfferBuf.p, pBuf, size); pInfo->pOfferBuf.buf_size = size; return ERR_SUCCESS; } return -ERR_MALLOC_MEMORY; } int cacheDhcpAckBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size) { pInfo->pAckBuf.p = (U8 *)malloc(size); if (pInfo->pAckBuf.p) { memcpy(pInfo->pAckBuf.p, pBuf, size); pInfo->pAckBuf.buf_size = size; return ERR_SUCCESS; } return -ERR_MALLOC_MEMORY; } _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { U8 *pkg; int size = 0; PDHCP_INFO pInfo, pTemp; struct timeval now; while (TRUE) { if (!g_runTask) { g_usleep(1000); continue; } HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { switch (pInfo->step) { case STEP_BEGIN: pInfo->pDiscBuf.p = dhcp_create_discover_req(pInfo, &size); if (pInfo->pDiscBuf.p) { pInfo->pDiscBuf.buf_size = size; pInfo->step = STEP_DISCOVER; pInfo->status = STA_WAIT_START; g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); } break; case STEP_DISCOVER: if (pInfo->status == STA_WAIT_START) { pkg = get_pkg_free_buf(); if (pkg) { memcpy(pkg, pInfo->pDiscBuf.p, pInfo->pDiscBuf.buf_size); if (pkg_mmap_tx((U8 *)pkg, pInfo->pDiscBuf.buf_size) == pInfo->pDiscBuf.buf_size) { pInfo->status = STA_SEND_REQ; gettimeofday(&pInfo->pDiscBuf.tm, NULL); pInfo->pDiscBuf.snd += 1; g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host send DHCP Discover\n", pInfo->vni, pInfo->hostname); } } } else if (pInfo->status == STA_SEND_REQ) { // 处理超时 gettimeofday(&now, NULL); if (now.tv_sec - pInfo->pDiscBuf.tm.tv_sec > DHCP_STEP_TIMEOUT) { if (pInfo->pDiscBuf.snd < DHCP_PKG_RETRY) { // 超时重传 pInfo->status = STA_WAIT_START; ADD_LOG_MSG(ZLOG_LEVEL_WARN, 1, "User %u host receive DHCP Offer timeout, retry send Discover %d\n", pInfo->vni, pInfo->hostname, pInfo->pDiscBuf.snd); } else { pInfo->status = STA_ERROR; vect_push(g_pErrTask, &pInfo->index); g_idle_add(upgrade_status_bar_msg, NULL); ADD_LOG_MSG(ZLOG_LEVEL_ERROR, 1, "User %u host receive DHCP Offer error, retry %d\n", pInfo->vni, pInfo->hostname, pInfo->pDiscBuf.snd); } } } else if (pInfo->status == STA_RECV_NACK) { pInfo->status = STA_ERROR; vect_push(g_pErrTask, &pInfo->index); g_idle_add(upgrade_status_bar_msg, NULL); g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_ERROR, 1, "User %u host receive DHCP NACK error, retry %d\n", pInfo->vni, pInfo->hostname, pInfo->pDiscBuf.snd); } break; case STEP_OFFER: if (pInfo->status == STA_RECV_RSP) { pInfo->pReqBuf.p = dhcp_create_request_req(pInfo, &size); if (pInfo->pReqBuf.p) { pInfo->pReqBuf.buf_size = size; pInfo->step = STEP_REQUEST; pInfo->status = STA_WAIT_START; g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host receive DHCP Offer information\n", pInfo->vni, pInfo->hostname); } } break; case STEP_REQUEST: if (pInfo->status == STA_WAIT_START) { pkg = get_pkg_free_buf(); if (pkg) { memcpy(pkg, pInfo->pReqBuf.p, pInfo->pReqBuf.buf_size); if (pkg_mmap_tx((U8 *)pkg, pInfo->pReqBuf.buf_size) == pInfo->pReqBuf.buf_size) { pInfo->status = STA_SEND_REQ; gettimeofday(&pInfo->pReqBuf.tm, NULL); pInfo->pReqBuf.snd += 1; g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host send DHCP Request\n", pInfo->vni, pInfo->hostname); } } } else if (pInfo->status == STA_SEND_REQ) { // 处理超时 gettimeofday(&now, NULL); if (now.tv_sec - pInfo->pReqBuf.tm.tv_sec > DHCP_STEP_TIMEOUT) { if (pInfo->pReqBuf.snd < DHCP_PKG_RETRY) { // 超时重传 pInfo->status = STA_WAIT_START; ADD_LOG_MSG(ZLOG_LEVEL_WARN, 1, "User %u host receive DHCP ACK timeout, retry send Request %d\n", pInfo->vni, pInfo->hostname, pInfo->pReqBuf.snd); } else { pInfo->status = STA_ERROR; vect_push(g_pErrTask, &pInfo->index); g_idle_add(upgrade_status_bar_msg, NULL); g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_WARN, 1, "User %u host receive DHCP ACK timeout, retry %d\n", pInfo->vni, pInfo->hostname, pInfo->pReqBuf.snd); } } } else if (pInfo->status == STA_RECV_NACK) { pInfo->status = STA_ERROR; vect_push(g_pErrTask, &pInfo->index); g_idle_add(upgrade_status_bar_msg, NULL); g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); ADD_LOG_MSG(ZLOG_LEVEL_WARN, 1, "User %u host receive DHCP NACK timeout, retry %d\n", pInfo->vni, pInfo->hostname, pInfo->pReqBuf.snd); } break; case STEP_ACK: if (pInfo->status == STA_RECV_RSP) { pInfo->step = STEP_END; pInfo->status = STA_RECV_RSP; vect_push(g_pFinishTask, &pInfo->index); g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, upgade_task, pInfo, tree_view_data_store_upgade); g_idle_add(upgrade_status_bar_msg, NULL); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 1, "User %u host receive DHCP ACK, finished.\n", pInfo->vni, pInfo->hostname); } break; default: break; } } g_usleep(100); } LOG_MSG(debug, "DHCP status mathine exit......\n"); } static void cleanupDHCPInfo() { PDHCP_INFO pInfo, pTemp; HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { HASH_DEL(g_pDhcpInfo, pInfo); if (pInfo->pOfferBuf.p) { free(pInfo->pOfferBuf.p); } if (pInfo->pDiscBuf.p) { free(pInfo->pDiscBuf.p); } if (pInfo->pReqBuf.p) { free(pInfo->pReqBuf.p); } if (pInfo->pAckBuf.p) { free(pInfo->pAckBuf.p); } free(pInfo); } } static void mainWnd_on_tb_start(GObject *object, gpointer UNUSED(user_data)) { int i, j, index = 0; GtkTreeIter iter; GtkTextIter it, it1; PDHCP_INFO pInfo; GtkTreeModel *cobModel; gchar *pCobText; unsigned char mac[6]; U32 macVal; GtkWidget *stopButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); GtkWidget *macBegin = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtMacStart")); GtkWidget *preHostname = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtHostname")); GtkWidget *vniStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkWidget *numVniCli = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVniClient")); GtkWidget *numRequest = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); GtkWidget *txLog = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtLogout")); GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txLog)); const char *strMacBegin = gtk_entry_get_text(GTK_ENTRY(macBegin)); const char *strPreHostname = gtk_entry_get_text(GTK_ENTRY(preHostname)); U32 nRequest = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numRequest)); U32 nVni = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vniStart)); U32 nVniCnt = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numVniCli)); string_mac_to_bytes(strMacBegin, mac); macVal = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; cleanupDHCPInfo(); g_endTask = 0; if (g_pFinishTask) { vect_clear(g_pFinishTask); } if (g_pErrTask) { vect_clear(g_pErrTask); } g_pFinishTask = vect_create(nRequest * nVniCnt, sizeof(U32), ZV_SEC_WIPE); g_pErrTask = vect_create(nRequest * nVniCnt, sizeof(U32), ZV_SEC_WIPE); for (i = 0; i < nRequest; i++) { for (j = 0; j < nVniCnt; j++) { U32 macAddr = macVal + index; pInfo = (PDHCP_INFO)malloc(sizeof(DHCP_INFO)); if (pInfo == NULL) { fprintf(stderr, "Malloc %lu bytes memory error of %d\n", sizeof(DHCP_INFO), i); continue; } memset(pInfo, 0, sizeof(DHCP_INFO)); pInfo->index = index; pInfo->vni = nVni + i; pInfo->mac[0] = mac[0]; pInfo->mac[1] = mac[1]; pInfo->mac[2] = (macAddr & 0xFF000000) >> 24; pInfo->mac[3] = (macAddr & 0xFF0000) >> 16; pInfo->mac[4] = (macAddr & 0xFF00) >> 8; pInfo->mac[5] = (macAddr & 0xFF); sprintf(pInfo->hostname, "%s_%u", strPreHostname, pInfo->vni + index); pInfo->step = STEP_BEGIN; pInfo->status = STA_WAIT_START; pInfo->close = FALSE; HASH_ADD_INT(g_pDhcpInfo, index, pInfo); index++; } } gtk_widget_set_sensitive(GTK_WIDGET(object), FALSE); gtk_widget_set_sensitive(nicSelect, FALSE); tree_view_data_store_create(); gtk_widget_set_sensitive(stopButton, TRUE); cobModel = gtk_combo_box_get_model(GTK_COMBO_BOX(nicSelect)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(nicSelect), &iter); gtk_tree_model_get(cobModel, &iter, 0, &pCobText, -1); dhcp_tools_init_network(pCobText); g_runTask = TRUE; gettimeofday(&g_StartTm, NULL); gtk_text_buffer_get_start_iter(buffer, &it); gtk_text_buffer_get_end_iter(buffer, &it1); gtk_text_buffer_delete(buffer, &it, &it1); ADD_LOG_MSG(ZLOG_LEVEL_INFO, 0, "Begin test total user: %d, %d host/user\n", nRequest, nVniCnt); } static void mainWnd_on_tb_stop(GObject *object, gpointer UNUSED(user_data)) { GtkWidget *startButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); GtkWidget *tbExpand = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbExpand")); g_runTask = FALSE; gtk_widget_set_sensitive(GTK_WIDGET(object), FALSE); gtk_widget_set_sensitive(startButton, TRUE); gtk_widget_set_sensitive(nicSelect, TRUE); gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(tbExpand), FALSE); g_object_set(G_OBJECT(tbExpand), "stock_id", "gtk-indent", NULL); } static void mainWnd_on_tb_expand(GObject *object, gpointer UNUSED(user_data)) { GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(object))) { gtk_tree_view_expand_all(GTK_TREE_VIEW(view)); g_object_set(object, "stock_id", "gtk-unindent", NULL); } else { gtk_tree_view_collapse_all(GTK_TREE_VIEW(view)); g_object_set(object, "stock_id", "gtk-indent", NULL); } } static void mainWnd_on_tb_cleanup(GObject *UNUSED(object), gpointer UNUSED(user_data)) { GtkTextIter it, it1; GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkWidget *tbStop = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); GtkWidget *txLog = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtLogout")); GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txLog)); gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); gtk_tree_store_clear(store); cleanupDHCPInfo(); mainWnd_on_tb_stop(G_OBJECT(tbStop), NULL); gtk_text_buffer_get_start_iter(buffer, &it); gtk_text_buffer_get_end_iter(buffer, &it1); gtk_text_buffer_delete(buffer, &it, &it1); } static void *uv_loop_thread(void *UNUSED(pData)) { task_manager_run(); return NULL; } static GtkTextBuffer *g_pLogTxtBuf = NULL; static gboolean upgrade_gtk_txt_msg(gpointer pInfo) { GtkTextIter iter; gtk_text_buffer_get_end_iter(g_pLogTxtBuf, &iter); gtk_text_buffer_insert(g_pLogTxtBuf, &iter, (const char *)pInfo, -1); free(pInfo); return FALSE; } void write_log_msg(const char *pMsg, int mode) { if (g_pLogTxtBuf == NULL) { GtkWidget *txLog = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtLogout")); g_pLogTxtBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txLog)); } if (pMsg && strlen(pMsg) > 0 && g_pLogTxtBuf) { if (mode == 0) { GtkTextIter iter; gtk_text_buffer_get_end_iter(g_pLogTxtBuf, &iter); gtk_text_buffer_insert(g_pLogTxtBuf, &iter, pMsg, -1); } else { g_idle_add(upgrade_gtk_txt_msg, (gpointer)pMsg); } } } int main(int args, char **argv) { int i, ret; GtkTreeIter iter; SYS_NIC_INFO info = {0}; if ((ret = zlog_init(ZLOG_CFG_PATH)) != ERR_SUCCESS) { printf("Zlog configure file [%s] init result: %d+++++\n", ZLOG_CFG_PATH, ret); zlog_profile(); return -ERR_ZLOG_INIT; } else { LOG_MOD(debug, ZLOG_MOD_INIT, "Zlog used configure file [%s]\n", ZLOG_CFG_PATH); dzlog_init(ZLOG_CFG_PATH, get_cur_process_name()); } get_all_network_info(&info); gtk_init(&args, &argv); load_css(); g_mainBuilder = gtk_builder_new(); gtk_builder_add_from_file(g_mainBuilder, "./res/main.glade", NULL); GtkWidget *mainWnd = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "wndMain")); g_signal_connect(mainWnd, "destroy", G_CALLBACK(mainWnd_on_destroy), g_mainBuilder); GtkWidget *txtLog = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtLogout")); gtk_widget_set_name(txtLog, "txtLogout"); GtkWidget *tbStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); g_signal_connect(tbStart, "clicked", G_CALLBACK(mainWnd_on_tb_start), g_mainBuilder); GtkWidget *tbStop = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); g_signal_connect(tbStop, "clicked", G_CALLBACK(mainWnd_on_tb_stop), g_mainBuilder); GtkWidget *tbExpand = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbExpand")); g_signal_connect(tbExpand, "clicked", G_CALLBACK(mainWnd_on_tb_expand), g_mainBuilder); GtkWidget *tbClean = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbCleanup")); g_signal_connect(tbClean, "clicked", G_CALLBACK(mainWnd_on_tb_cleanup), g_mainBuilder); GtkWidget *cbNic = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); for (i = 0; i < info.nicCnt; i++) { GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(g_mainBuilder, "lsNicName")); gtk_combo_box_set_model(GTK_COMBO_BOX(cbNic), GTK_TREE_MODEL(store)); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, info.pNicCtx[i].ethName, -1); if (i == info.nicCnt - 1) { gtk_combo_box_set_active(GTK_COMBO_BOX(cbNic), i); } } if (info.pNicCtx) { free(info.pNicCtx); } //GtkWidget *macTxt = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtMacStart")); GtkWidget *numInc = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); GtkAdjustment *adj = gtk_adjustment_new(1, 1, 100000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numInc), adj); GtkWidget *numVni = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkAdjustment *adjVni = gtk_adjustment_new(1, 0, 10000000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVni), adjVni); GtkWidget *numVniCli = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVniClient")); GtkAdjustment *adjVniCli = gtk_adjustment_new(1, 1, 1000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVniCli), adjVniCli); //GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); details_wnd_create(g_mainBuilder); //hex_wnd_create(g_mainBuilder); //statis_wnd_create(g_mainBuilder); #if 0 gtk_list_store_new(NUM_COLS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_FLOAT); #endif GdkDisplay *display = gdk_display_get_default(); GdkMonitor *monitor = gdk_display_get_primary_monitor(display); GdkRectangle rect; gdk_monitor_get_geometry(monitor, &rect); gtk_widget_set_size_request(mainWnd, MAIN_WND_WIDTH, MAIN_WND_HEIGHT); // 设置窗口的最小大小 gtk_window_move(GTK_WINDOW(mainWnd), (rect.width - MAIN_WND_WIDTH) / 2, (rect.height - MAIN_WND_HEIGHT) / 2); gtk_builder_connect_signals(g_mainBuilder, NULL); gtk_widget_show(mainWnd); upgrade_status_bar_msg(NULL); g_pEvLoopThread = g_thread_new("uv_loop", uv_loop_thread, NULL); g_thread_new("dhcp", dhcpThreadCb, NULL); gtk_main(); return 0; }