2010-08-19 10 views
10

मैं POSIXy C++ में परत 2 पैकेट कैसे प्राप्त करूं? पैकेट में केवल src और dst मैक पता, प्रकार/लंबाई, और कस्टम स्वरूपित डेटा है। वे टीसीपी या यूडीपी या आईपी या आईजीएमपी या एआरपी या जो कुछ भी नहीं हैं - वे हार्डवेयर लोगों द्वारा मुझे दिए गए घर-निर्मित प्रारूप हैं।मैं सी/सी ++ में कच्चे, परत 2 पैकेट कैसे प्राप्त करूं?

मेरा socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW) कभी भी recvfrom() से वापस नहीं आता है।

मैं ठीक भेज सकता हूं, मुझे कोई फर्क नहीं पड़ता कि मैं नेटवर्क स्टैक पर किस विकल्प को घुमाता हूं।

(प्लेटफार्म VxWorks है, लेकिन मैं इसे POSIX या लिनक्स या जो कुछ भी ... अनुवाद कर सकते हैं)

कोड (वर्तमान अवतार) प्राप्त करते हैं:

int s; 

if ((s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) { 
    printf("socket create error."); 
     return -1; 
} 

    struct ifreq   _ifr; 
    strncpy(_ifr.ifr_name, "lltemac0", strlen("lltemac0")); 
    ioctl(s, IP_SIOCGIFINDEX, &_ifr); 

    struct sockaddr_ll _sockAttrib; 
    memset(&_sockAttrib, 0, sizeof(_sockAttrib)); 
    _sockAttrib.sll_len  = sizeof(_sockAttrib); 
    _sockAttrib.sll_family = AF_PACKET; 
    _sockAttrib.sll_protocol = IFT_ETHER; 
    _sockAttrib.sll_ifindex = _ifr.ifr_ifindex; 
    _sockAttrib.sll_hatype = 0xFFFF; 
    _sockAttrib.sll_pkttype = PACKET_HOST; 
    _sockAttrib.sll_halen = 6; 
    _sockAttrib.sll_addr[0] = 0x00; 
    _sockAttrib.sll_addr[1] = 0x02; 
    _sockAttrib.sll_addr[2] = 0x03; 
    _sockAttrib.sll_addr[3] = 0x12; 
    _sockAttrib.sll_addr[4] = 0x34; 
    _sockAttrib.sll_addr[5] = 0x56; 
    int _sockAttribLen = sizeof(_sockAttrib); 


char packet[64]; 
memset(packet, 0, sizeof(packet)); 

    if (recvfrom(s, (char *)packet, sizeof(packet), 0, 
       (struct sockaddr *)&_sockAttrib, &_sockAttribLen) < 0) 
    { 
     printf("packet receive error."); 
    } 

    // code never reaches here 
+0

बहुत बढ़िया सवाल! –

+1

मुझे खुशी है कि आपने इस पॉज़िक्स को टैग किया है, शुभकामनाएं विंडोज पर ऐसा करने की कोशिश कर रही हैं;) –

+0

बस एक नाइटपिक: POSIX सी ++ बाइंडिंग को परिभाषित नहीं करता है, केवल सी –

उत्तर

4

मुझे लगता है कि ऐसा करने का तरीका अपनी खुद की नेटवर्क सेवा लिखना है जो VxWorks नेटवर्क स्टैक में एमयूएक्स परत से जुड़ा हुआ है। यह VxWorks नेटवर्क प्रोग्रामर गाइड और कुछ बार मैंने कई बार किया है, यह उचित रूप से अच्छी तरह से प्रलेखित है।

MUX_PROTO_SNARF सेवा प्रकार का उपयोग कर नेटवर्क इंटरफ़ेस पर प्राप्त सभी परत 2 पैकेट देखने के लिए एक कस्टम नेटवर्क सेवा कॉन्फ़िगर किया जा सकता है, इस प्रकार पवन नदी का स्वयं का डब्लूडीबी प्रोटोकॉल काम करता है, या एक विशिष्ट प्रोटोकॉल प्रकार के साथ पैकेट।

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

