linux IP QUEUE機制應用層程式設計

2021-06-15 06:40:20 字數 3153 閱讀 3290

linux核心在netfilter框架的基礎上提供了ip queue機制,從而使得基於使用者態的防火牆開發成為可能。從而可以在使用者態對報文內容進行分析,同時可以給出對這個報文的處理意見,也可以修改報文。

簡單介紹一下nf中各個鉤子(hook)函式對資料報處理的返回值,即該函式告訴核心對該資料報的處理意見。

nf_accept: 接受該報文,並繼續處理;

nf_stolen: 該報文已經被hook函式接管,協議棧無須繼續處理;

nf_queue: 將該報文傳遞到使用者態去做進一步的處理;

nf_repeat: 再次呼叫本hook函式。

當hook處理函式返回值為nf_queue時,核心協議棧將通過ip queue機制把當前報文傳遞到使用者態,由使用者態的應用程式進行處理。這樣,只要能夠在相應的hook點上返回nf_queue值,就可以將符合要求的報文傳送到使用者態去做進一步對報文行處理。隨後,使用者態程式會將處理後的報文以及對報文的處理意見(accept,drop等)傳遞給核心協議棧。核心協議棧就會按照使用者態對報文的處理意見將報文做接受、丟棄等處理。整個處理的過程就相當於乙個使用者態的防火牆,所有資料報的實質性處理都放在使用者態進行。這樣,即使是不具有深入核心知識的開發人員,也可以開發出適應一定應用場合的使用者態防火牆。

基於以上的介紹可以大致講一下應用層程式設計實現防火牆的流程:核心和應用層之間的通訊以及報文的傳輸採用netlink套接字來實現。使用者態可以通過iptables來決定哪一類報文將要傳送到應用層(採用iptables的queue任務,如iptables -t mangle -a forward  -j queue,則所有匹配到這條規則的報文都將通過ip_queue傳送到使用者空間),而應用層通過對報文的分析和處理最終返回乙個處理意見給核心,返回的值同上面的hook函式返回值一樣,可以是其中的一種。

下面是乙個簡單的應用層獲獲取核心報文的實現:

#include #include #include #include #include #include #include #include #include #include /*ip_queue主要資料結構標頭檔案*/

#include#define val_len 1024

#define rs_ok 0

#define rs_wrong -1

typedef unsigned int u32;

/* 應用層傳送到核心的報文的二種模式。

*/enum ;

/* 應用層返回給核心的幾種報文的處理意見

*/enum ;

typedef struct ipq_hand ipqhander;

/* 應用層請求核心報文頭部

*/struct req_head ;

struct ipq_hand *ipqh;

/*建立netlink套接字,並初始化*/

int create_ipqueue_hander()

memset(ipqh, 0, sizeof(struct ipq_hand));

ipqh->ipqfd = socket(pf_netlink, sock_raw, netlink_firewall);

if (ipqh->ipqfd == -1)

memset(&ipqh->local,0, sizeof(ipqh->local));

ipqh->local.nl_family = af_netlink;

ipqh->local.nl_pid = getpid();

ipqh->local.nl_groups = 0;

memset(&ipqh->peer, 0, sizeof(ipqh->peer));

ipqh->peer.nl_family = af_netlink;

ipqh->peer.nl_pid = 0;

ipqh->peer.nl_groups = 0;

if(bind(ipqh->ipqfd, (struct sockaddr *)&(ipqh->local), sizeof (ipqh->local)))

return rs_ok;

}/*向核心傳送訊息,包括二種,一種為模式設定,一種為返回處理意見*/

int send_msg_to_kernel(u32 msgtype, ipq_packet_msg_t *m, u32 verdict)

ret = sendto(ipqh->ipqfd, &req, sizeof(req), 0, (struct sockaddr *)&ipqh->peer, sizeof(ipqh->peer));

if (ret == -1)

return rs_ok;

}/*從核心接收訊息*/

int recv_msg_from_kernel()

else

}

if (!fd_isset(ipqh->ipqfd, &read_fds))

continue;

memset(buf, 0, sizeof(buf));

status = recvfrom(ipqh->ipqfd, buf, val_len, 0, null, null);

if (status < 0)

if (status == 0)

nlh = (struct nlmsghdr *)buf;

if (nlh->nlmsg_flags & msg_trunc || nlh->nlmsg_len > status)

packet = nlmsg_data((struct nlmsghdr *)(buf));

printf("recv bytes =%d, nlmsg_len=%d, indev=%s, datalen=%d, packet_id=%x\n", status, nlh->nlmsg_len,

packet->indev_name, packet->data_len, (u32)packet->packet_id);

if (send_msg_to_kernel(return_ide, packet, nf_accept))

}return rs_ok;

}int main(int argc, char *argv)

if (send_msg_to_kernel(set_mode, null, 0))

recv_msg_from_kernel();

return 0;

}

LRU是什麼?LRU快取淘汰機制的原理和應用

rul是一種快取淘汰演算法,是一種快取淘汰機制 快取分為兩種 硬體的快取和軟體的快取 硬體的快取也是cpu快取,是位於cpu和記憶體之間的臨時的儲存器,包括一級快取,二級快取,快取 軟體的快取包括記憶體快取,資料庫快取和 網路快取 瀏覽器快取 等等 大家都知道,快取不是無限的資源,甚至是稀缺的。那麼...

Silverlight Caliburn應用框架2

silverlight caliburn應用框架1 silverlight caliburn應用框架2 silverlight caliburn應用框架3 silverlight caliburn應用框架4 silverlight caliburn應用框架5 silverlight caliburn...

FormsAuthentication應用之登入

配置項描述 name aspxauth loginurl login.aspx defaulturl default.aspx protection all timeout 30 path requiressl false slidingexpiration false cookieless use...