2012-11-27 21 views
5

में sk_buff पैकेट के सभी पेलोड को संसाधित करने का सही तरीका क्या है, मैं वर्तमान में एक एटीएम encapsulation परत डीबग करने की कोशिश कर रहा हूं जो ईथरनेट के शीर्ष पर चलता है। मूल रूप से एटीएम कोशिकाएं ईथरनेट हेडर के बाद व्यवस्थित होती हैं। हालांकि मुझे संदेह है कि ड्राइवर sk_buffs के लिए बेवकूफ दृष्टिकोण टूट गया है।लिनक्स

चालक आँख बंद करके मानता है कि skb-> डेटा के माध्यम से लेकिन virtio_net.c के लिए कर्नेल कोड को देख दोहराया जा सकता है: page_to_skb मैं निम्नलिखित व्यवहार देखें: पर आगे फिर

memcpy(hdr, p, hdr_len); 
len -= hdr_len; 
p += offset; 
copy = len; 

if (copy > skb_tailroom(skb)) 
     copy = skb_tailroom(skb); 

memcpy(skb_put(skb, copy), p, copy); 

:

while (len) { 
     set_skb_frag(skb, page, offset, &len); 
    page = (struct page *)page->private; 
    offset = 0; 
} 

जो दिखाता है कि बफर को केवल पहले भाग को स्कैब-> डेटा से सीधे पहुंचने के साथ खंडित किया गया है।

अंतर्निहित डेटा प्राप्त करने के लिए मुझे क्या उपयोग करना चाहिए। आदर्श रूप से मैं एक पुनर्विक्रय बफर में रखे टुकड़ों को याद करने से पहले ईथरनेट पैकेट में मनमाने ढंग से ऑफसेट पर कुछ बाइट्स देखना चाहता हूं। ऐसा करने के लिए मुझे क्या उपयोग करना चाहिए?

उत्तर

7

सॉकेट बफर के कार्यान्वयन में रैखिक डेटा बफर और एक या अधिक पृष्ठ बफर शामिल हैं।

सॉकेट बफर में पेज किए गए डेटा का अस्तित्व skb->data_len सदस्य गैर-शून्य होने का संकेत है।

bool skb_is_nonlinear(const struct sk_buff *skb)/include/linux/skbuff.h में परिभाषित इस परीक्षण के लिए प्रयोग किया जाता है।

skb-> डेटा पर गैर-पेज किए गए डेटा की मात्रा को skb-> len-skb-> data_len के रूप में गणना की जा सकती है। unsigned int skb_headlen(const struct sk_buff *skb)/include/linux/skbuff.h में परिभाषित इस परीक्षण के लिए प्रयोग किया जाता है।

skb->data पॉइंटर केवल गैर पेज किए गए डेटा को इंगित करता है, जो आपके द्वारा वर्णित ड्राइवर संभवतः निर्भर करता है।

void *skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer)/include/linux/skbuff.h में परिभाषित किया गया है। यह सॉकेट बफर, बाइट ऑफ़सेट और बाइट लंबाई आपकी इच्छित और एक स्थानीय डेटा बफर लेता है जिसका उपयोग केवल तभी किया जाता है जब डेटा पृष्ठ बफर में से एक में होता है।

यह skb->data से रेखीय डेटा बफर में या तो डेटा या आपूर्ति की स्थानीय डेटा बफर करने के लिए सूचक, या शून्य करने के लिए एक सूचक लौटाता है यदि आपके ऑफसेट और लंबाई गलत थे।

प्रोटोकॉल हेडर से बड़ा डेटा के टुकड़े के लिए आप या तो

int skb_copy_bits(const struct sk_buff *skb, int offset,void *to, int len);

उपयोग करने के लिए किसी दिए गए सॉकेट बफर, बाइट ऑफसेट और बाइट लंबाई एक दिया कर्नेल बफर करने से प्रतिलिपि बनाना चाहते हैं।

या

int skb_copy_datagram_iovec(const struct sk_buff *from, int offset, struct iovec *to, int size);

किसी दिए गए सॉकेट बफर से कॉपी करने के लिए करने के लिए, बाइट ऑफसेट और उपयोगकर्ता अंतरिक्ष में एक iovec दिया संरचना करने के लिए बाइट लंबाई।

नेटफिल्टर कोड और अन्य ईथरनेट ड्राइवरों में उपयोग के उदाहरण देखे जा सकते हैं।

अधिक जानकारी के लिए

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

  • कोई संबंधित समस्या नहीं^_^