2012-07-10 17 views
7

की गणना कैसे करें मैं एक कर्नेल मॉड्यूल लिख रहा हूं जो कुछ टीसीपी हेडर जानकारी को संशोधित करने के लिए नेटफिल्टर हुक का उपयोग करता है और जाहिर है, भेजने से पहले, मैं चेकसम की फिर से गणना करना चाहता हूं।
मैं प्राप्तकर्ता पक्ष में शीर्षलेख भी संपादित करता हूं, इसलिए मुझे इसे फिर से गणना करने की आवश्यकता है।टीसीपी चेकसम

ऑनलाइन खोजना, मुझे कुछ लोगों ने कहा कि मैं इसे आसानी से 0 पर सेट कर सकता हूं और इसकी गणना मेरे लिए की जाएगी, जाहिर है कि काम नहीं किया।
मैं हालांकि कोई भी स्पष्ट किया है कि यह कैसे किया जाता है, और क्या मैं वास्तव में/प्राप्त पर उपयोग कर सकते हैं उसी तरह भेजने के भी इस समारोह

tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); 

पाया है।
मेरा अपना प्रयास चेकसम को 0 पर सेट करना था, फिर इस फ़ंक्शन को मेरे पास स्कैब पास करना और skb-> sk मेरे पास है, अभी भी कुछ भी नहीं है।

तो कृपया, टीसीपी डेटाग्राम के चेकसम की गणना करने का एक सीधा तरीका क्या है?

+0

वास्तव में क्या आप 0 पर सेट किया था और जहां चेकसम पाने की उम्मीद की थी? कोड को देखते हुए, आपको tcp_hdr (skb) सेट करना चाहिए -> 0 पर जांचें, फिर फ़ंक्शन को कॉल करें और उसके बाद नया चेकसम वहां होना चाहिए। – BjoernD

+0

और यह वही है जो मैंने किया था, फिर भी जब मैंने मॉड्यूल लोड किया तो सभी टीसीपी कनेक्शन बस काम नहीं करते थे। – Fingolfin

+0

आपको शायद प्रश्न में 'सी' टैग जोड़ना चाहिए। बीटीडब्ल्यू, http://www.winpcap.org/pipermail/winpcap-users/2007-July/001984.html – Jite

उत्तर

3

चेकसम की पुन: गणना करने के लिए, आप एक वृद्धिशील चेकसम की बेहतर गणना करते हैं - पूरे पैकेट को पढ़ने के बजाय, आपके द्वारा बदले गए फ़ील्ड के आधार पर मौजूदा चेकसम को संशोधित करें।

यह पैकेट बदलते समय किया जाना चाहिए, जब आप पुराने मूल्यों और आपके द्वारा संग्रहीत नए मूल्यों को जानते हैं।

मूल विचार tcp->check += (new_val - old_val) है।
यह इससे थोड़ा अधिक जटिल है, क्योंकि:
1. old_val और new_val 16-बिट मान होने की आवश्यकता है, जो 2 बाइट्स (जैसे पोर्ट नंबर बदलना) पर गठबंधन हैं।
2. चेकसम एक अंकगणितीय पूरक का उपयोग करता है, इसलिए आपको "प्रतिक्रिया लेना" करना होगा। इसका मूल रूप से अर्थ है कि यदि tcp->check + new_val - old_val ऋणात्मक है, तो आपको परिणाम से 1 घटाना होगा।

http://www.linuxvirtualserver.org/software/tcpsp/index.html

tcpsp_core.c बुलाया फ़ाइल में देखो:

+1

यह करने का यह सही तरीका है। यह तेज़ है और डेटा भ्रष्टाचार का कम जोखिम है। स्क्रैच से चेकसम को दोबारा करने से किसी भी भ्रष्टाचार को मास्क करने का खतरा होता है जो डेटा से पहले ही हुआ था। – kasperd

1

यहाँ एक उदाहरण है जो टीसीपी (नहीं आईपी) के लिए नेटफिल्टर एपीआई + चेकसम गठबंधन है।

th->check = 0; 
    th->check = csum_tcpudp_magic(iph->saddr, iph->daddr, 
            datalen, iph->protocol, 
            csum_partial((char *)th, datalen, 0)); 
    skb->ip_summed = CHECKSUM_UNNECESSARY; 

(यह नोटिस असाइन किया गया है शून्य पहले चेकसम गणना की है, तो आईपी checksum रूप में की जरूरत नहीं दर्शाया गया है)।

जो नेटफिल्टर मॉड्यूल यू लोड पर निर्भर करता है (वहाँ कई हैं !!!) वे अलग परत, जैसे, iptable IP परत पर काम पर काम करेंगे नीचे दिखाया गया है (छवि):

http://ars.sciencedirect.com/content/image/1-s2.0-S1389128608004040-gr3.jpg

1

@ यूगोरन का जवाब सटीक नहीं है। आरएफसी 1624 https://tools.ietf.org/html/rfc1624 के अनुसार, यह कभी-कभी -0 (0xFFFF) उत्पन्न करेगा, जिसकी अनुमति नहीं है।

चेकसम गणना करने के लिए किया जाना चाहिए सही तरीका: new_tcp_check = ~(~old_tcp_check + ~old_val + new_val)