OCT 1. dhcp 测试工具增加数据包发送功能

This commit is contained in:
huangxin 2023-04-20 17:20:30 +08:00
parent ff887e21e3
commit 2719023967
6 changed files with 758 additions and 88 deletions

View File

@ -7,7 +7,9 @@ PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0)
INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
LINK_DIRECTORIES(${GTK3_LIBRARY_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) FILE(GLOB PROJECT_HEADS ./*.h)
AUX_SOURCE_DIRECTORY(./ PROJECT_SRC) AUX_SOURCE_DIRECTORY(./ PROJECT_SRC)
@ -26,5 +28,7 @@ ADD_CUSTOM_COMMAND(TARGET ${PROJECT_TARGET}
POST_BUILD POST_BUILD
COMMENT "!!!!!! Notice: Automatic upgreade GTK3 UI files after build project." 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}/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/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/") COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/dhcp_tools/res/main.glade" "${CMAKE_CURRENT_BINARY_DIR}/res/")

62
dhcp_tools/main.h Normal file
View File

@ -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

View File

@ -2,18 +2,28 @@
// Created by xajhuang on 2023/4/12. // Created by xajhuang on 2023/4/12.
// //
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <zlog.h>
#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 { #define ZLOG_CFG_PATH "./config/zlog.conf"
COL_VNI = 0,
COL_MAC,
COL_HOSTNAME,
COL_STEP,
COL_RESULT,
COL_STATUS,
NUM_COLS
} COL_NAME;
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) { static void load_css(void) {
GtkCssProvider *provider; GtkCssProvider *provider;
@ -33,22 +43,68 @@ static void load_css(void) {
gtk_css_provider_load_from_file(provider, css_fp, &error); gtk_css_provider_load_from_file(provider, css_fp, &error);
} }
G_MODULE_EXPORT void __mainWnd_on_destroy(GObject *object, gpointer user_data) { static double calc_total_progress(PDHCP_INFO pInfo) {
gtk_main_quit(); double pre_cnt = 0.0;
if (pInfo) {
pre_cnt += pInfo->step * 20;
pre_cnt += pInfo->status * 5;
} }
static void add_item_to_list_view(GtkWidget *list, return pre_cnt;
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++) { for (i = 0; i < 1000; i++) {
char buf[24] = {0}; char buf[24] = {0};
char bufHost[32] = {0}; char bufHost[32] = {0};
@ -61,21 +117,21 @@ static void add_item_to_list_view(GtkWidget *list,
gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_append(store, &iter, NULL);
// clang-format off // clang-format off
gtk_tree_store_set(store, &iter, gtk_tree_store_set(store, &iter,
COL_VNI, bufVni, COL_INDEX, bufVni,
COL_MAC, buf, COL_MAC, buf,
COL_HOSTNAME, bufHost, COL_HOSTNAME, bufHost,
COL_STATUS, 20.0, COL_STATUS, 20.0,
-1); -1);
gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_append(store, &iter_child, &iter);
gtk_tree_store_set(store, &iter_child, gtk_tree_store_set(store, &iter_child,
COL_VNI, "", COL_INDEX, "",
COL_STEP, "Discover", COL_STEP, "Discover",
COL_RESULT, "", COL_RESULT, "",
COL_STATUS, 10.0, COL_STATUS, 10.0,
-1); -1);
gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_append(store, &iter_child, &iter);
gtk_tree_store_set(store, &iter_child, gtk_tree_store_set(store, &iter_child,
COL_VNI, "", COL_INDEX, "",
COL_STEP, "Offer", COL_STEP, "Offer",
COL_RESULT, "", COL_RESULT, "",
COL_STATUS, 10.0, COL_STATUS, 10.0,
@ -83,44 +139,273 @@ static void add_item_to_list_view(GtkWidget *list,
gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_append(store, &iter_child, &iter);
gtk_tree_store_set(store, &iter_child, gtk_tree_store_set(store, &iter_child,
COL_VNI, "", COL_INDEX, "",
COL_STEP, "Request", COL_STEP, "Request",
COL_RESULT, "", COL_RESULT, "",
COL_STATUS, 10.0, COL_STATUS, 10.0,
-1); -1);
gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_append(store, &iter_child, &iter);
gtk_tree_store_set(store, &iter_child, gtk_tree_store_set(store, &iter_child,
COL_VNI, "", COL_INDEX, "",
COL_STEP, "ACK", COL_STEP, "ACK",
COL_RESULT, "", COL_RESULT, "",
COL_STATUS, 10.0, COL_STATUS, 10.0,
-1); -1);
// clang-format on // clang-format on
} }
#endif
//g_object_unref(store);
} }
int main(int argc, char **argv) { static gboolean tree_view_data_store_upgade(gpointer pInfo) {
gtk_init(&argc, &argv); 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
}
}
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(); load_css();
g_main_builder = gtk_builder_new(); g_mainBuilder = gtk_builder_new();
gtk_builder_add_from_file(g_main_builder, "./res/main.glade", NULL); 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")); GtkWidget *tbStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart"));
//gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(macTxt)), "txtMacStart"); 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); GtkAdjustment *adj = gtk_adjustment_new(1000, 1, 100000, 1, 0, 0);
gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numInc), adj); 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); GtkAdjustment *adjVni = gtk_adjustment_new(1, 1, 10000000, 1, 0, 0);
gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVni), adjVni); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVni), adjVni);
#if 1
GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_main_builder, "treeResult")); GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult"));
GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_main_builder, "tsDhcpInfo"));
#if 0 #if 0
gtk_list_store_new(NUM_COLS, gtk_list_store_new(NUM_COLS,
G_TYPE_INT, G_TYPE_INT,
@ -132,17 +417,13 @@ int main(int argc, char **argv) {
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_FLOAT); G_TYPE_FLOAT);
#endif #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); gtk_builder_connect_signals(g_mainBuilder, NULL);
g_object_unref(store); //g_object_unref(G_OBJECT(g_mainBuilder));
#endif
gtk_builder_connect_signals(g_main_builder, NULL);
//g_object_unref(G_OBJECT(g_main_builder));
gtk_widget_show(mainWnd); 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(); gtk_main();
return 0; return 0;

View File

@ -2,25 +2,36 @@
<interface> <interface>
<requires lib="gtk+" version="2.16"/> <requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide --> <!-- interface-naming-policy project-wide -->
<object class="GtkTreeStore" id="tsDhcpInfo"> <object class="GtkListStore" id="tsDhcpInfo">
<columns> <columns>
<!-- column-name cVni --> <!-- column-name cIndex -->
<column type="gchararray"/> <column type="guint"/>
<!-- column-name cMac --> <!-- column-name cMac -->
<column type="gchararray"/> <column type="gchararray"/>
<!-- column-name cHostname --> <!-- column-name cHostname -->
<column type="gchararray"/> <column type="gchararray"/>
<!-- column-name cStep --> <!-- column-name cDiscover -->
<column type="gchararray"/> <column type="gfloat"/>
<!-- column-name cOffer -->
<column type="gfloat"/>
<!-- column-name cRequest -->
<column type="gfloat"/>
<!-- column-name cAck -->
<column type="gfloat"/>
<!-- column-name cResult --> <!-- column-name cResult -->
<column type="gchararray"/> <column type="gchararray"/>
<!-- column-name cRltPrgess --> <!-- column-name cRltPrgess -->
<column type="gfloat"/> <column type="gfloat"/>
</columns> </columns>
</object> </object>
<object class="GtkListStore" id="lsNicName">
<columns>
<!-- column-name cNicName -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="wndMain"> <object class="GtkWindow" id="wndMain">
<property name="width_request">1024</property> <property name="width_request">1024</property>
<signal name="destroy" handler="__mainWnd_on_destroy"/>
<child> <child>
<object class="GtkVBox" id="vbWnd"> <object class="GtkVBox" id="vbWnd">
<property name="visible">True</property> <property name="visible">True</property>
@ -169,6 +180,7 @@
<child> <child>
<object class="GtkToolButton" id="tbStart"> <object class="GtkToolButton" id="tbStart">
<property name="visible">True</property> <property name="visible">True</property>
<property name="is_important">True</property>
<property name="label" translatable="yes">Start</property> <property name="label" translatable="yes">Start</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="stock_id">gtk-media-play</property> <property name="stock_id">gtk-media-play</property>
@ -181,8 +193,9 @@
<child> <child>
<object class="GtkToolButton" id="tbStop"> <object class="GtkToolButton" id="tbStop">
<property name="visible">True</property> <property name="visible">True</property>
<property name="sensitive">False</property>
<property name="is_important">True</property>
<property name="label" translatable="yes">Stop</property> <property name="label" translatable="yes">Stop</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-media-stop</property> <property name="stock_id">gtk-media-stop</property>
</object> </object>
<packing> <packing>
@ -210,7 +223,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="border_width">5</property> <property name="border_width">5</property>
<property name="n_rows">2</property> <property name="n_rows">2</property>
<property name="n_columns">4</property> <property name="n_columns">6</property>
<property name="column_spacing">5</property> <property name="column_spacing">5</property>
<property name="row_spacing">5</property> <property name="row_spacing">5</property>
<child> <child>
@ -268,10 +281,11 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkEntry" id="entry2"> <object class="GtkEntry" id="txtHostname">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property> <property name="invisible_char">&#x25CF;</property>
<property name="text" translatable="yes">hostname</property>
</object> </object>
<packing> <packing>
<property name="left_attach">3</property> <property name="left_attach">3</property>
@ -304,6 +318,40 @@
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&#x7F51;&#x5361;&#xFF1A;</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="right_attach">5</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="cbNicName">
<property name="width_request">64</property>
<property name="visible">True</property>
<property name="model">lsNicName</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext5"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">5</property>
<property name="right_attach">6</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object> </object>
</child> </child>
<child type="label"> <child type="label">
@ -341,7 +389,8 @@
<property name="enable_grid_lines">both</property> <property name="enable_grid_lines">both</property>
<child> <child>
<object class="GtkTreeViewColumn" id="tvcIndex"> <object class="GtkTreeViewColumn" id="tvcIndex">
<property name="title">VNI</property> <property name="min_width">32</property>
<property name="title">Index</property>
<property name="alignment">0.5</property> <property name="alignment">0.5</property>
<child> <child>
<object class="GtkCellRendererText" id="cellrenderertext1"/> <object class="GtkCellRendererText" id="cellrenderertext1"/>
@ -353,6 +402,7 @@
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="tvcMac"> <object class="GtkTreeViewColumn" id="tvcMac">
<property name="min_width">128</property>
<property name="title">MAC</property> <property name="title">MAC</property>
<property name="alignment">0.5</property> <property name="alignment">0.5</property>
<child> <child>
@ -365,6 +415,7 @@
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="tvcHostname"> <object class="GtkTreeViewColumn" id="tvcHostname">
<property name="min_width">64</property>
<property name="title">Hostname</property> <property name="title">Hostname</property>
<property name="alignment">0.5</property> <property name="alignment">0.5</property>
<child> <child>
@ -376,38 +427,89 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="tvcStep"> <object class="GtkTreeViewColumn" id="tvcDiscover">
<property name="sizing">autosize</property> <property name="sizing">autosize</property>
<property name="title">Step</property> <property name="fixed_width">64</property>
<property name="min_width">96</property>
<property name="title">Discover</property>
<property name="alignment">0.5</property> <property name="alignment">0.5</property>
<child> <child>
<object class="GtkCellRendererText" id="cellrenderertext4"/> <object class="GtkCellRendererProgress" id="crDiscover"/>
<attributes> <attributes>
<attribute name="text">3</attribute> <attribute name="value">3</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="tvcOffer">
<property name="sizing">autosize</property>
<property name="fixed_width">64</property>
<property name="min_width">96</property>
<property name="title">Offer</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererProgress" id="crOffer"/>
<attributes>
<attribute name="value">4</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="tvcRequest">
<property name="sizing">autosize</property>
<property name="min_width">96</property>
<property name="title">Request</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererProgress" id="crRequest"/>
<attributes>
<attribute name="value">5</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="tvcAck">
<property name="sizing">autosize</property>
<property name="min_width">96</property>
<property name="title">ACK</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererProgress" id="crAck"/>
<attributes>
<attribute name="value">6</attribute>
</attributes> </attributes>
</child> </child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="tvcResult"> <object class="GtkTreeViewColumn" id="tvcResult">
<property name="sizing">fixed</property>
<property name="min_width">200</property>
<property name="title">Result</property> <property name="title">Result</property>
<property name="alignment">0.5</property> <property name="alignment">0.5</property>
<child> <child>
<object class="GtkCellRendererText" id="crResult"/> <object class="GtkCellRendererText" id="crResult"/>
<attributes> <attributes>
<attribute name="text">4</attribute> <attribute name="text">7</attribute>
</attributes> </attributes>
</child> </child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkTreeViewColumn" id="tblStatus"> <object class="GtkTreeViewColumn" id="tblStatus">
<property name="title">Staus</property> <property name="sizing">fixed</property>
<property name="fixed_width">64</property>
<property name="min_width">64</property>
<property name="max_width">64</property>
<property name="title">Totol Progress</property>
<property name="alignment">0.5</property> <property name="alignment">0.5</property>
<child> <child>
<object class="GtkCellRendererProgress" id="cellrendererprogress1"/> <object class="GtkCellRendererProgress" id="cellrendererprogress1"/>
<attributes> <attributes>
<attribute name="value">5</attribute> <attribute name="value">8</attribute>
</attributes> </attributes>
</child> </child>
</object> </object>

View File

@ -8,7 +8,7 @@ spinbutton {
} }
.view { .view {
font: 16px "Comic Sans"; font: 14px "Comic Sans";
} }
entry { entry {

221
dhcp_tools/uv_rawsocket.c Normal file
View File

@ -0,0 +1,221 @@
//
// Created by xajhuang on 2023/4/20.
//
#include <uv.h>
#include <linux/filter.h>
#include <string.h>
#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;
}