2014-10-15 9 views
5

स्थानांतरण मैं मॉड्यूल Net::Pcap::Easy के लिए कुछ उदाहरण कोड का टुकड़ा पढ़ रहा था, और मैं, कोडपर्ल बिटवाइज़ और और बिटवाइज़

my $l3protlen = ord substr $raw_bytes, 14, 1; 
my $l3prot = $l3protlen & 0xf0 >> 2; # the protocol part 
return unless $l3prot == 4; # return unless IPv4 
my $l4prot = ord substr $packet, 23, 1; 
return unless $l4prot == '7'; 

के इस टुकड़े में आए कच्चे पैकेट $ raw_bytes की कुल हेक्स डंप करने के बाद मैं देख सकते हैं कि यह एक ईथरनेट फ्रेम है, न कि टीसीपी/यूडीपी पैकेट पर। क्या कोई बता सकता है कि उपर्युक्त कोड क्या करता है?

उत्तर

7

फ्रेम को पार्स करने के लिए, मैंने this page देखा।

अब पर्ल पर ...

my $l3protlen = ord substr $raw_bytes, 14, 1; 

$raw_bytes से 15 बाइट (चरित्र) निकालें, और उसके क्रमसूचक मूल्य (जैसे एक चरित्र में बदलने का 'ए' एक पूर्णांक 65 में रूपांतरित हो जाएगा (0x41), मानते हुए कि चरित्र सेट ASCII है)। इस प्रकार पर्ल बाइनरी डेटा को संभाल सकता है जैसे कि यह एक स्ट्रिंग था (उदा। इसे substr पर पास करना) लेकिन फिर आपको द्विआधारी मूल्यों को वापस पाने और उन्हें संख्याओं के रूप में संभालने दें। (लेकिन TMTOWTDI याद रखें।)

आईपीवी 4 फ्रेम में, पहले 14 बाइट मैक हेडर (गंतव्य और स्रोत मैक पते के लिए प्रत्येक 6 बाइट्स हैं, इसके बाद 2-बाइट ईथरटाइप जो शायद 0x8000 था - आप इसे चेक कर सकते थे)। इसके बाद, 15 वीं बाइट ईथरनेट डेटा पेलोड की शुरुआत है: इसमें पहले बाइट में संस्करण (ऊपरी 4 बाइट्स) और शीर्षलेख लंबाई DWORDs (कम 4 बाइट्स) है।

अब मुझे लगता है कि इस नमूना कोड की अगली पंक्ति में एक बग है, लेकिन यह आमतौर पर एक झुकाव से काम कर सकता है!

my $l3prot = $l3protlen & 0xf0 >> 2; # the protocol part 

पर्ल में, >>& की तुलना में अधिक पूर्वता है, तो इस

my $l3prot = $l3protlen & (0xf0 >> 2); 

के बराबर होगी या यदि आप

my $l3prot = $l3protlen & 0x3c; 

पसंद करते हैं तो यह बिट्स 2 निकालता है - 5 से $l3prot मूल्य: मास्क मान 0x3c बाइनरी में 0011 1100 है। तो उदाहरण के लिए 0x86 (बाइनरी में, 1000 0110) का मान 0x04 (बाइनरी 0000 0100) बन जाएगा। वास्तव में एक 'सामान्य' आईपीवी 4 मान 0x45 है, यानी प्रोटोकॉल प्रकार 4, हेडर लम्बाई 5 पासवर्ड। मास्क कि 0x3c के साथ और आप ... 4! लेकिन केवल झुकाव से: आपने लंबाई के शीर्ष 2 बिट्स का परीक्षण किया है, न कि प्रोटोकॉल प्रकार!

इस लाइन निश्चित रूप से

my $l3prot = ($l3protlen & 0xf0) >> 4; 

(पूर्वता के लिए टिप्पणी कोष्ठक और 4 बिट्स, नहीं 2 की एक पारी) होना चाहिए। (मैं CPAN documentation में यह वही गलती पाया इसलिए मुझे लगता है कि यह शायद काफी व्यापक रूप से फैला है।)

return unless $l3prot == 4; # return unless IPv4 

IPv4 के लिए हम उम्मीद करते हैं इस मान को 4 होने के लिए - अगर यह नहीं है, समारोह से बाहर कूद सही दूर। (तो गलत कोड से ऊपर परिणाम जो इस एक IPv4 पैकेट के रूप में व्याख्या की जा है, लेकिन केवल भाग्य द्वारा की सुविधा देता है देता है।)

my $l4prot = ord substr $packet, 23, 1; 

अब 24 बाइट निकालने और उसी तरह से क्रमसूचक मूल्य में बदलने का।इस IP हेडर से प्रोटोकॉल बाइट है:

return unless $l4prot == '7'; 

हम इस 7 होने की उम्मीद - अगर यह समारोह से बाहर कूद नहीं है अभी। (IANA के अनुसार, 7 "कोर-आधारित पेड़" है ... लेकिन मुझे लगता है कि आप जानते हैं कि आप किस प्रोटोकॉल में रुचि रखते हैं!)

+0

बहुत अच्छी तरह से समझाया गया। हाँ, मैं विशेष रूप से udp के लिए देख रहा था, इसलिए 7. – nohup

+1

@ नोहुप - धन्यवाद! लेकिन यूडीपी 17 है, न कि 7 ... क्या आपने इसे "' 0xf0' "लाइन में सुझाए गए सुधार के साथ भी कोशिश की है? – AAT

+0

उत्कृष्ट और अच्छी तरह से समझाया गया। अच्छी गलतियों को उन गलतियों को खोजना –

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