OCT 1. DHCP 测试工具支持双层VLAN
This commit is contained in:
parent
a356a7f9ef
commit
e6ea44dd19
|
@ -3,6 +3,7 @@ SET(PROJECT_TARGET dhcp_tools)
|
|||
PROJECT(${PROJECT_TARGET} LANGUAGES C)
|
||||
|
||||
FIND_PACKAGE(PkgConfig REQUIRED)
|
||||
# sudo apt install libgtk-3-dev
|
||||
PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0)
|
||||
INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS})
|
||||
|
|
|
@ -97,10 +97,10 @@ static void add_dhcp_tree_colums(GtkWidget *treeView) {
|
|||
break; \
|
||||
case 3: \
|
||||
do { \
|
||||
U32 *pIp = (U32 *)(val); \
|
||||
U32 *pIps = (U32 *)(val); \
|
||||
gtk_tree_store_append(store, &iterOpt, &iterSub); \
|
||||
s = sdsempty(); \
|
||||
sprintf(s, "%s", u32_to_str_ip(*pIp)); \
|
||||
sprintf(s, "%s", u32_to_str_ip(*pIps)); \
|
||||
gtk_tree_store_set(store, &iterOpt, 0, dhcp_get_opName(code), 1, s, -1); \
|
||||
sdsfree(s); \
|
||||
count_flag += 4; \
|
||||
|
@ -129,14 +129,19 @@ static void add_dhcp_tree_colums(GtkWidget *treeView) {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
static void create_dhcp_tree_mode(PDHCP_PACKAGE p, U32 nBytes, GtkWidget *treeView) {
|
||||
static void create_dhcp_tree_mode(U8 *pkg, U32 nBytes, GtkWidget *treeView) {
|
||||
PVLAN_HDR pvLan;
|
||||
PVLAN_HDR2 pvLan2;
|
||||
// 填充右上侧 TreeView 协议数据
|
||||
sds s;
|
||||
GtkTreeIter iter, iterSub, iterOpt;
|
||||
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"};
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
|
||||
//GtkTreeStore *store = GTK_TREE_STORE();
|
||||
struct ethhdr *pEth = (struct ethhdr *)pkg;
|
||||
struct iphdr *pIp = NULL;
|
||||
struct udphdr *pUdp = NULL;
|
||||
PDHCP_PROTO pDhcp = NULL;
|
||||
|
||||
if (model) {
|
||||
store = GTK_TREE_STORE(model);
|
||||
|
@ -153,55 +158,78 @@ static void create_dhcp_tree_mode(PDHCP_PACKAGE p, U32 nBytes, GtkWidget *treeVi
|
|||
|
||||
// 添加 Ethernet II 头相关内容
|
||||
s = sdsempty();
|
||||
MAC_TO_STR(p->hdr.eth.h_dest, s);
|
||||
MAC_TO_STR(pEth->h_dest, s);
|
||||
ADD_SUB_STRING("Destination", s);
|
||||
sdsfree(s);
|
||||
|
||||
s = sdsempty();
|
||||
MAC_TO_STR(p->hdr.eth.h_source, s);
|
||||
MAC_TO_STR(pEth->h_source, s);
|
||||
ADD_SUB_STRING("Source", s);
|
||||
sdsfree(s);
|
||||
|
||||
#if VLAN_SUPPORT
|
||||
switch (get_package_vlan_type(pkg)) {
|
||||
default:
|
||||
pIp = (struct iphdr *)(pkg + IP_HDR_OFFSET);
|
||||
pUdp = (struct udphdr *)(UDP_HDR_OFFSET);
|
||||
pDhcp = (PDHCP_PROTO)((U8 *)pkg + DHCP_OFFSET);
|
||||
break;
|
||||
case VLAN_LEVEL1:
|
||||
pvLan = (PVLAN_HDR)(pkg + sizeof(struct ethhdr));
|
||||
pIp = (struct iphdr *)(pkg + IP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||
pUdp = (struct udphdr *)(pkg + UDP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||
pDhcp = (PDHCP_PROTO)((U8 *)pkg + DHCP_OFFSET + sizeof(VLAN_HDR));
|
||||
// 添加 VLan 头相关内容
|
||||
gtk_tree_store_append(store, &iter, NULL);
|
||||
gtk_tree_store_set(store, &iter, 0, itemTitle[1], 1, "", -1);
|
||||
ADD_SUB_INT("ID", "%u", VLAN_VNI_ID(p->hdr.vlan.id));
|
||||
ADD_SUB_INT("Type", "0x%04X", ntohs(p->hdr.vlan.type));
|
||||
#endif
|
||||
ADD_SUB_INT("ID", "%u", VLAN_VNI_ID(pvLan->id));
|
||||
ADD_SUB_INT("Type", "0x%04X", ntohs(pvLan->type));
|
||||
break;
|
||||
case VLAN_LEVEL2:
|
||||
pvLan2 = (PVLAN_HDR2)(pkg + sizeof(struct ethhdr));
|
||||
pIp = (struct iphdr *)(pkg + IP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||
pUdp = (struct udphdr *)(pkg + UDP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||
pDhcp = (PDHCP_PROTO)((U8 *)pkg + DHCP_OFFSET + sizeof(VLAN_HDR2));
|
||||
gtk_tree_store_append(store, &iter, NULL);
|
||||
gtk_tree_store_set(store, &iter, 0, itemTitle[1], 1, "", -1);
|
||||
ADD_SUB_INT("ID Low", "%u", VLAN_VNI_ID(pvLan2->id1));
|
||||
ADD_SUB_INT("Type", "0x%04X", ntohs(pvLan2->h_type));
|
||||
ADD_SUB_INT("ID Hight", "%u", VLAN_VNI_ID(pvLan2->id2));
|
||||
ADD_SUB_INT("Type", "0x%04X", ntohs(pvLan2->type));
|
||||
break;
|
||||
}
|
||||
|
||||
// 添加 IP 头
|
||||
gtk_tree_store_append(store, &iter, NULL);
|
||||
gtk_tree_store_set(store, &iter, 0, itemTitle[2], 1, "", -1);
|
||||
ADD_SUB_INT("Version", "%u", p->hdr.ip.version);
|
||||
ADD_SUB_INT("Version", "%u", pIp->version);
|
||||
|
||||
s = sdsempty();
|
||||
sprintf(s, "%u %s (%u)", p->hdr.ip.ihl * 4, "bytes", p->hdr.ip.ihl);
|
||||
sprintf(s, "%u %s (%u)", pIp->ihl * 4, "bytes", pIp->ihl);
|
||||
ADD_SUB_STRING("Header Length", s);
|
||||
sdsfree(s);
|
||||
|
||||
ADD_SUB_INT("Differentiated Services Field", "0x%02X", p->hdr.ip.tos);
|
||||
ADD_SUB_INT("Total Length", "%u", ntohs(p->hdr.ip.tot_len));
|
||||
ADD_SUB_INT("Identification", "0x%04X", ntohs(p->hdr.ip.id));
|
||||
ADD_SUB_INT("Flags", "0x%04X", ntohs(p->hdr.ip.frag_off));
|
||||
ADD_SUB_INT("Time to live", "%u", p->hdr.ip.ttl);
|
||||
ADD_SUB_INT("Differentiated Services Field", "0x%02X", pIp->tos);
|
||||
ADD_SUB_INT("Total Length", "%u", ntohs(pIp->tot_len));
|
||||
ADD_SUB_INT("Identification", "0x%04X", ntohs(pIp->id));
|
||||
ADD_SUB_INT("Flags", "0x%04X", ntohs(pIp->frag_off));
|
||||
ADD_SUB_INT("Time to live", "%u", pIp->ttl);
|
||||
ADD_SUB_STRING("Protocol", "UDP");
|
||||
ADD_SUB_INT("Header Checksum", "0x%04X", ntohs(p->hdr.ip.check));
|
||||
ADD_SUB_STRING("Source", inet_ntoa(*(struct in_addr *)&p->hdr.ip.saddr));
|
||||
ADD_SUB_STRING("Destination", inet_ntoa(*(struct in_addr *)&p->hdr.ip.daddr));
|
||||
ADD_SUB_INT("Header Checksum", "0x%04X", ntohs(pIp->check));
|
||||
ADD_SUB_STRING("Source", inet_ntoa(*(struct in_addr *)&pIp->saddr));
|
||||
ADD_SUB_STRING("Destination", inet_ntoa(*(struct in_addr *)&pIp->daddr));
|
||||
|
||||
// 添加 UDP 头
|
||||
gtk_tree_store_append(store, &iter, NULL);
|
||||
gtk_tree_store_set(store, &iter, 0, itemTitle[3], 1, "", -1);
|
||||
ADD_SUB_INT("Source Port", "%u", ntohs(p->hdr.udp.source));
|
||||
ADD_SUB_INT("Destination Port", "%u", ntohs(p->hdr.udp.dest));
|
||||
ADD_SUB_INT("Length", "%u", ntohs(p->hdr.udp.len));
|
||||
ADD_SUB_INT("Checksum", "0x%04X", ntohs(p->hdr.udp.check));
|
||||
ADD_SUB_INT("Source Port", "%u", ntohs(pUdp->source));
|
||||
ADD_SUB_INT("Destination Port", "%u", ntohs(pUdp->dest));
|
||||
ADD_SUB_INT("Length", "%u", ntohs(pUdp->len));
|
||||
ADD_SUB_INT("Checksum", "0x%04X", ntohs(pUdp->check));
|
||||
|
||||
// 添加 DHCP 内容
|
||||
gtk_tree_store_append(store, &iter, NULL);
|
||||
gtk_tree_store_set(store, &iter, 0, itemTitle[4], 1, "", -1);
|
||||
switch (p->dhcp.op) {
|
||||
switch (pDhcp->op) {
|
||||
case 1:
|
||||
ADD_SUB_STRING("Message Type", "Boot Request");
|
||||
break;
|
||||
|
@ -211,43 +239,43 @@ static void create_dhcp_tree_mode(PDHCP_PACKAGE p, U32 nBytes, GtkWidget *treeVi
|
|||
default:
|
||||
ADD_SUB_STRING("Message Type", "Unknown");
|
||||
}
|
||||
switch (p->dhcp.htype) {
|
||||
switch (pDhcp->htype) {
|
||||
case 1:
|
||||
ADD_SUB_STRING("Hardware Type", "Ethernet");
|
||||
break;
|
||||
default:
|
||||
ADD_SUB_STRING("Hardware Type", "Unknown");
|
||||
}
|
||||
ADD_SUB_INT("Hardware address length", "%u", p->dhcp.hlen);
|
||||
ADD_SUB_INT("Hops", "%u", p->dhcp.hops);
|
||||
ADD_SUB_INT("Transaction ID", "0x%08X", p->dhcp.xid);
|
||||
ADD_SUB_INT("Seconds elapsed", "%u", p->dhcp.secs);
|
||||
ADD_SUB_INT("Bootp flags", "0x%04X", p->dhcp.flags);
|
||||
ADD_SUB_STRING("Client IP address", inet_ntoa(*(struct in_addr *)&p->dhcp.ciaddr));
|
||||
ADD_SUB_STRING("Your(client) IP address", inet_ntoa(*(struct in_addr *)&p->dhcp.yiaddr));
|
||||
ADD_SUB_STRING("Next server IP address", inet_ntoa(*(struct in_addr *)&p->dhcp.siaddr));
|
||||
ADD_SUB_STRING("Relay agent IP address", inet_ntoa(*(struct in_addr *)&p->dhcp.giaddr));
|
||||
ADD_SUB_INT("Hardware address length", "%u", pDhcp->hlen);
|
||||
ADD_SUB_INT("Hops", "%u", pDhcp->hops);
|
||||
ADD_SUB_INT("Transaction ID", "0x%08X", pDhcp->xid);
|
||||
ADD_SUB_INT("Seconds elapsed", "%u", pDhcp->secs);
|
||||
ADD_SUB_INT("Bootp flags", "0x%04X", pDhcp->flags);
|
||||
ADD_SUB_STRING("Client IP address", inet_ntoa(*(struct in_addr *)&pDhcp->ciaddr));
|
||||
ADD_SUB_STRING("Your(client) IP address", inet_ntoa(*(struct in_addr *)&pDhcp->yiaddr));
|
||||
ADD_SUB_STRING("Next server IP address", inet_ntoa(*(struct in_addr *)&pDhcp->siaddr));
|
||||
ADD_SUB_STRING("Relay agent IP address", inet_ntoa(*(struct in_addr *)&pDhcp->giaddr));
|
||||
s = sdsempty();
|
||||
MAC_TO_STR(p->dhcp.chaddr, s);
|
||||
MAC_TO_STR(pDhcp->chaddr, s);
|
||||
ADD_SUB_STRING("Client MAC address", s);
|
||||
sdsfree(s);
|
||||
|
||||
if (strlen((char *)p->dhcp.sname) > 0) {
|
||||
ADD_SUB_STRING("Server host name", p->dhcp.sname);
|
||||
if (strlen((char *)pDhcp->sname) > 0) {
|
||||
ADD_SUB_STRING("Server host name", pDhcp->sname);
|
||||
} else {
|
||||
ADD_SUB_STRING("Server host name", "not given");
|
||||
}
|
||||
|
||||
if (strlen((char *)p->dhcp.file) > 0) {
|
||||
ADD_SUB_STRING("Boot file name", p->dhcp.file);
|
||||
if (strlen((char *)pDhcp->file) > 0) {
|
||||
ADD_SUB_STRING("Boot file name", pDhcp->file);
|
||||
} else {
|
||||
ADD_SUB_STRING("Boot file name", "not given");
|
||||
}
|
||||
|
||||
ADD_SUB_STRING("Magic cookie", "DHCP");
|
||||
|
||||
U8 *opPointer, *optEnd = (U8 *)p + nBytes;
|
||||
opPointer = p->dhcp.options;
|
||||
U8 *opPointer, *optEnd = (U8 *)pkg + nBytes;
|
||||
opPointer = pDhcp->options;
|
||||
while (*opPointer && opPointer < optEnd) {
|
||||
if (*opPointer == OPT_END) {
|
||||
ADD_SUB_STRING("Option(255)", "End");
|
||||
|
@ -291,21 +319,21 @@ static gboolean upgrade_statusbar_proc(gpointer user_data) {
|
|||
(pInfo->pReqBuf.tm.tv_sec * 1000000 + pInfo->pReqBuf.tm.tv_usec));
|
||||
|
||||
if (pInfo->pAckBuf.p) {
|
||||
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)pInfo->pAckBuf.p;
|
||||
U32 optSize = pInfo->pAckBuf.buf_size - sizeof(DHCP_PACKAGE);
|
||||
pIp = u32_to_str_ip_safe(pkg->dhcp.yiaddr);
|
||||
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, pkg->dhcp.options, optSize, &opt);
|
||||
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_ROUTER, pkg->dhcp.options, optSize, &opt);
|
||||
ret = dhcp_get_option(OPT_ROUTER, pDhcp->options, optSize, &opt);
|
||||
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||
pGw = u32_to_str_ip_safe(*((U32 *)opt.pValue));
|
||||
}
|
||||
|
||||
ret = dhcp_get_option(OPT_DNS, pkg->dhcp.options, optSize, &opt);
|
||||
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);
|
||||
|
@ -424,7 +452,7 @@ void details_wnd_show(PDHCP_INFO pInfo) {
|
|||
|
||||
// 填充 TreeView
|
||||
add_dhcp_tree_colums(g_ptvDHcp[i]);
|
||||
create_dhcp_tree_mode((PDHCP_PACKAGE)g_HexBuf[i]->p, g_HexBuf[i]->buf_size, g_ptvDHcp[i]);
|
||||
create_dhcp_tree_mode(g_HexBuf[i]->p, g_HexBuf[i]->buf_size, g_ptvDHcp[i]);
|
||||
}
|
||||
|
||||
upgrade_statusbar_proc(pInfo);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include "uthash/uthash.h"
|
||||
#include "rfc2131.h"
|
||||
#include "service/dhcpd.h"
|
||||
|
||||
#define ADD_LOG_MSG(level, m, format, ...) \
|
||||
(format_log_msg(level, (m), "[%s] - %s(%d):" format, basename_v2(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__))
|
||||
|
@ -95,4 +96,5 @@ void statis_wnd_create(GtkBuilder *builder);
|
|||
void write_log_msg(const char *pMsg, int mode);
|
||||
GtkBuilder *get_main_builder();
|
||||
void format_log_msg(int level, int mode, const char *pMsg, ...);
|
||||
PDHCP_PROTO get_dhcp_date(void *pBuf, U32 *pOptSize, U32 bufSize);
|
||||
#endif //VCPE_MAIN_H
|
||||
|
|
|
@ -98,17 +98,17 @@ static void get_task_result(PDHCP_INFO pInfo, char *pInBuf, int maxBuf) {
|
|||
} else if (pInfo->step == STEP_END) {
|
||||
int ret;
|
||||
DHCP_OPT opt;
|
||||
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)pInfo->pAckBuf.p;
|
||||
U32 optSize = pInfo->pAckBuf.buf_size - sizeof(DHCP_PACKAGE);
|
||||
const char *pIp = NULL, *pNetmask = NULL, *pDns1 = NULL, *pDns2 = NULL;
|
||||
pIp = u32_to_str_ip_safe(pkg->dhcp.yiaddr);
|
||||
U32 optSize = 0;
|
||||
PDHCP_PROTO pDhcp = get_dhcp_date(pInfo->pAckBuf.p, &optSize, pInfo->pAckBuf.buf_size);
|
||||
|
||||
ret = dhcp_get_option(OPT_NETMASK, pkg->dhcp.options, optSize, &opt);
|
||||
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, pkg->dhcp.options, optSize, &opt);
|
||||
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);
|
||||
|
|
|
@ -15,91 +15,141 @@
|
|||
static U8 g_dhcpReqParams[] = {0x01, 0x1c, 0x02, 0x03, 0x0f, 0x06, 0x77, 0x0c, 0x2c, 0x2f, 0x1a, 0x79, 0x2a};
|
||||
static char *g_pNicName = NULL;
|
||||
|
||||
static void pkg_init_head(PDHCP_PACKAGE p, PDHCP_INFO pInfo) {
|
||||
static PDHCP_PROTO fill_dhcp_pkg(U8 *pRsp, PDHCP_INFO pInfo) {
|
||||
struct ethhdr *pEth = (struct ethhdr *)pRsp;
|
||||
struct iphdr *pIp = NULL;
|
||||
struct udphdr *pUdp = NULL;
|
||||
PDHCP_PROTO pDhcp = NULL;
|
||||
|
||||
memset(pRsp, 0, MAX_DHCP_PKG_SIZE);
|
||||
|
||||
// 目的地 MAC 地址
|
||||
memset(p->hdr.eth.h_dest, 0xFF, ETH_ALEN);
|
||||
memset(pEth->h_dest, 0xFF, ETH_ALEN);
|
||||
// 源 MAC 地址
|
||||
memcpy(p->hdr.eth.h_source, pInfo->mac, ETH_ALEN);
|
||||
memcpy(pEth->h_source, pInfo->mac, ETH_ALEN);
|
||||
|
||||
#if VLAN_SUPPORT
|
||||
// 协议 VLAN
|
||||
p->hdr.eth.h_proto = htons(ETH_P_8021Q);
|
||||
|
||||
// VLAN 隧道信息
|
||||
p->hdr.vlan.id = htons(pInfo->vni);
|
||||
p->hdr.vlan.type = htons(ETH_P_IP);
|
||||
#else
|
||||
// 协议 VLAN
|
||||
p->hdr.eth.h_proto = htons(ETH_P_IP);
|
||||
#endif
|
||||
|
||||
// IP 头
|
||||
p->hdr.ip.version = IPVERSION;
|
||||
p->hdr.ip.ihl = 5;
|
||||
p->hdr.ip.tos = 0;
|
||||
p->hdr.ip.tot_len = 0;
|
||||
p->hdr.ip.id = 0;
|
||||
p->hdr.ip.frag_off = 0;
|
||||
p->hdr.ip.ttl = 128;
|
||||
p->hdr.ip.protocol = IPPROTO_UDP;
|
||||
p->hdr.ip.check = 0;
|
||||
p->hdr.ip.saddr = INADDR_ANY;
|
||||
p->hdr.ip.daddr = INADDR_BROADCAST;
|
||||
|
||||
// UDP 头
|
||||
p->hdr.udp.source = htons(DHCP_CLI_PORT);
|
||||
p->hdr.udp.dest = htons(DHCP_SVR_PORT);
|
||||
p->hdr.udp.len = 0;
|
||||
p->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 = 0;
|
||||
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);
|
||||
if (pInfo->vni == 0) {
|
||||
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET);
|
||||
pUdp = (struct udphdr *)(UDP_HDR_OFFSET);
|
||||
pDhcp = (PDHCP_PROTO)((U8 *)pRsp + DHCP_OFFSET);
|
||||
pEth->h_proto = htons(ETH_P_IP);
|
||||
} else if (pInfo->vni >= 1 && pInfo->vni <= 4094) {
|
||||
PVLAN_HDR pHdr = (PVLAN_HDR)(pRsp + sizeof(struct ethhdr));
|
||||
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||
pUdp = (struct udphdr *)(pRsp + UDP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||
pDhcp = (PDHCP_PROTO)((U8 *)pRsp + DHCP_OFFSET + sizeof(VLAN_HDR));
|
||||
pEth->h_proto = htons(ETH_P_8021Q);
|
||||
pHdr->id = htons(pInfo->vni);
|
||||
pHdr->type = htons(ETH_P_IP);
|
||||
} else {
|
||||
PVLAN_HDR2 pHdr = (PVLAN_HDR2)(pRsp + sizeof(struct ethhdr));
|
||||
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||
pUdp = (struct udphdr *)(pRsp + UDP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||
pDhcp = (PDHCP_PROTO)((U8 *)pRsp + DHCP_OFFSET + sizeof(VLAN_HDR2));
|
||||
pEth->h_proto = htons(ETH_P_8021Q);
|
||||
pHdr->id1 = htons(4094);
|
||||
pHdr->h_type = htons(ETH_P_8021Q);
|
||||
pHdr->id2 = htons((pInfo->vni - 4094) & 0x0FFF);
|
||||
pHdr->type = htons(ETH_P_IP);
|
||||
}
|
||||
|
||||
static void cacl_package_checksum(PDHCP_PACKAGE p, int tolSize) {
|
||||
// IP 头
|
||||
pIp->version = IPVERSION;
|
||||
pIp->ihl = 5;
|
||||
pIp->tos = 0;
|
||||
pIp->tot_len = 0;
|
||||
pIp->id = 0;
|
||||
pIp->frag_off = 0;
|
||||
pIp->ttl = 128;
|
||||
pIp->protocol = IPPROTO_UDP;
|
||||
pIp->check = 0;
|
||||
pIp->saddr = INADDR_ANY;
|
||||
pIp->daddr = INADDR_BROADCAST;
|
||||
|
||||
// UDP 头
|
||||
pUdp->source = htons(DHCP_CLI_PORT);
|
||||
pUdp->dest = htons(DHCP_SVR_PORT);
|
||||
pUdp->len = 0;
|
||||
pUdp->check = 0;
|
||||
|
||||
// DHCP 协议内容
|
||||
pDhcp->op = BOOTP_REQUEST;
|
||||
pDhcp->htype = 0x01;
|
||||
pDhcp->hlen = ETH_ALEN;
|
||||
pDhcp->hops = 0;
|
||||
pDhcp->xid = 0;
|
||||
pDhcp->secs = 0;
|
||||
pDhcp->flags = 0;
|
||||
pDhcp->ciaddr = INADDR_ANY;
|
||||
pDhcp->yiaddr = INADDR_ANY;
|
||||
pDhcp->siaddr = INADDR_ANY;
|
||||
pDhcp->giaddr = INADDR_ANY;
|
||||
memcpy(pDhcp->chaddr, pInfo->mac, ETH_ALEN);
|
||||
pDhcp->cookie = htonl(DHCP_COOKIE_VAL);
|
||||
|
||||
return pDhcp;
|
||||
}
|
||||
|
||||
static U32 dhcp_pkk_checksum(U8 *pRsp, U32 optSize) {
|
||||
struct iphdr *pIp = NULL;
|
||||
struct udphdr *pUdp = NULL;
|
||||
U16 csum;
|
||||
U32 tolSize;
|
||||
U8 vlanSize = 0;
|
||||
|
||||
switch (get_package_vlan_type(pRsp)) {
|
||||
default:
|
||||
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET);
|
||||
pUdp = (struct udphdr *)(UDP_HDR_OFFSET);
|
||||
// 计算包总长度
|
||||
tolSize = optSize + sizeof(DHCP_PROTO) + DHCP_OFFSET;
|
||||
break;
|
||||
case VLAN_LEVEL1:
|
||||
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||
pUdp = (struct udphdr *)(pRsp + UDP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||
// 计算包总长度
|
||||
tolSize = optSize + sizeof(DHCP_PROTO) + DHCP_OFFSET + sizeof(VLAN_HDR);
|
||||
vlanSize = sizeof(VLAN_HDR);
|
||||
break;
|
||||
case VLAN_LEVEL2:
|
||||
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||
pUdp = (struct udphdr *)(pRsp + UDP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||
// 计算包总长度
|
||||
tolSize = optSize + sizeof(DHCP_PROTO) + DHCP_OFFSET + sizeof(VLAN_HDR2);
|
||||
vlanSize = sizeof(VLAN_HDR2);
|
||||
break;
|
||||
}
|
||||
|
||||
// 计算 IP 数据长度
|
||||
p->hdr.ip.tot_len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr));
|
||||
pIp->tot_len = htons(tolSize - sizeof(struct ethhdr) - vlanSize);
|
||||
// 计算 UDP 数据长度
|
||||
p->hdr.udp.len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr) - sizeof(struct iphdr));
|
||||
pUdp->len = htons(tolSize - sizeof(struct ethhdr) - vlanSize - sizeof(struct iphdr));
|
||||
|
||||
// 计算 IP 校验和
|
||||
csum = htons(ip_checksum((unsigned char *)&p->hdr.ip));
|
||||
p->hdr.ip.check = htons(csum);
|
||||
csum = htons(ip_checksum((unsigned char *)pIp));
|
||||
pIp->check = htons(csum);
|
||||
|
||||
// 计算 UDP 校验和
|
||||
csum = htons(udp_checksum(p->hdr.ip.saddr, p->hdr.ip.daddr, (unsigned char *)&p->hdr.udp));
|
||||
p->hdr.udp.check = htons(csum);
|
||||
csum = htons(udp_checksum(pIp->saddr, pIp->daddr, (unsigned char *)pUdp));
|
||||
pUdp->check = htons(csum);
|
||||
|
||||
return tolSize;
|
||||
}
|
||||
|
||||
U8 *dhcp_create_request_req(PDHCP_INFO pInfo, int *pOutSize) {
|
||||
U8 *pOpt;
|
||||
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);
|
||||
//PDHCP_PACKAGE pDhcp = (PDHCP_PACKAGE)pReqData;
|
||||
PDHCP_PROTO pDhcp = fill_dhcp_pkg(pReqData, pInfo);
|
||||
|
||||
pkg_init_head(p, pInfo);
|
||||
//pkg_init_head(pDhcp, pInfo);
|
||||
|
||||
p->dhcp.xid = htonl(pInfo->offerRsp.xid);
|
||||
pDhcp->xid = htonl(pInfo->offerRsp.xid);
|
||||
|
||||
// DHCP Options
|
||||
pOpt = p->dhcp.options;
|
||||
pOpt = pDhcp->options;
|
||||
|
||||
// DHCP 消息类型
|
||||
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_REQUEST);
|
||||
|
@ -113,12 +163,8 @@ U8 *dhcp_create_request_req(PDHCP_INFO pInfo, int *pOutSize) {
|
|||
pOpt += dhcp_add_u32_option(pOpt, OPT_REQUESTEDIPADDR, htonl(pInfo->offerRsp.ipAddr));
|
||||
// 结束
|
||||
*pOpt = OPT_END;
|
||||
// 计算包总长度
|
||||
tolSize = (int)((pOpt - p->dhcp.options) + 1 + sizeof(DHCP_PACKAGE));
|
||||
|
||||
cacl_package_checksum(p, tolSize);
|
||||
|
||||
*pOutSize = tolSize;
|
||||
*pOutSize = (int)dhcp_pkk_checksum(pReqData, (int)((pOpt - pDhcp->options) + 1));
|
||||
}
|
||||
|
||||
return pReqData;
|
||||
|
@ -130,15 +176,15 @@ U8 *dhcp_create_discover_req(PDHCP_INFO pInfo, int *pOutSize) {
|
|||
U8 *pReqData = (U8 *)malloc(MAX_DHCP_PKG_SIZE);
|
||||
|
||||
if (pReqData) {
|
||||
PDHCP_PACKAGE p = (PDHCP_PACKAGE)pReqData;
|
||||
//PDHCP_PACKAGE pDhcp = (PDHCP_PACKAGE)pReqData;
|
||||
PDHCP_PROTO pDhcp = fill_dhcp_pkg(pReqData, pInfo);
|
||||
//memset(pReqData, 0, MAX_DHCP_PKG_SIZE);
|
||||
|
||||
memset(pReqData, 0, MAX_DHCP_PKG_SIZE);
|
||||
|
||||
pkg_init_head(p, pInfo);
|
||||
p->dhcp.xid = htonl((rand_number() & 0xFF000000) + pInfo->index);
|
||||
//pkg_init_head(pDhcp, pInfo);
|
||||
pDhcp->xid = htonl((rand_number() & 0xFF000000) + pInfo->index);
|
||||
|
||||
// DHCP Options
|
||||
pOpt = p->dhcp.options;
|
||||
pOpt = pDhcp->options;
|
||||
|
||||
// DHCP 消息类型
|
||||
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_DISCOVER);
|
||||
|
@ -149,12 +195,7 @@ U8 *dhcp_create_discover_req(PDHCP_INFO pInfo, int *pOutSize) {
|
|||
// 结束
|
||||
*pOpt = OPT_END;
|
||||
|
||||
// 计算包总长度
|
||||
tolSize = (int)((pOpt - p->dhcp.options) + 1 + sizeof(DHCP_PACKAGE));
|
||||
|
||||
cacl_package_checksum(p, tolSize);
|
||||
|
||||
*pOutSize = tolSize;
|
||||
*pOutSize = (int)dhcp_pkk_checksum(pReqData, (int)((pOpt - pDhcp->options) + 1));
|
||||
}
|
||||
|
||||
return pReqData;
|
||||
|
@ -167,18 +208,18 @@ static void on_dhcp_recv(uv_work_t *req) {
|
|||
DHCP_OPT optMsg, opt;
|
||||
int ret;
|
||||
PPKG_PROCESS_INFO pWork = (PPKG_PROCESS_INFO)req->data;
|
||||
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)pWork->pPkgBase;
|
||||
U32 optSize = pWork->nSize - sizeof(DHCP_PACKAGE);
|
||||
U32 id = DHCP_XID(pkg->dhcp.xid);
|
||||
U32 optSize = 0;
|
||||
PDHCP_PROTO pDhcp = get_dhcp_date(pWork->pPkgBase, &optSize, pWork->nSize);
|
||||
U32 id = DHCP_XID(pDhcp->xid);
|
||||
|
||||
// Check op flag
|
||||
if (pkg->dhcp.op != BOOTP_REPLY) {
|
||||
LOG_MOD(error, ZM_DHCP_NET, "Error message op code %d\n", pkg->dhcp.op);
|
||||
if (pDhcp->op != BOOTP_REPLY) {
|
||||
LOG_MOD(error, ZM_DHCP_NET, "Error message op code %d\n", pDhcp->op);
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取消息类型
|
||||
ret = dhcp_get_option(OPT_MESSAGETYPE, pkg->dhcp.options, optSize, &optMsg);
|
||||
ret = dhcp_get_option(OPT_MESSAGETYPE, pDhcp->options, optSize, &optMsg);
|
||||
if (ret != ERR_SUCCESS) {
|
||||
LOG_MOD(error, ZM_DHCP_NET, "Get \'message type\' option error %d\n", ret);
|
||||
return;
|
||||
|
@ -187,24 +228,24 @@ static void on_dhcp_recv(uv_work_t *req) {
|
|||
pInfo = get_dhcp_info_by_id(id);
|
||||
|
||||
if (pInfo == NULL) {
|
||||
LOG_MOD(error, ZM_DHCP_NET, "Unknown Client %d\n", DHCP_XID(pkg->dhcp.xid) & 0xFFFFFF);
|
||||
LOG_MOD(error, ZM_DHCP_NET, "Unknown Client %d\n", DHCP_XID(pDhcp->xid) & 0xFFFFFF);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&rspDhcp, 0, sizeof(DHCP_RSP));
|
||||
rspDhcp.xid = id;
|
||||
rspDhcp.ipAddr = ntohl(pkg->dhcp.yiaddr);
|
||||
memcpy(rspDhcp.cliMac, pkg->dhcp.chaddr, ETH_ALEN);
|
||||
memcpy(rspDhcp.svrHostname, pkg->dhcp.sname, 64);
|
||||
rspDhcp.ipAddr = ntohl(pDhcp->yiaddr);
|
||||
memcpy(rspDhcp.cliMac, pDhcp->chaddr, ETH_ALEN);
|
||||
memcpy(rspDhcp.svrHostname, pDhcp->sname, 64);
|
||||
|
||||
switch (*optMsg.pValue) {
|
||||
case DHCP_MSG_OFFER:
|
||||
ret = dhcp_get_option(OPT_NETMASK, pkg->dhcp.options, optSize, &opt);
|
||||
ret = dhcp_get_option(OPT_NETMASK, pDhcp->options, optSize, &opt);
|
||||
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||
rspDhcp.netmask = ntohl(*((U32 *)opt.pValue));
|
||||
}
|
||||
|
||||
ret = dhcp_get_option(OPT_DNS, pkg->dhcp.options, optSize, &opt);
|
||||
ret = dhcp_get_option(OPT_DNS, pDhcp->options, optSize, &opt);
|
||||
if (ret == ERR_SUCCESS) {
|
||||
U32 *pVal = (U32 *)opt.pValue;
|
||||
rspDhcp.primeDNS = ntohl(*pVal);
|
||||
|
@ -214,22 +255,22 @@ static void on_dhcp_recv(uv_work_t *req) {
|
|||
}
|
||||
}
|
||||
|
||||
ret = dhcp_get_option(OPT_ROUTER, pkg->dhcp.options, optSize, &opt);
|
||||
ret = dhcp_get_option(OPT_ROUTER, pDhcp->options, optSize, &opt);
|
||||
if (ret == ERR_SUCCESS) {
|
||||
rspDhcp.route = ntohl(*((U32 *)opt.pValue));
|
||||
}
|
||||
|
||||
ret = dhcp_get_option(OPT_IPADDRLEASE, pkg->dhcp.options, optSize, &opt);
|
||||
ret = dhcp_get_option(OPT_IPADDRLEASE, pDhcp->options, optSize, &opt);
|
||||
if (ret == ERR_SUCCESS) {
|
||||
rspDhcp.leaseTime = ntohl(*((U32 *)opt.pValue));
|
||||
}
|
||||
|
||||
ret = dhcp_get_option(OPT_SERVERID, pkg->dhcp.options, optSize, &opt);
|
||||
ret = dhcp_get_option(OPT_SERVERID, pDhcp->options, optSize, &opt);
|
||||
if (ret == ERR_SUCCESS) {
|
||||
rspDhcp.svrIp = ntohl(*((U32 *)opt.pValue));
|
||||
}
|
||||
|
||||
ret = dhcp_get_option(OPT_DOMAINNAME, pkg->dhcp.options, optSize, &opt);
|
||||
ret = dhcp_get_option(OPT_DOMAINNAME, pDhcp->options, optSize, &opt);
|
||||
if (ret == ERR_SUCCESS) {
|
||||
strncpy(rspDhcp.domainName, (char *)opt.pValue, MIN((int)opt.len, 64));
|
||||
}
|
||||
|
@ -271,7 +312,7 @@ int dhcp_tools_init_network(const char *pNicName) {
|
|||
}
|
||||
|
||||
#if VLAN_SUPPORT
|
||||
init_filter("vlan and udp and dst port 68");
|
||||
init_filter("vlan or (udp and dst port 68)");
|
||||
#else
|
||||
init_filter("udp and dst port 68");
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue