2015-05-09 52 views
1

我已經使用netfiler_queueiptables創建了一個NFQUEUE模塊,該模塊處理所有出站的UDP數據包。在netfilter模塊中重新注入修改的數據包

我想修改所有匹配特定模式的UDP數據包,並將它們重新輸入到網絡中。

下面是一些示例代碼:

... 

static int Callback(nfq_q_handle *myQueue, struct nfgenmsg *msg, nfq_data *pkt, void *cbData) { 
    uint32_t id = 0; 
    nfqnl_msg_packet_hdr *header; 

    if ((header = nfq_get_msg_packet_hdr(pkt))) { 
    id = ntohl(header->packet_id); 
    } 

    // Get the packet payload 
    unsigned char *pktData; 
    int len = nfq_get_payload(pkt, &pktData); 

    // The following is an example. 
    // In reality, it involves more parsing of the packet payload. 
    if (len && pktData[40] == 'X') { 
    // Modify byte 40 
    pktData[40] = 'Y'; 
    } 

    // Pass through the (modified) packet. 
    return nfq_set_verdict(myQueue, id, NF_ACCEPT, 0, NULL); 
} 

... 

int main(){ 

    ... 

    struct nfq_handle nfqHandle; 
    nfq_create_queue(nfqHandle, 0, &Callback, NULL) 

    ... 

    return 0; 
} 

修改的數據包並沒有得到重新注入流。我將如何注入數據包的修改版本?

+0

示例代碼純粹是一個示例,將其視爲僞代碼。 – Excl

回答

3

兩件事。第一:

return nfq_set_verdict(myQueue, id, NF_ACCEPT, 0, NULL); 

應該是:

return nfq_set_verdict(myQueue, id, NF_ACCEPT, len, pktData); 

,告訴它你要發送一個修改的數據包。 (你可能需要一些類型轉換)

其次,你只是修改了數據包。在這一點上IP堆棧不再幫助你,所以你需要重新計算該數據包的UDP校驗和,將其歸零,所以另一端甚至不會檢查它。

UDP校驗將生活在字節0x1A和你的包0x1B,因此這將歸零出來:

pktData[0x1a] = 0; 
pktData[0x1b] = 0; 

,然後你的數據包將經歷。

+0

如何在這種情況下重新計算校驗和? – Excl

+0

更具體地說,我如何使用通用校驗和計算函數並將其插入到這兩個腳本中? – Excl

+1

你不能使用通用的,你必須使用UDP校驗和功能。它在RFC768,http://tools.ietf.org/html/rfc768和維基百科上有描述,http://en.wikipedia.org/wiki/User_Datagram_Protocol#Checksum_computation –