diff --git a/config/vcpe.cfg b/config/vcpe.cfg index 7789a73..6393d70 100644 --- a/config/vcpe.cfg +++ b/config/vcpe.cfg @@ -100,7 +100,7 @@ application: # MAC地址黑名单 # mac_filter = ["00:01:02:03:04:07", "00:01:02:03:04:01"]; # 数据包过滤器 - net_filter = "vlan or (udp and dst port 67)"; + net_filter = " (udp and dst port 67) or vlan"; # IP地址池配置 range_set: ( { dhcp_range = "192.168.101.2-192.168.101.40"; diff --git a/srcs/service/dhcpd/db_interface.c b/srcs/service/dhcpd/db_interface.c index 8ab3afc..fd976c4 100644 --- a/srcs/service/dhcpd/db_interface.c +++ b/srcs/service/dhcpd/db_interface.c @@ -6,8 +6,6 @@ #include "user_errno.h" #include "database.h" #include "dhcp_network.h" -#include "rfc2131.h" -#include "ip_pool.h" #include "db_interface.h" #include "misc.h" #include "zlog_module.h" @@ -53,6 +51,18 @@ " createTm TIMESTAMP DEFAULT (datetime('now', 'localtime')) NOT NULL" \ "); CREATE INDEX IF NOT EXISTS pre_assign_index ON pre_assign(ip, uid);" +#define CREATE_IPTV_TABLE() \ + "CREATE TABLE IF NOT EXISTS iptv" \ + " ( id INTEGER PRIMARY KEY AUTOINCREMENT," \ + " uid INTEGER NOT NULL," \ + " mac CHAR(20) NOT NULL," \ + " createTm TIMESTAMP DEFAULT (datetime('now', 'localtime')) NOT NULL" \ + "); CREATE INDEX IF NOT EXISTS iptv_index ON iptv(uid);" + +#define INSERT_IPTV_DEVICE \ + "INSERT INTO iptv (uid, mac) SELECT %d, '%s' WHERE NOT EXISTS (SELECT id FROM iptv WHERE uid = %d AND mac = " \ + "'%s');" + #define INSERT_PRE_ASSIGN_ROW_FMT \ "INSERT INTO pre_assign (uid, xid, hostname, mac, ip, lease, netmask, gateway, dns1, dns2, server) " \ "VALUES (%d, %d, '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s');" @@ -114,6 +124,22 @@ #define LEASE_RELEASE_FMT "DELETE FROM lease WHERE uid = %d AND mac = '%s' AND ip = '%s'" +int db_iptv_add_device(U32 uid, const char *pMac) { + int rc; + char buf[2048] = {0}; + //INSERT INTO iptv (uid, mac) SELECT 0, '58:B4:2D:DA:D4:25' WHERE NOT EXISTS (SELECT id FROM iptv WHERE uid = 0 AND mac = '58:B4:2D:DA:D4:26') + + snprintf(buf, 2048, INSERT_IPTV_DEVICE, uid, pMac, uid, pMac); + + rc = db_sqlite3_sql_exec(buf, NULL, NULL, NULL); + + if (rc != ERR_SUCCESS) { + LOG_MOD(error, ZM_DHCP_DB, "DB add iptv device error: %s\n", buf); + } + + return ERR_SUCCESS; +} + static int lease_add(PDHCP_REQ pReq, const char *ip, const char *netmask, @@ -506,5 +532,11 @@ int db_init_lease_database() { return rc; } + rc = db_sqlite3_sql_exec(CREATE_IPTV_TABLE(), NULL, NULL, NULL); + + if (rc != ERR_SUCCESS) { + return rc; + } + return ERR_SUCCESS; } \ No newline at end of file diff --git a/srcs/service/dhcpd/dhcpd_network.c b/srcs/service/dhcpd/dhcpd_network.c index 07e0b22..954c6ff 100644 --- a/srcs/service/dhcpd/dhcpd_network.c +++ b/srcs/service/dhcpd/dhcpd_network.c @@ -536,6 +536,8 @@ static void on_sock_recv(uv_work_t *req) { PDHCP_PROTO pkg = get_dhcp_date(pWork->pPkgBase, &optSize, pWork->nSize); struct iphdr *pIpHdr = (struct iphdr *)((U8 *)pkg - sizeof(struct iphdr) - sizeof(struct udphdr)); + //LOG_MSG(info, "Recv, xid: 0x%08X\n", DHCP_XID(pkg->xid)); + //sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macStr[0], macStr[1], macStr[2], macStr[3], macStr[4], macStr[5]); // Check op flag @@ -581,7 +583,12 @@ static void on_sock_recv(uv_work_t *req) { ret = dhcp_get_option(OPT_VENDORCLASSID, pkg->options, optSize, &opt); if (ret == ERR_SUCCESS) { - strncpy(reqDhcp.vendorClassId, (char *)opt.pValue, MIN((int)opt.len, 256)); + memcpy(reqDhcp.vendorClassId, (char *)opt.pValue, MIN((int)opt.len, 256)); + + // IPTV 组播设备不用分配IP地址 + if (analyze_iptv_multicast_dev((const U8 *)reqDhcp.vendorClassId, opt.len, macStr, reqDhcp.uid)) { + return; + } } ret = dhcp_get_option(OPT_HOSTNAME, pkg->options, optSize, &opt); @@ -719,7 +726,6 @@ static void on_sock_recv(uv_work_t *req) { //dhcp_option_prase(optMsg, pkg->options, pWork->nSize - sizeof(DHCP_PACKAGE)); //LOG_MSG_HEX(trace, pkg, pWork->nSize); - //LOG_MSG(info, "Recv, xid: 0x%08X\n", DHCP_XID(pkg->xid)); #if 0 LOG_MOD(info, ZM_DHCP_NET, "vlan = %u\n", VXLAN_VIN_ID_PACK(pkg->hdr.vlan.id)); diff --git a/srcs/service/dhcpd/include/db_interface.h b/srcs/service/dhcpd/include/db_interface.h index 2258282..5405dbd 100644 --- a/srcs/service/dhcpd/include/db_interface.h +++ b/srcs/service/dhcpd/include/db_interface.h @@ -7,6 +7,8 @@ #ifdef __cplusplus extern "C" { #endif +#include "rfc2131.h" +#include "ip_pool.h" int db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PPOOL_CTX pPool); int db_init_lease_database(); int db_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign); @@ -17,6 +19,7 @@ int db_clearup_timeout_lease(); int db_lock_pre_assign_ip(); int db_release_lease(PDHCP_REQ pReq); int db_add_lease(PDHCP_REQ pReq, PPOOL_CTX pCtx); +int db_iptv_add_device(U32 uid, const char *pMac); #ifdef __cplusplus } #endif diff --git a/srcs/service/dhcpd/include/dhcp_options.h b/srcs/service/dhcpd/include/dhcp_options.h index 989c237..8c205a0 100644 --- a/srcs/service/dhcpd/include/dhcp_options.h +++ b/srcs/service/dhcpd/include/dhcp_options.h @@ -4,7 +4,9 @@ #ifndef VCPE_DHCP_OPTIONS_H #define VCPE_DHCP_OPTIONS_H + #include "common.h" + #ifdef __cplusplus extern "C" { #endif @@ -148,8 +150,10 @@ int dhcp_add_buf_option(U8 *pBegin, int opt, U8 *buf, U8 nSize); int dhcp_add_string_option(U8 *pBegin, int opt, const char *buf); int dhcp_get_option(int opt, U8 *pOptData, U32 nSize, PDHCP_OPT pVal); void dhcp_option_cfg_init(); -const char* dhcp_get_opName(int opt); +const char *dhcp_get_opName(int opt); int dhcp_get_opType(int opt); +int analyze_iptv_multicast_dev(const unsigned char *p, int UNUSED_size, const char *mac, U32 uid); + #ifdef __cplusplus } #endif diff --git a/srcs/service/dhcpd/iptv_dev.c b/srcs/service/dhcpd/iptv_dev.c new file mode 100644 index 0000000..af70f10 --- /dev/null +++ b/srcs/service/dhcpd/iptv_dev.c @@ -0,0 +1,21 @@ +// +// Created by HuangXin on 2023/5/17. +// +#include +#include "zlog_module.h" +#include "common.h" +#include "db_interface.h" + +int analyze_iptv_multicast_dev(const unsigned char *p, int UNUSED(size), const char *mac, U32 uid) { + char ipTvId[16] = {0}; + memcpy(ipTvId, &p[4], 10); + + if (strcmp(ipTvId, "JSCMCC-OTT") == 0) { + LOG_MOD(debug, ZM_DHCP, "Found IPTV %s of user %d\n", mac, uid); + db_iptv_add_device(uid, mac); + return TRUE; + } + + LOG_MOD(trace, ZM_DHCP, "Device %s is not IPTV device of user %d\n", mac, uid); + return FALSE; +} \ No newline at end of file