2009-09-26 9 views
18

यूडीपी हैडर struct /usr/include/netinet/udp.h में परिभाषित किया गया हैयूडीपी चेकसम गणना

struct udphdr 
{ 
    u_int16_t source; 
    u_int16_t dest; 
    u_int16_t len; 
    u_int16_t check; 
}; 

क्या मूल्य हेडर के जांच के क्षेत्र में संग्रहीत किया जाता है इस प्रकार है? चेकसम सही होने पर कैसे सत्यापित करें? मेरा मतलब है कि चेकसम की गणना किस डेटा पर की जाती है? (क्या यह सिर्फ udp हेडर या udp हेडर प्लस है जो इसके बाद पेलोड है?)

धन्यवाद।

उत्तर

27

यूडीपी चेकसम, और शीर्षक में अन्य क्षेत्रों, और IP हेडर से कुछ क्षेत्रों पूरे पेलोड से अधिक किया जाता है। गणना करने के लिए आईपी हेडर से एक छद्म-हेडर बनाया गया है (जो इस छद्म-हेडर, यूडीपी हेडर और पेलोड पर किया जाता है)। छद्म-हेडर को शामिल करने का कारण उन पैकेट को पकड़ना है जिन्हें गलत आईपी पते पर भेजा गया है।

असल में, प्राप्त करने वाले अंत में, हेडर प्लस डेटा क्षेत्र के सभी 16-बिट शब्दों को एक साथ जोड़ा जाता है (16 बिट्स पर लपेटकर) और परिणाम 0xffff के विरुद्ध चेक किया जाता है।

भेजने की तरफ, यह थोड़ा और जटिल है। एक के पूरक योग सभी 16-बिट मानों पर किया जाता है, फिर किसी के पूरक (यानी, सभी बिट्स उलटा) उस मूल्य से चेकसम फ़ील्ड को पॉप्युलेट करने के लिए लिया जाता है (अतिरिक्त शर्त के साथ कि शून्य की गणना की गई चेकस सभी में बदल दी जाएगी एक बिट)।

एक का पूरक योग केवल सभी के पूरक मूल्यों का योग है। यह थोड़ा और जटिल है।

असल में, आपके पास शून्य से शुरू होने वाला 16-बिट संचयक चल रहा है और आप उसमें प्रत्येक 16-बिट मान जोड़ते हैं। जब भी उन जोड़ों में से एक को ले जाने में परिणाम होता है, तो मूल्य चारों ओर लपेटा जाता है और आप फिर से मूल्य में एक जोड़ते हैं। यह प्रभावी ढंग से 16-बिट जोड़ के ले जाने वाला बिट लेता है और इसे मूल्य में जोड़ता है।


एक अलग रूप में के रूप में, और यह मेरा ओर से शुद्ध अनुमान है, लेकिन यह शायद कुशलतापूर्वक ADC के उपयोग के द्वारा किया जा सकता है (आश्चर्यजनक रूप से काफी जोड़ने) के बजाय ADD से (कैरी के साथ जोड़ने) अनुदेश, या उस समय आपके सीपीयू पर जो भी समकक्ष निर्देश उपलब्ध थे।

यदि कोई वाह नहीं था, ADC केवल ले जाने से शून्य बिट जोड़ देगा। उन दिनों में जब यह सामान किया गया था (और हां, दुर्भाग्यवश, मैं पूर्वाह्न पुराना), स्मृति गति से कहीं अधिक बाधा थी, आजकल इतना मामला नहीं है, इसलिए आपके कोड में कुछ बाइट्स को बचाया जा सकता है आप :-)


नोट अर्ध-देवता-सम्राट ऑफ द ब्रह्मांड के स्तर है कि आप चिंता करने के बारे में चारों ओर ले जाने के लिए दूसरी बार नहीं था (या अगले साथ दो का एक कैरी ADC यदि आप पिछले पैराग्राफ में उल्लिखित विधि का उपयोग कर रहे हैं) दो सबसे बड़े 16-बिट मानों के बाद, जब सारांशित किया जाता है, तो उत्पादन (0x1fffe से छिड़काव) 0xfffe - इसमें से एक को जोड़ने से कोई और वाह नहीं होगा।

एक बार जब गणना की गई किसी के पूरक राशि की गणना की जाती है, तो उसके बिट्स उलटा हो जाता है और पैकेट में डाला जाता है, जिससे 0xffff उत्पन्न करने के लिए प्राप्त होने वाले अंतराल की गणना होगी, पाठ्यक्रम के संचरण में कोई त्रुटि नहीं है।

यह ध्यान देने योग्य है कि पेलोड हमेशा 16-बिट शब्दों की अभिन्न संख्या सुनिश्चित करने के लिए गद्देदार होता है। यदि यह पैड किया गया था, तो लंबाई फ़ील्ड आपको वास्तविक लंबाई बताती है।

RFC768 विनिर्देश है जो यह विवरण देता है।

+0

इसके लिए धन्यवाद। मैं छद्म-हेडर भाग के बारे में थोड़ा उलझन में था .. लेकिन फिर आरएफसी ने हवा को मंजूरी दे दी। – Deepak

+1

"हेडर के सभी 16-बिट शब्द (जहां यूडीपी चेकसम शून्य है) जोड़ा जाता है और एक का पूरक (यानी, सभी बिट्स को उलटा) चेकसम क्षेत्र में डाल दिया जाता है।" नहीं, आरएफसी का कहना है कि "हेडर्स के 16-बिट शब्दों (जहां यूडीपी चेकसम शून्य है) के सभी के पूरक (यानी, सभी बिट्स को उलटाएं) को जोड़ दिया जाएगा और इसका पूरक यह है कि चेकसम क्षेत्र में। " अन्यथा सही उत्तर +1। – Joren

+1

यह सही नहीं है। "एक का पूरक योग" का मतलब यह नहीं है कि प्रत्येक शब्द का पूरक लें और उन्हें एक साथ जोड़ें। इसका मतलब है कि आप शब्दों को एक साथ जोड़ते हैं, और जब एक ले जाने वाला बिट उत्पन्न होता है, तो आप चल रहे योग में 1 जोड़ते हैं। Http://mathforum.org/library/drmath/view/54379.html देखें। –

1

मैं कुछ कोड के लिए नेट खोज रहा था जो udp शीर्षलेख की गणना करेगा (उपरोक्त वर्णित छद्म आईपी हेडर के साथ)।

अंत में मैंने पाया खुले bsd dhclient packet.c:

https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sbin/dhclient/packet.c

जांच समारोह assemble_udp_ip_header()

1

अच्छा और यूडीपी चेकसम गणना का उदाहरण समझने में आसान गर्ड हॉफमन द्वारा किया जाता है ।

आप "नेट checksum.c गर्ड हॉफमन" के लिए गूगल कर सकते हैं या फ़ाइल यहाँ देखो:

https://gist.github.com/fxlv/81209bbd150abfeaceb1f85ff076c9f3

आप net_checksum_tcpudp समारोह का उपयोग कर सकते हैं, यह यूडीपी पेलोड लंबाई फ़ीड, आद्य, src और डीएसपी आईपी और फिर यूडीपी पेलोड स्वयं और यह सही काम करेगा।

अंत में आपको चेकसम पर htons() पर कॉल करना होगा और आप अच्छे हैं।

संबंधित मुद्दे