आप VxWorks का कौन सा संस्करण उपयोग कर रहे हैं नहीं कहा, लेकिन मैं इसके बाद के संस्करण VxWorks 5.5.x और 6.x

+0

धन्यवाद। मैं आलसी मार्ग चला गया और नेटवर्क स्टैक में आने से पहले पैकेट को Xilinx कोड से कॉपी किया। आपका रास्ता होगा ... आलसी नहीं, अनुसूची के पीछे नहीं ... :) – spydez

3

आप के रूप में सॉकेट प्रोटोकॉल स्थापित करने की कोशिश की htons(ETH_P_ALL) किया है packet(7) में निर्धारित? आप जो कर रहे हैं उसके पास आईपी के साथ बहुत कुछ नहीं है (हालांकि IPPROTO_RAW कुछ वाइल्डकार्ड मान हो सकता है, डुनो)

+0

सही उत्तर - 'सॉकेट()' को पारित प्रोटोकॉल 'IPPROTO_RAW' नहीं होना चाहिए, यह ईथरनेट होना चाहिए (802.3) नेटवर्क-बाइट-ऑर्डर में, आपके कस्टम प्रोटोकॉल के लिए प्रोटोकॉल आईडी। – caf

+0

धन्यवाद। आप सही हैं लेकिन यह अभी भी काम नहीं करता है। – spydez

+0

शायद मैन पेज पढ़ना शुरू करें और वहां पर अनुमान लगाए गए किसी भी तर्क की जांच करें। – mvds

1

मुझे लगता है कि यह अपेक्षा करने के लिए हल करने में थोड़ा मुश्किल समस्या होगी। यह देखते हुए कि यह आईपी बिल्कुल नहीं है (या स्पष्ट रूप से कोई अन्य प्रोटोकॉल कुछ भी पहचान लेगा), मुझे नहीं लगता कि आप पूरी तरह से उपयोगकर्ता-स्तर कोड के साथ अपनी समस्या को हल करने में सक्षम होंगे। लिनक्स पर, मुझे लगता है कि आपको अपना खुद का device agnostic interface ड्राइवर लिखना होगा (शायद NAPI का उपयोग करना)। इसे VxWorks के तहत काम करने के लिए लगभग निश्चित रूप से गैर-तुच्छ (अधिकतर लोग एक बंदरगाह के रूप में सोचने वाले लोगों की तुलना में ग्राउंड-अप से पूर्ण पुनर्लेखन की तरह) होंगे।

0

क्या आपने वायरशर्क के माध्यम से पुष्टि करने की कोशिश की है कि वास्तव में एक पैकेट को दूसरे छोर से भेजा गया है?

इसके अलावा, डिबगिंग के लिए, अपने हार्डवेयर लोगों से पूछें कि क्या उनके पास डीबग पिन है (आप एक तर्क विश्लेषक से संलग्न कर सकते हैं) कि वे एक पैकेट प्राप्त करते समय जोर दे सकते हैं। बस यह सुनिश्चित करने के लिए कि हार्डवेयर पैकेट ठीक हो रहा है।

+0

यह सब एक एफपीजीए के अंदर है, इसलिए इसे शार्क नहीं किया जा सकता है। एचडब्ल्यू का कहना है कि यह काम करता है, इसलिए मुझे इसके साथ अभी जाना है। – spydez

0

पहले के लिए रखती है लगता है, ताकि आपके इंटरफ़ेस सब हो जाता है आप ETH_P_ALL के रूप में प्रोटोकॉल निर्दिष्ट करने की आवश्यकता पैकेट। अपनी सॉकेट को विचित्र मोड पर सेट करें। फिर प्राप्त करने से पहले अपने रॉ सॉकेट को एक इंटरफेस में बांधें।

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