OCT 1. 修正DHCP Tools切换数据包窗口时异常问题

2. DHCP Tools 数据包窗口Tab切换时自动更新页面
3. 增加数据包超时重传
4. 增加数据包发送、接收时间戳
This commit is contained in:
黄昕 2023-05-05 15:25:25 +08:00
parent d91e80acb3
commit 99e1ec5cf9
6 changed files with 199 additions and 123 deletions

View File

@ -3,6 +3,7 @@
// //
#include <ctype.h> #include <ctype.h>
#include "main.h" #include "main.h"
#include "misc.h"
#include "zlog_module.h" #include "zlog_module.h"
#include "dhcp_network.h" #include "dhcp_network.h"
#include "sds/sds.h" #include "sds/sds.h"
@ -92,6 +93,9 @@ static gboolean delete_event(GtkWidget *widget, GdkEventAny *event) {
} }
static void add_dhcp_tree_colums(GtkWidget *treeView) { static void add_dhcp_tree_colums(GtkWidget *treeView) {
GList *cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(treeView));
if (g_list_length(cols) == 0) {
GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("协议", renderer, "text", 0, NULL); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("协议", renderer, "text", 0, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), column); gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), column);
@ -100,6 +104,7 @@ static void add_dhcp_tree_colums(GtkWidget *treeView) {
column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 1, NULL); column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 1, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), column); gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), column);
} }
}
#define ADD_SUB_STRING(name, s) \ #define ADD_SUB_STRING(name, s) \
do { \ do { \
@ -118,8 +123,8 @@ static void add_dhcp_tree_colums(GtkWidget *treeView) {
#define ADD_SUB_OPTION(code, len, val) \ #define ADD_SUB_OPTION(code, len, val) \
do { \ do { \
U8 *pVal; \
int count_flag = 0; \ int count_flag = 0; \
char *p; \
gtk_tree_store_append(store, &iterOpt, &iterSub); \ gtk_tree_store_append(store, &iterOpt, &iterSub); \
s = sdsempty(); \ s = sdsempty(); \
sprintf(s, "%u", (len)); \ sprintf(s, "%u", (len)); \
@ -132,20 +137,26 @@ static void add_dhcp_tree_colums(GtkWidget *treeView) {
gtk_tree_store_set(store, &iterOpt, 0, dhcp_get_opName(code), 1, (val), -1); \ gtk_tree_store_set(store, &iterOpt, 0, dhcp_get_opName(code), 1, (val), -1); \
break; \ break; \
case 2: \ case 2: \
pVal = val; \
do { \ do { \
sds sv = sdsempty(); \
gtk_tree_store_append(store, &iterOpt, &iterSub); \ gtk_tree_store_append(store, &iterOpt, &iterSub); \
s = sdsempty(); \ s = sdsempty(); \
sprintf(s, "(%u) %s", (val)[count_flag], dhcp_get_opName((val)[count_flag]));\ sprintf(s, "%s", dhcp_get_opName(*pVal)); \
gtk_tree_store_set(store, &iterOpt, 0, dhcp_get_opName(code), 1, s, -1);\ sprintf(sv, "Request (%03d)", *pVal); \
gtk_tree_store_set(store, &iterOpt, 0, sv, 1, s, -1); \
sdsfree(s); \ sdsfree(s); \
sdsfree(sv); \
count_flag++; \ count_flag++; \
pVal++; \
} while (count_flag != (len)); \ } while (count_flag != (len)); \
break; \ break; \
case 3: \ case 3: \
do { \ do { \
U32 *pIp = (U32 *)(val); \
gtk_tree_store_append(store, &iterOpt, &iterSub); \ gtk_tree_store_append(store, &iterOpt, &iterSub); \
s = sdsempty(); \ s = sdsempty(); \
sprintf(s, "%u.%u.%u.%u", (val)[count_flag], (val)[count_flag+1], (val)[count_flag+2], (val)[count_flag+3]);\ sprintf(s, "%s", u32_to_str_ip(*pIp)); \
gtk_tree_store_set(store, &iterOpt, 0, dhcp_get_opName(code), 1, s, -1); \ gtk_tree_store_set(store, &iterOpt, 0, dhcp_get_opName(code), 1, s, -1); \
sdsfree(s); \ sdsfree(s); \
count_flag += 4; \ count_flag += 4; \
@ -174,18 +185,29 @@ static void add_dhcp_tree_colums(GtkWidget *treeView) {
} \ } \
} while (0) } while (0)
static void create_dhcp_tree_mode(PDHCP_PACKAGE p, GtkWidget *treeView) { static void create_dhcp_tree_mode(PDHCP_PACKAGE p, U32 nBytes, GtkWidget *treeView) {
// 填充右上侧 TreeView 协议数据 // 填充右上侧 TreeView 协议数据
sds s; sds s;
GtkTreeIter iter, iterSub, iterOpt; GtkTreeIter iter, iterSub, iterOpt;
GtkTreeStore *store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING); GtkTreeStore *store = NULL; //gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
const char *itemTitle[] = {"Ethernet II", "802.1Q Virtual LAN", "IP Version 4", "UDP", "DHCP"}; const char *itemTitle[] = {"Ethernet II", "802.1Q Virtual LAN", "IP Version 4", "UDP", "DHCP"};
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
//GtkTreeStore *store = GTK_TREE_STORE();
if (model) {
store = GTK_TREE_STORE(model);
if (gtk_tree_model_get_iter_first(model, &iter)) {
gtk_tree_store_clear(store);
}
} else {
store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(store));
}
gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store, &iter, 0, itemTitle[0], 1, "", -1); gtk_tree_store_set(store, &iter, 0, itemTitle[0], 1, "", -1);
// 添加 Ethernet II 头相关内容 // 添加 Ethernet II 头相关内容
s = sdsempty(); s = sdsempty();
MAC_TO_STR(p->hdr.eth.h_dest, s); MAC_TO_STR(p->hdr.eth.h_dest, s);
ADD_SUB_STRING("Destination", s); ADD_SUB_STRING("Destination", s);
@ -266,22 +288,29 @@ static void create_dhcp_tree_mode(PDHCP_PACKAGE p, GtkWidget *treeView) {
ADD_SUB_STRING("Destination", s); ADD_SUB_STRING("Destination", s);
sdsfree(s); sdsfree(s);
if(strlen(p->dhcp.sname) != 0) if (strlen((char *)p->dhcp.sname) != 0) {
ADD_SUB_STRING("Server host name", p->dhcp.sname); ADD_SUB_STRING("Server host name", p->dhcp.sname);
else } else {
ADD_SUB_STRING("Server host name", "not given"); ADD_SUB_STRING("Server host name", "not given");
}
if(strlen(p->dhcp.file) != 0) if (strlen((char *)p->dhcp.file) != 0) {
ADD_SUB_STRING("Boot file name", p->dhcp.file); ADD_SUB_STRING("Boot file name", p->dhcp.file);
else } else {
ADD_SUB_STRING("Boot file name", "not given"); ADD_SUB_STRING("Boot file name", "not given");
}
ADD_SUB_STRING("Magic cookie", "DHCP"); ADD_SUB_STRING("Magic cookie", "DHCP");
U8 *opPointer; U8 *opPointer, *optEnd = (U8 *)p + nBytes;
opPointer = p->dhcp.options; opPointer = p->dhcp.options;
while (*opPointer && *opPointer != OPT_END) { while (*opPointer && opPointer < optEnd) {
if (*opPointer == OPT_END) {
ADD_SUB_STRING("Option(255)", "End");
opPointer++;
} else {
STR_OPT opTmp; STR_OPT opTmp;
sds st = sdsempty();
opTmp.op_code = *opPointer; opTmp.op_code = *opPointer;
opPointer++; opPointer++;
opTmp.op_size = *opPointer; opTmp.op_size = *opPointer;
@ -290,34 +319,44 @@ static void create_dhcp_tree_mode(PDHCP_PACKAGE p, GtkWidget *treeView) {
opPointer += opTmp.op_size; opPointer += opTmp.op_size;
s = sdsempty(); s = sdsempty();
sprintf(s, "(%u) %s", opTmp.op_code, dhcp_get_opName(opTmp.op_code)); //sprintf(s, "(%u) %s", opTmp.op_code, dhcp_get_opName(opTmp.op_code));
ADD_SUB_STRING("Option", s); sprintf(st, "Option(%u)", opTmp.op_code);
ADD_SUB_STRING(st, dhcp_get_opName(opTmp.op_code));
sdsfree(s); sdsfree(s);
sdsfree(st);
ADD_SUB_OPTION(opTmp.op_code, opTmp.op_size, opTmp.op_value); ADD_SUB_OPTION(opTmp.op_code, opTmp.op_size, opTmp.op_value);
} }
}
if(*opPointer == OPT_END) {
ADD_SUB_STRING("Option", "(255) End");
} }
gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(store)); static PDHCP_INFO g_preInfo = NULL;
g_object_unref(GTK_TREE_MODEL(store));
}
void details_wnd_show(PDHCP_INFO pInfo) { void details_wnd_show(PDHCP_INFO pInfo) {
int i;
PBUF_INFO hexBuf[4]; PBUF_INFO hexBuf[4];
GtkTextIter iter, iter1;
if (pInfo) { if (pInfo) {
if (pInfo != g_preInfo) {
g_preInfo = pInfo;
for (i = 0; i < 4; i++) {
gtk_text_buffer_get_start_iter(g_pTxtBuf[i], &iter);
gtk_text_buffer_get_end_iter(g_pTxtBuf[i], &iter1);
gtk_text_buffer_delete(g_pTxtBuf[i], &iter, &iter1);
}
}
hexBuf[0] = &pInfo->pDiscBuf; hexBuf[0] = &pInfo->pDiscBuf;
hexBuf[1] = &pInfo->pOfferBuf; hexBuf[1] = &pInfo->pOfferBuf;
hexBuf[2] = &pInfo->pReqBuf; hexBuf[2] = &pInfo->pReqBuf;
hexBuf[3] = &pInfo->pAckBuf; hexBuf[3] = &pInfo->pAckBuf;
// 填充HEX 窗口数据 // 填充HEX 窗口数据
for (int i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
char buf[128] = {0}; char buf[128] = {0};
U32 offset = 0; U32 offset = 0;
GtkTextIter iter, iter1;
if (hexBuf[i]->buf_size == 0) { if (hexBuf[i]->buf_size == 0) {
continue; continue;
@ -367,7 +406,7 @@ void details_wnd_show(PDHCP_INFO pInfo) {
// 填充 TreeView // 填充 TreeView
add_dhcp_tree_colums(g_ptvDHcp[i]); add_dhcp_tree_colums(g_ptvDHcp[i]);
create_dhcp_tree_mode((PDHCP_PACKAGE)hexBuf[i]->p, g_ptvDHcp[i]); create_dhcp_tree_mode((PDHCP_PACKAGE)hexBuf[i]->p, hexBuf[i]->buf_size, g_ptvDHcp[i]);
} }
} }
@ -394,6 +433,15 @@ static gboolean button_release_event(GtkWidget *self, GdkEventButton event, gpoi
return FALSE; return FALSE;
} }
void switch_page(GtkNotebook *UNUSED(self),
GtkWidget *UNUSED(page),
guint UNUSED(page_num),
gpointer UNUSED(user_data)) {
if (g_preInfo) {
details_wnd_show(g_preInfo);
}
}
void details_wnd_create(GtkBuilder *builder) { void details_wnd_create(GtkBuilder *builder) {
// 创建主窗口 // 创建主窗口
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@ -407,6 +455,7 @@ void details_wnd_create(GtkBuilder *builder) {
// 页标签的位置,可以有四种位置:上、下、左或右。 // 页标签的位置,可以有四种位置:上、下、左或右。
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
g_signal_connect(notebook, "switch-page", G_CALLBACK(switch_page), NULL);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
GtkTreeIter iter; GtkTreeIter iter;

View File

@ -53,7 +53,8 @@ typedef enum {
typedef struct { typedef struct {
U8 *p; U8 *p;
int buf_size; int buf_size;
unsigned int tm; struct timeval tm;
U32 snd;
} BUF_INFO, *PBUF_INFO; } BUF_INFO, *PBUF_INFO;
typedef struct { typedef struct {

View File

@ -2,6 +2,7 @@
// Created by xajhuang on 2023/4/12. // Created by xajhuang on 2023/4/12.
// //
#include <zlog.h> #include <zlog.h>
#include <sys/time.h>
#include "main.h" #include "main.h"
#include "misc.h" #include "misc.h"
#include "task_manager.h" #include "task_manager.h"
@ -9,6 +10,8 @@
#include "zlog_module.h" #include "zlog_module.h"
#include "dhcp_network.h" #include "dhcp_network.h"
#define DHCP_STEP_TIMEOUT (30)
#define MAIN_WND_WIDTH (1024) #define MAIN_WND_WIDTH (1024)
#define MAIN_WND_HEIGHT (768) #define MAIN_WND_HEIGHT (768)
@ -345,6 +348,7 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) {
U8 *pkg; U8 *pkg;
int size = 0; int size = 0;
PDHCP_INFO pInfo, pTemp; PDHCP_INFO pInfo, pTemp;
struct timeval now;
while (TRUE) { while (TRUE) {
if (!g_runTask) { if (!g_runTask) {
@ -361,7 +365,6 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) {
pInfo->pDiscBuf.buf_size = size; pInfo->pDiscBuf.buf_size = size;
pInfo->step = STEP_DISCOVER; pInfo->step = STEP_DISCOVER;
pInfo->status = STA_WAIT_START; pInfo->status = STA_WAIT_START;
pInfo->pDiscBuf.tm = time(NULL);
g_idle_add(tree_view_data_store_upgade, pInfo); g_idle_add(tree_view_data_store_upgade, pInfo);
} }
break; break;
@ -374,9 +377,19 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) {
if (pkg_mmap_tx((U8 *)pkg, pInfo->pDiscBuf.buf_size) == pInfo->pDiscBuf.buf_size) { if (pkg_mmap_tx((U8 *)pkg, pInfo->pDiscBuf.buf_size) == pInfo->pDiscBuf.buf_size) {
pInfo->status = STA_SEND_REQ; pInfo->status = STA_SEND_REQ;
gettimeofday(&pInfo->pDiscBuf.tm, NULL);
pInfo->pDiscBuf.snd += 1;
g_idle_add(tree_view_data_store_upgade, pInfo); g_idle_add(tree_view_data_store_upgade, pInfo);
} }
} }
} else if (pInfo->status == STA_SEND_REQ) {
// 处理超时
gettimeofday(&now, NULL);
if (now.tv_sec - pInfo->pDiscBuf.tm.tv_sec > DHCP_STEP_TIMEOUT) {
// 超时重传
pInfo->status = STA_WAIT_START;
}
} }
break; break;
case STEP_OFFER: case STEP_OFFER:
@ -387,7 +400,6 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) {
pInfo->pReqBuf.buf_size = size; pInfo->pReqBuf.buf_size = size;
pInfo->step = STEP_REQUEST; pInfo->step = STEP_REQUEST;
pInfo->status = STA_WAIT_START; pInfo->status = STA_WAIT_START;
pInfo->pReqBuf.tm = time(NULL);
g_idle_add(tree_view_data_store_upgade, pInfo); g_idle_add(tree_view_data_store_upgade, pInfo);
} }
} }
@ -401,9 +413,19 @@ _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) {
if (pkg_mmap_tx((U8 *)pkg, pInfo->pReqBuf.buf_size) == pInfo->pReqBuf.buf_size) { if (pkg_mmap_tx((U8 *)pkg, pInfo->pReqBuf.buf_size) == pInfo->pReqBuf.buf_size) {
pInfo->status = STA_SEND_REQ; pInfo->status = STA_SEND_REQ;
gettimeofday(&pInfo->pReqBuf.tm, NULL);
pInfo->pReqBuf.snd = 1;
g_idle_add(tree_view_data_store_upgade, pInfo); g_idle_add(tree_view_data_store_upgade, pInfo);
} }
} }
} else if (pInfo->status == STA_SEND_REQ) {
// 处理超时
gettimeofday(&now, NULL);
if (now.tv_sec - pInfo->pReqBuf.tm.tv_sec > DHCP_STEP_TIMEOUT) {
// 超时重传
pInfo->status = STA_WAIT_START;
}
} }
break; break;
case STEP_ACK: case STEP_ACK:

View File

@ -3,6 +3,7 @@
// //
#include <uv.h> #include <uv.h>
#include <string.h> #include <string.h>
#include <sys/time.h>
#include "user_errno.h" #include "user_errno.h"
#include "dhcp_network.h" #include "dhcp_network.h"
#include "dhcp_options.h" #include "dhcp_options.h"
@ -236,7 +237,8 @@ static void on_dhcp_recv(uv_work_t *req) {
cacheDhcpOfferBuffer(pInfo, pWork->pPkgBase, pWork->nSize); cacheDhcpOfferBuffer(pInfo, pWork->pPkgBase, pWork->nSize);
memcpy(&pInfo->offerRsp, &rspDhcp, sizeof(DHCP_RSP)); memcpy(&pInfo->offerRsp, &rspDhcp, sizeof(DHCP_RSP));
pInfo->pOfferBuf.tm = time(NULL);
gettimeofday(&pInfo->pOfferBuf.tm, NULL);
break; break;
case DHCP_MSG_ACK: case DHCP_MSG_ACK:
pInfo->step = STEP_ACK; pInfo->step = STEP_ACK;
@ -244,7 +246,7 @@ static void on_dhcp_recv(uv_work_t *req) {
cacheDhcpAckBuffer(pInfo, pWork->pPkgBase, pWork->nSize); cacheDhcpAckBuffer(pInfo, pWork->pPkgBase, pWork->nSize);
memcpy(&pInfo->ackRsp, &rspDhcp, sizeof(DHCP_RSP)); memcpy(&pInfo->ackRsp, &rspDhcp, sizeof(DHCP_RSP));
pInfo->pAckBuf.tm = time(NULL); gettimeofday(&pInfo->pAckBuf.tm, NULL);
break; break;
case DHCP_MSG_NAK: case DHCP_MSG_NAK:
break; break;

View File

@ -208,7 +208,7 @@ const char* dhcp_get_opName(int opt) {
return g_opCfg[i].opName; return g_opCfg[i].opName;
} }
return NULL; return "Unknown";
} }
int dhcp_get_opType(int opt) { int dhcp_get_opType(int opt) {

View File

@ -4,6 +4,7 @@
#include <time.h> #include <time.h>
#include "lease.h" #include "lease.h"
#include "misc.h"
#include "user_errno.h" #include "user_errno.h"
#include "zlog_module.h" #include "zlog_module.h"
#include "dhcp_network.h" #include "dhcp_network.h"
@ -33,6 +34,7 @@ int usr_lease_lock_ip(PDHCP_USER pUser, U32 ip) {
memset(pLock, 0, sizeof(LOCK_IP)); memset(pLock, 0, sizeof(LOCK_IP));
pLock->ip = ip; pLock->ip = ip;
HASH_ADD_INT(pUser->plockIp, ip, pLock); HASH_ADD_INT(pUser->plockIp, ip, pLock);
LOG_MOD(trace, ZM_DHCP_LEASE, "User %u lock ip %s\n", pUser->uid, u32_to_str_ip(ip));
return ERR_SUCCESS; return ERR_SUCCESS;
} }