📄 netlink.htm
字号:
nSocket = socket(AF_NETLINK, SOCK_RAW, NETLINK_FIREWALL);
<font color="#ffff00"><b>if</b></font> (nSocket < <font color="#ff40ff"><b>0</b></font>)
{
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"创建SOCKET错误:</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>, strerror(errno));
<font color="#ffff00"><b>return</b></font> -<font color="#ff40ff"><b>1</b></font>;
}
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 监听本地地址</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
memset(&struAddr, <font color="#ff40ff"><b>0</b></font>, <font color="#ffff00"><b>sizeof</b></font>(struAddr));
struAddr.nl_family = AF_NETLINK;
struAddr.nl_pid = getpid();
struAddr.nl_groups = <font color="#ff40ff"><b>0</b></font>;
<font color="#ffff00"><b>if</b></font>(bind(nSocket, (<font color="#00ff00"><b>struct</b></font> sockaddr *)&struAddr, <font color="#ffff00"><b>sizeof</b></font>(struAddr)) < <font color="#ff40ff"><b>0</b></font>)
{
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"绑定SOCKET错误:</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>, strerror(errno));
<font color="#ffff00"><b>return</b></font> -<font color="#ff40ff"><b>1</b></font>;
}
memset(&struAct, <font color="#ff40ff"><b>0</b></font>, <font color="#ffff00"><b>sizeof</b></font>(struAct));
struAct.sa_handler = in_catch_sig;
sigfillset(&struAct.sa_mask);
<font color="#ffff00"><b>if</b></font>(sigaction(<font color="#ff40ff"><b>SIGINT</b></font>, &struAct, <font color="#ff40ff"><b>NULL</b></font>) < <font color="#ff40ff"><b>0</b></font>)
{
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"设置信号捕捉错误:</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>, strerror(errno));
<font color="#ffff00"><b>return</b></font> -<font color="#ff40ff"><b>1</b></font>;
}
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 设置报文内容</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
memset(&struReq, <font color="#ff40ff"><b>0</b></font>, <font color="#ffff00"><b>sizeof</b></font>(struReq));
struReq.head.nlmsg_len = NLMSG_LENGTH(<font color="#ffff00"><b>sizeof</b></font>(struReq));
struReq.head.nlmsg_type = IPQM_MODE;
struReq.head.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
struReq.head.nlmsg_pid = getpid();
struReq.body.mode.value = IPQ_COPY_META;
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 发送报文到内核</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
memset(&struAddr, <font color="#ff40ff"><b>0</b></font>, <font color="#ffff00"><b>sizeof</b></font>(struAddr));
struAddr.nl_family = AF_NETLINK;
struAddr.nl_pid = <font color="#ff40ff"><b>0</b></font>;
struAddr.nl_groups = <font color="#ff40ff"><b>0</b></font>;
<font color="#ffff00"><b>if</b></font>(sendto(nSocket, &struReq, struReq.head.nlmsg_len, <font color="#ff40ff"><b>0</b></font>,
(<font color="#00ff00"><b>struct</b></font> sockaddr *)&struAddr, <font color="#ffff00"><b>sizeof</b></font>(struAddr)) < <font color="#ff40ff"><b>0</b></font>)
{
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"设置 IPQM_MODE 错误:</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>, strerror(errno));
<font color="#ffff00"><b>return</b></font> -<font color="#ff40ff"><b>1</b></font>;
}
memset(szBuffer, <font color="#ff40ff"><b>0</b></font>, <font color="#ffff00"><b>sizeof</b></font>(szBuffer));
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"Press CTRL+C to quit</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>);
<font color="#ffff00"><b>while</b></font>(gnContinue)
{
nLen = recv(nSocket, szBuffer, <font color="#ffff00"><b>sizeof</b></font>(szBuffer), <font color="#ff40ff"><b>0</b></font>);
<font color="#ffff00"><b>if</b></font>(nLen < <font color="#ff40ff"><b>0</b></font>)
<font color="#ffff00"><b>break</b></font>;
pstruNL =(<font color="#00ff00"><b>struct</b></font> nlmsghdr *)szBuffer;
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 判断是否继续有数据</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
<font color="#ffff00"><b>while</b></font>(NLMSG_OK(pstruNL, nLen))
{
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 数据已经获取完成</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
<font color="#ffff00"><b>if</b></font>(pstruNL -> nlmsg_type == NLMSG_DONE)
<font color="#ffff00"><b>break</b></font>;
<font color="#ffff00"><b>if</b></font>(pstruNL -> nlmsg_type == NLMSG_ERROR)
{
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 发生一个错误</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
<font color="#00ff00"><b>struct</b></font> nlmsgerr *pstruError;
pstruError = (<font color="#00ff00"><b>struct</b></font> nlmsgerr *)NLMSG_DATA(pstruNL);
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"发生错误[</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff40ff"><b>]</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>,
strerror(-pstruError -> error));
<font color="#ffff00"><b>break</b></font>;
}
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 下面通过宏获取数据</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
<font color="#ffff00"><b>if</b></font>(pstruNL -> nlmsg_type == IPQM_PACKET)
{
pstruPacketMsg = NLMSG_DATA(pstruNL);
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"获取到一个报文:[MARK-</b></font><font color="#ff6060"><b>%lu</b></font><font color="#ff40ff"><b>]"</b></font>,
pstruPacketMsg -> mark);
<font color="#ffff00"><b>switch</b></font>(pstruPacketMsg -> hook)
{
<font color="#ffff00"><b>case</b></font> NF_IP_PRE_ROUTING:
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"[PREROUTING]"</b></font>);
<font color="#ffff00"><b>break</b></font>;
<font color="#ffff00"><b>case</b></font> NF_IP_LOCAL_IN:
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"[INPUT]"</b></font>);
<font color="#ffff00"><b>break</b></font>;
<font color="#ffff00"><b>case</b></font> NF_IP_FORWARD:
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"[FORWARD]"</b></font>);
<font color="#ffff00"><b>break</b></font>;
<font color="#ffff00"><b>case</b></font> NF_IP_LOCAL_OUT:
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"[OUTPUT]"</b></font>);
<font color="#ffff00"><b>break</b></font>;
<font color="#ffff00"><b>case</b></font> NF_IP_POST_ROUTING:
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"[POSTROUTING]"</b></font>);
<font color="#ffff00"><b>break</b></font>;
<font color="#ffff00"><b>default</b></font>:
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"[UNKNOWN]"</b></font>);
<font color="#ffff00"><b>break</b></font>;
}
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>);
struTmNow = *localtime(&pstruPacketMsg -> timestamp_sec);
fprintf(<font color="#ff40ff"><b>stderr</b></font>,
<font color="#ff40ff"><b>"</b></font><font color="#ff6060"><b>\t</b></font><font color="#ff40ff"><b>时间[</b></font><font color="#ff6060"><b>%04d</b></font><font color="#ff40ff"><b>-</b></font><font color="#ff6060"><b>%02d</b></font><font color="#ff40ff"><b>-</b></font><font color="#ff6060"><b>%02d</b></font><font color="#ff40ff"><b> </b></font><font color="#ff6060"><b>%02d</b></font><font color="#ff40ff"><b>:</b></font><font color="#ff6060"><b>%02d</b></font><font color="#ff40ff"><b>:</b></font><font color="#ff6060"><b>%02d</b></font><font color="#ff40ff"><b>] ID:</b></font><font color="#ff6060"><b>%lu</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>,
struTmNow.tm_year + <font color="#ff40ff"><b>1900</b></font>, struTmNow.tm_mon + <font color="#ff40ff"><b>1</b></font>,
struTmNow.tm_mday, struTmNow.tm_hour,
struTmNow.tm_min, struTmNow.tm_sec,
pstruPacketMsg -> packet_id);
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"</b></font><font color="#ff6060"><b>\t</b></font><font color="#ff40ff"><b>进入:</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff40ff"><b> 出去:</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>,
pstruPacketMsg -> indev_name,
pstruPacketMsg -> outdev_name);
<font color="#ffff00"><b>if</b></font>(pstruPacketMsg -> hw_type == ARPHRD_ETHER)
{
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"</b></font><font color="#ff6060"><b>\t</b></font><font color="#ff40ff"><b>MAC地址:</b></font><font color="#ff6060"><b>%s</b></font><font color="#ff6060"><b>\n</b></font><font color="#ff40ff"><b>"</b></font>,
ether_ntoa((<font color="#00ff00"><b>struct</b></font> ether_addr *)
pstruPacketMsg -> hw_addr));
}
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 决定数据的下一步</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
memset(&struReq, <font color="#ff40ff"><b>0</b></font>, <font color="#ffff00"><b>sizeof</b></font>(struReq));
struReq.head.nlmsg_len = NLMSG_LENGTH(<font color="#ffff00"><b>sizeof</b></font>(struReq));
struReq.head.nlmsg_type = IPQM_VERDICT;
struReq.head.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
struReq.head.nlmsg_pid = getpid();
struReq.body.verdict.value = NF_ACCEPT;
struReq.body.verdict.id = pstruPacketMsg -> packet_id;
<font color="#00ffff"><b>/*</b></font>
<font color="#00ffff"><b> * 发送报文到内核</b></font>
<font color="#00ffff"><b> </b></font><font color="#00ffff"><b>*/</b></font>
memset(&struAddr, <font color="#ff40ff"><b>0</b></font>, <font color="#ffff00"><b>sizeof</b></font>(struAddr));
struAddr.nl_family = AF_NETLINK;
struAddr.nl_pid = <font color="#ff40ff"><b>0</b></font>;
struAddr.nl_groups = <font color="#ff40ff"><b>0</b></font>;
<font color="#ffff00"><b>if</b></font>(sendto(nSocket, &struReq, struReq.head.nlmsg_len, <font color="#ff40ff"><b>0</b></font>,
(<font color="#00ff00"><b>struct</b></font> sockaddr *)&struAddr, <font color="#ffff00"><b>sizeof</b></font>(struAddr)) < <font color="#ff40ff"><b>0</b></font>)
{
fprintf(<font color="#ff40ff"><b>stderr</b></font>, <font color="#ff40ff"><b>"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -