From 2719023967b01613ceef25ecc65e87fc3fb67fa6 Mon Sep 17 00:00:00 2001 From: huangxin Date: Thu, 20 Apr 2023 17:20:30 +0800 Subject: [PATCH] =?UTF-8?q?OCT=201.=20dhcp=20=E6=B5=8B=E8=AF=95=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=8C=85=E5=8F=91?= =?UTF-8?q?=E9=80=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dhcp_tools/CMakeLists.txt | 6 +- dhcp_tools/main.h | 62 ++++++ dhcp_tools/main_wnd.c | 419 +++++++++++++++++++++++++++++++------- dhcp_tools/res/main.glade | 136 +++++++++++-- dhcp_tools/res/style.css | 2 +- dhcp_tools/uv_rawsocket.c | 221 ++++++++++++++++++++ 6 files changed, 758 insertions(+), 88 deletions(-) create mode 100644 dhcp_tools/main.h create mode 100644 dhcp_tools/uv_rawsocket.c diff --git a/dhcp_tools/CMakeLists.txt b/dhcp_tools/CMakeLists.txt index 8bcb6b7..0d0e7a5 100644 --- a/dhcp_tools/CMakeLists.txt +++ b/dhcp_tools/CMakeLists.txt @@ -7,7 +7,9 @@ PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0) INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS}) LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS}) -INCLUDE_DIRECTORIES(. ${CMAKE_SOURCE_DIR}/srcs/include ${CMAKE_SOURCE_DIR}/srcs/libs/include) +INCLUDE_DIRECTORIES(. ${CMAKE_SOURCE_DIR}/srcs/include + ${CMAKE_SOURCE_DIR}/srcs/service/dhcpd/include + ${CMAKE_SOURCE_DIR}/srcs/libs/include) FILE(GLOB PROJECT_HEADS ./*.h) AUX_SOURCE_DIRECTORY(./ PROJECT_SRC) @@ -26,5 +28,7 @@ ADD_CUSTOM_COMMAND(TARGET ${PROJECT_TARGET} POST_BUILD COMMENT "!!!!!! Notice: Automatic upgreade GTK3 UI files after build project." COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/res/" + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/config/" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/config/zlog.conf" "${CMAKE_CURRENT_BINARY_DIR}/config/" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/dhcp_tools/res/style.css" "${CMAKE_CURRENT_BINARY_DIR}/res/" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/dhcp_tools/res/main.glade" "${CMAKE_CURRENT_BINARY_DIR}/res/") \ No newline at end of file diff --git a/dhcp_tools/main.h b/dhcp_tools/main.h new file mode 100644 index 0000000..a2d04bf --- /dev/null +++ b/dhcp_tools/main.h @@ -0,0 +1,62 @@ +// +// Created by xajhuang on 2023/4/19. +// + +#ifndef VCPE_MAIN_H +#define VCPE_MAIN_H + +#include "uthash/uthash.h" + +typedef enum { + COL_INDEX = 0, + COL_MAC, + COL_HOSTNAME, + COL_DISCOVER, + COL_OFFER, + COL_REQUEST, + COL_ACK, + COL_RESULT, + COL_STATUS, + + NUM_COLS +} COL_NAME; + +typedef enum { + STEP_BEGIN = 0, + STEP_DISCOVER, + STEP_OFFER, + STEP_REQUEST, + STEP_ACK, + STEP_END, +} DHCP_STEP; + +typedef enum { + STA_WAIT_START = 0, + STA_SEND_REQ, + STA_RECV_RSP, + STA_FINISHED, +} DHCP_STATUS; + +typedef struct { + U8 *p; + int buf_size; +} BUF_INFO, *PBUF_INFO; + +typedef struct { + U32 index; + U32 vni; + U8 mac[6]; + S8 hostname[64]; + DHCP_STEP step; + DHCP_STATUS status; + BUF_INFO pDiscBuf; + BUF_INFO pOfferBuf; + BUF_INFO pReqBuf; + BUF_INFO pAckBuf; + UT_hash_handle hh; +} DHCP_INFO, *PDHCP_INFO; + +U32 rand_number(); +int dhcp_tools_init_network(const char *pNicName); +U8 *dhcp_create_discover_req(PDHCP_INFO pInfo, int *pOutSize); +#endif //VCPE_MAIN_H diff --git a/dhcp_tools/main_wnd.c b/dhcp_tools/main_wnd.c index 19f3750..0285933 100644 --- a/dhcp_tools/main_wnd.c +++ b/dhcp_tools/main_wnd.c @@ -2,18 +2,28 @@ // Created by xajhuang on 2023/4/12. // #include +#include +#include "common.h" +#include "main.h" +#include "misc.h" +#include "task_manager.h" +#include "user_errno.h" +#include "zlog_module.h" +#include "dhcp_network.h" -typedef enum { - COL_VNI = 0, - COL_MAC, - COL_HOSTNAME, - COL_STEP, - COL_RESULT, - COL_STATUS, - NUM_COLS -} COL_NAME; +#define ZLOG_CFG_PATH "./config/zlog.conf" -static GtkBuilder *g_main_builder; +static GtkBuilder *g_mainBuilder = NULL; +static PDHCP_INFO g_pDhcpInfo = NULL; +static GThread *g_pEvLoopThread = NULL; +static GThread *g_pDHCPSTMThread = NULL; +static int g_runTask = FALSE; + +U32 rand_number() { + GRand *pRand = g_rand_new_with_seed(time(NULL)); + + return g_rand_int(pRand); +} static void load_css(void) { GtkCssProvider *provider; @@ -33,22 +43,68 @@ static void load_css(void) { gtk_css_provider_load_from_file(provider, css_fp, &error); } -G_MODULE_EXPORT void __mainWnd_on_destroy(GObject *object, gpointer user_data) { - gtk_main_quit(); +static double calc_total_progress(PDHCP_INFO pInfo) { + double pre_cnt = 0.0; + + if (pInfo) { + pre_cnt += pInfo->step * 20; + pre_cnt += pInfo->status * 5; + } + + return pre_cnt; } -static void add_item_to_list_view(GtkWidget *list, - int idx, - const char *pMac, - const char *pHostname, - const char *pDiscover, - const char *pOffer, - const char *pRequest, - const char *pAck) { - int i, j; - GtkTreeIter iter, iter_child, iter_sub; - GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list))); +static double calc_step_progress(PDHCP_INFO pInfo, DHCP_STEP step) { + double pre_cnt = 0.0; + if (pInfo && pInfo->step == step) { + pre_cnt += pInfo->status * 5; + } + + return pre_cnt; +} + +static void tree_view_data_store_create() { + int i, j; + PDHCP_INFO pInfo, pTemp; + GtkTreeIter iter, iter_child, iter_sub; + GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); + GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); + + gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); + gtk_list_store_clear(store); + + HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { + 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]); + + gtk_list_store_append(store, &iter); + + // clang-format off + gtk_list_store_set(store, + &iter, + COL_INDEX, pInfo->index, + 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), + -1); + // clang-format on + } + + gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); +#if 0 for (i = 0; i < 1000; i++) { char buf[24] = {0}; char bufHost[32] = {0}; @@ -60,67 +116,296 @@ static void add_item_to_list_view(GtkWidget *list, gtk_tree_store_append(store, &iter, NULL); // clang-format off - gtk_tree_store_set(store, &iter, - COL_VNI, bufVni, - COL_MAC, buf, - COL_HOSTNAME, bufHost, - COL_STATUS, 20.0, - -1); + 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_VNI, "", - COL_STEP, "Discover", - COL_RESULT, "", - COL_STATUS, 10.0, - -1); + 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_VNI, "", - COL_STEP, "Offer", - COL_RESULT, "", - COL_STATUS, 10.0, - -1); + 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_VNI, "", - COL_STEP, "Request", - COL_RESULT, "", - COL_STATUS, 10.0, - -1); + 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_VNI, "", - COL_STEP, "ACK", - COL_RESULT, "", - COL_STATUS, 10.0, - -1); + COL_INDEX, "", + COL_STEP, "ACK", + COL_RESULT, "", + COL_STATUS, 10.0, + -1); + // clang-format on + } +#endif + //g_object_unref(store); +} + +static gboolean tree_view_data_store_upgade(gpointer pInfo) { + char buf[32] = {0}; + GtkTreePath *path; + GtkTreeIter iter; + GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); + + if (!pInfo) { + return FALSE; + } + + sprintf(buf, "%d", ((PDHCP_INFO)pInfo)->index); + + if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, buf)) { + // clang-format off + gtk_list_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, "", + COL_STATUS, calc_total_progress(pInfo), + -1); // clang-format on } } -int main(int argc, char **argv) { - gtk_init(&argc, &argv); +G_MODULE_EXPORT void __mainWnd_on_destroy(GObject *object, gpointer user_data) { + task_manager_exit(); + g_thread_unref(g_pEvLoopThread); + gtk_main_quit(); +} + +static void *dhcpThreadCb(void *pData) { + U8 *pkg; + int size = 0; + PDHCP_INFO pInfo, pTemp; + + 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(tree_view_data_store_upgade, pInfo); + } + break; + case STEP_DISCOVER: + switch (pInfo->status) { + case 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; + g_idle_add(tree_view_data_store_upgade, pInfo); + } + } + break; + case STA_SEND_REQ: + break; + case STA_RECV_RSP: + break; + case STA_FINISHED: + break; + } + break; + case STEP_OFFER: + break; + case STEP_REQUEST: + break; + case STEP_ACK: + break; + case STEP_END: + break; + } + } + + g_usleep(100); + } + + LOG_MSG(debug, "DHCP status mathine exit......\n"); + g_thread_exit(NULL); + return NULL; +} + +G_MODULE_EXPORT void __mainWnd_on_tb_start(GObject *object, gpointer user_data) { + int i; + PDHCP_INFO pInfo, pTemp; + 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 *numRequest = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); + 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)); + + string_mac_to_bytes(strMacBegin, mac); + macVal = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; + + HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { + HASH_DEL(g_pDhcpInfo, pInfo); + free(pInfo); + } + + for (i = 0; i < nRequest; i++) { + char strMac[6]; + U32 macAddr = macVal + i; + 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 = i; + 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); + pInfo->step = STEP_BEGIN; + pInfo->status = STA_WAIT_START; + + HASH_ADD_INT(g_pDhcpInfo, index, pInfo); + } + + 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); + + dhcp_tools_init_network("ens192"); + + g_runTask = TRUE; +} + +G_MODULE_EXPORT void __mainWnd_on_tb_stop(GObject *object, gpointer user_data) { + GtkWidget *startButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); + GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); + // PDHCP_INFO pInfo; + // GRand *pRnd = g_rand_new_with_seed(time(NULL)); + // unsigned int val = g_rand_int(pRnd) % 100; + // + // HASH_FIND_INT(g_pDhcpInfo, &val, pInfo); + // + // if (pInfo) { + // tree_view_data_store_upgade(pInfo); + // printf("Upgrade treeview row %u\n", val); + // } + + printf("__mainWnd_on_tb_stop\n"); + g_runTask = FALSE; + //g_thread_join(g_pDHCPSTMThread); + + gtk_widget_set_sensitive(GTK_WIDGET(object), FALSE); + gtk_widget_set_sensitive(startButton, TRUE); + gtk_widget_set_sensitive(nicSelect, TRUE); +} + +static void *uv_loop_thread(void *pData) { + static uv_timer_t uvTm; + task_manager_run(); + return NULL; +} + +int main(int args, char **argv) { + int i, ret; + GtkTreeIter iter; + GList *pNicList = NULL; + 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_main_builder = gtk_builder_new(); - gtk_builder_add_from_file(g_main_builder, "./res/main.glade", NULL); + 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_main_builder, "wndMain")); + GtkWidget *mainWnd = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "wndMain")); + g_signal_connect(mainWnd, "destroy", G_CALLBACK(__mainWnd_on_destroy), g_mainBuilder); - GtkWidget *macTxt = GTK_WIDGET(gtk_builder_get_object(g_main_builder, "txtMacStart")); - //gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(macTxt)), "txtMacStart"); + 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 *numInc = GTK_WIDGET(gtk_builder_get_object(g_main_builder, "sbReqNum")); + 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 *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(1000, 1, 100000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numInc), adj); - GtkWidget *numVni = GTK_WIDGET(gtk_builder_get_object(g_main_builder, "sbVni")); + GtkWidget *numVni = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkAdjustment *adjVni = gtk_adjustment_new(1, 1, 10000000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVni), adjVni); -#if 1 - GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_main_builder, "treeResult")); - GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_main_builder, "tsDhcpInfo")); + + GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); + #if 0 gtk_list_store_new(NUM_COLS, G_TYPE_INT, @@ -132,17 +417,13 @@ int main(int argc, char **argv) { G_TYPE_STRING, G_TYPE_FLOAT); #endif - gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); - add_item_to_list_view(view, 0, NULL, NULL, NULL, NULL, NULL, NULL); - g_object_unref(store); - -#endif - - gtk_builder_connect_signals(g_main_builder, NULL); - //g_object_unref(G_OBJECT(g_main_builder)); + gtk_builder_connect_signals(g_mainBuilder, NULL); + //g_object_unref(G_OBJECT(g_mainBuilder)); gtk_widget_show(mainWnd); + g_pEvLoopThread = g_thread_new("uv_loop", uv_loop_thread, NULL); + g_pDHCPSTMThread = g_thread_new("dhcp", dhcpThreadCb, NULL); gtk_main(); return 0; diff --git a/dhcp_tools/res/main.glade b/dhcp_tools/res/main.glade index 1fe6fbf..0108787 100644 --- a/dhcp_tools/res/main.glade +++ b/dhcp_tools/res/main.glade @@ -2,25 +2,36 @@ - + - - + + - - + + + + + + + + + + + + + + 1024 - True @@ -169,6 +180,7 @@ True + True Start True gtk-media-play @@ -181,8 +193,9 @@ True + False + True Stop - True gtk-media-stop @@ -210,7 +223,7 @@ True 5 2 - 4 + 6 5 5 @@ -268,10 +281,11 @@ - + True True + hostname 3 @@ -304,6 +318,40 @@ 2 + + + True + 0 + 网卡: + + + 4 + 5 + + + + + 64 + True + lsNicName + + + + 0 + + + + + 5 + 6 + + + + + + + + @@ -341,7 +389,8 @@ both - VNI + 32 + Index 0.5 @@ -353,6 +402,7 @@ + 128 MAC 0.5 @@ -365,6 +415,7 @@ + 64 Hostname 0.5 @@ -376,38 +427,89 @@ - + autosize - Step + 64 + 96 + Discover 0.5 - + - 3 + 3 + + + + + + + autosize + 64 + 96 + Offer + 0.5 + + + + 4 + + + + + + + autosize + 96 + Request + 0.5 + + + + 5 + + + + + + + autosize + 96 + ACK + 0.5 + + + + 6 + fixed + 200 Result 0.5 - 4 + 7 - Staus + fixed + 64 + 64 + 64 + Totol Progress 0.5 - 5 + 8 diff --git a/dhcp_tools/res/style.css b/dhcp_tools/res/style.css index 5e1295f..66eb59a 100644 --- a/dhcp_tools/res/style.css +++ b/dhcp_tools/res/style.css @@ -8,7 +8,7 @@ spinbutton { } .view { - font: 16px "Comic Sans"; + font: 14px "Comic Sans"; } entry { diff --git a/dhcp_tools/uv_rawsocket.c b/dhcp_tools/uv_rawsocket.c new file mode 100644 index 0000000..3213d75 --- /dev/null +++ b/dhcp_tools/uv_rawsocket.c @@ -0,0 +1,221 @@ +// +// Created by xajhuang on 2023/4/20. +// +#include +#include +#include +#include "user_errno.h" +#include "dhcp_network.h" +#include "dhcp_options.h" +#include "zlog_module.h" +#include "main.h" +#include "rfc2131.h" +#include "misc.h" + +static char *g_pNicName = NULL; + +static struct sock_filter g_filterCode[] = { + // region BPF code + // create by: tcpdump "vlan and udp and port 67 and port 68" -dd + {0x0, 0, 0, 0x00000000}, + {0x2, 0, 0, 0x00000000}, + {0x2, 0, 0, 0x00000001}, + {0x30, 0, 0, 0xfffff030}, + {0x15, 7, 0, 0x00000001}, + {0x0, 0, 0, 0x00000004}, + {0x2, 0, 0, 0x00000000}, + {0x2, 0, 0, 0x00000001}, + {0x28, 0, 0, 0x0000000c}, + {0x15, 2, 0, 0x00008100}, + {0x15, 1, 0, 0x000088a8}, + {0x15, 0, 56, 0x00009100}, + {0x61, 0, 0, 0x00000001}, + {0x48, 0, 0, 0x0000000c}, + {0x15, 0, 13, 0x000086dd}, + {0x61, 0, 0, 0x00000000}, + {0x50, 0, 0, 0x00000014}, + {0x15, 0, 50, 0x00000011}, + {0x61, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x00000036}, + {0x15, 0, 3, 0x00000043}, + {0x61, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x00000038}, + {0x15, 43, 44, 0x00000044}, + {0x15, 0, 43, 0x00000044}, + {0x61, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x00000038}, + {0x15, 39, 40, 0x00000043}, + {0x15, 0, 39, 0x00000800}, + {0x61, 0, 0, 0x00000000}, + {0x50, 0, 0, 0x00000017}, + {0x15, 0, 36, 0x00000011}, + {0x61, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x00000014}, + {0x45, 33, 0, 0x00001fff}, + {0x61, 0, 0, 0x00000000}, + {0x50, 0, 0, 0x0000000e}, + {0x54, 0, 0, 0x0000000f}, + {0x64, 0, 0, 0x00000002}, + {0xc, 0, 0, 0x00000000}, + {0x7, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x0000000e}, + {0x15, 0, 8, 0x00000043}, + {0x61, 0, 0, 0x00000000}, + {0x50, 0, 0, 0x0000000e}, + {0x54, 0, 0, 0x0000000f}, + {0x64, 0, 0, 0x00000002}, + {0xc, 0, 0, 0x00000000}, + {0x7, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x00000010}, + {0x15, 16, 17, 0x00000044}, + {0x61, 0, 0, 0x00000000}, + {0x50, 0, 0, 0x0000000e}, + {0x54, 0, 0, 0x0000000f}, + {0x64, 0, 0, 0x00000002}, + {0xc, 0, 0, 0x00000000}, + {0x7, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x0000000e}, + {0x15, 0, 9, 0x00000044}, + {0x61, 0, 0, 0x00000000}, + {0x50, 0, 0, 0x0000000e}, + {0x54, 0, 0, 0x0000000f}, + {0x64, 0, 0, 0x00000002}, + {0xc, 0, 0, 0x00000000}, + {0x7, 0, 0, 0x00000000}, + {0x48, 0, 0, 0x00000010}, + {0x15, 0, 1, 0x00000043}, + {0x6, 0, 0, 0x00040000}, + {0x6, 0, 0, 0x00000000}, + // endregion +}; + +static struct sock_fprog bpf = { + .len = sizeof(g_filterCode) / (sizeof(struct sock_filter)), + .filter = g_filterCode, +}; + +U8 *dhcp_create_discover_req(PDHCP_INFO pInfo, int *pOutSize) { + static U8 reqParams[] = {0x01, 0x1c, 0x02, 0x03, 0x0f, 0x06, 0x77, 0x0c, 0x2c, 0x2f, 0x1a, 0x79, 0x2a}; + U8 *pOpt; + U16 csum; + int tolSize; + U8 *pReqData = (U8 *)malloc(MAX_DHCP_PKG_SIZE); + + if (pReqData) { + PDHCP_PACKAGE p = (PDHCP_PACKAGE)pReqData; + + memset(pReqData, 0, MAX_DHCP_PKG_SIZE); + + // 目的地 MAC 地址 + memset(p->vlan_hdr.eth.h_dest, 0xFF, ETH_ALEN); + // 源 MAC 地址 + memcpy(p->vlan_hdr.eth.h_source, pInfo->mac, ETH_ALEN); + // 协议 VLAN + p->vlan_hdr.eth.h_proto = htons(ETH_P_8021Q); + + // VLAN 隧道信息 + p->vlan_hdr.vlan.id = htons(pInfo->vni); + p->vlan_hdr.vlan.type = htons(ETH_P_IP); + + // IP 头 + p->vlan_hdr.ip.version = IPVERSION; + p->vlan_hdr.ip.ihl = 5; + p->vlan_hdr.ip.tos = 0x10; + p->vlan_hdr.ip.tot_len = 0; + p->vlan_hdr.ip.id = 0; + p->vlan_hdr.ip.frag_off = 0; + p->vlan_hdr.ip.ttl = 128; + p->vlan_hdr.ip.protocol = IPPROTO_UDP; + p->vlan_hdr.ip.check = 0; + p->vlan_hdr.ip.saddr = INADDR_ANY; + p->vlan_hdr.ip.daddr = INADDR_BROADCAST; + + // UDP 头 + p->vlan_hdr.udp.source = htons(DHCP_CLI_PORT); + p->vlan_hdr.udp.dest = htons(DHCP_SVR_PORT); + p->vlan_hdr.udp.len = 0; + p->vlan_hdr.udp.check = 0; + + // DHCP 协议内容 + p->dhcp.op = BOOTP_REQUEST; + p->dhcp.htype = 0x01; + p->dhcp.hlen = ETH_ALEN; + p->dhcp.hops = 0; + p->dhcp.xid = htonl(rand_number()); + p->dhcp.secs = 0; + p->dhcp.flags = 0; + p->dhcp.ciaddr = INADDR_ANY; + p->dhcp.yiaddr = INADDR_ANY; + p->dhcp.siaddr = INADDR_ANY; + p->dhcp.giaddr = INADDR_ANY; + memcpy(p->dhcp.chaddr, pInfo->mac, ETH_ALEN); + p->dhcp.cookie = htonl(DHCP_COOKIE_VAL); + + // DHCP Options + pOpt = p->dhcp.options; + + // DHCP 消息类型 + pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_DISCOVER); + // DHCP 主机名 + pOpt += dhcp_add_string_option(pOpt, OPT_HOSTNAME, pInfo->hostname); + // DHCP 请求参数列表 + pOpt += dhcp_add_buf_option(pOpt, OPT_PARAMREQLIST, reqParams, 13); + // 结束 + *pOpt = OPT_END; + + // 计算包总长度 + tolSize = (int)((pOpt - p->dhcp.options) + 1 + sizeof(DHCP_PACKAGE)); + + // 计算 IP 数据长度 + p->vlan_hdr.ip.tot_len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr)); + // 计算 UDP 数据长度 + p->vlan_hdr.udp.len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr) - sizeof(struct iphdr)); + + // 计算 IP 校验和 + csum = htons(ip_checksum((unsigned char *)&p->vlan_hdr.ip)); + p->vlan_hdr.ip.check = htons(csum); + + // 计算 UDP 校验和 + csum = htons(udp_checksum(p->vlan_hdr.ip.saddr, p->vlan_hdr.ip.daddr, (unsigned char *)&p->vlan_hdr.udp)); + p->vlan_hdr.udp.check = htons(csum); + + *pOutSize = tolSize; + } + + return pReqData; +} + +static void on_dhcp_recv(uv_work_t *req) { + printf("+++++++++++++recv\n"); + //LOG_MOD_HEX(debug, ZLOG_MOD_MAIN, dhcp_create_discover_req(&info), 512); +} + +int dhcp_tools_init_network(const char *pNicName) { + static RECV_CB_DATA rcData; + static uv_poll_t uvSocket; + static uv_timer_t uvTm; + int ret; + + if (g_pNicName == NULL) { + g_pNicName = strdup(pNicName); + } else if (strcmp(pNicName, g_pNicName) != 0) { + dhcp_uninit(); + free(g_pNicName); + g_pNicName = strdup(pNicName); + } else { + return ERR_SUCCESS; + } + + init_filter("vlan and udp and port 67 and port 68"); + + ret = create_udp_raw_socket(g_pNicName); + if (ret != ERR_SUCCESS) { + LOG_MOD(error, ZLOG_MOD_DHCPD, "Create receive RAW Socket Error: %s(%d)\n", getErrorEnumNameString(-ret), ret); + return ret; + } + + dhcp_option_cfg_init(); + init_raw_socket_poll(on_dhcp_recv, NULL); + + return ERR_SUCCESS; +} \ No newline at end of file