2011-04-16 11 views
5

मैं कच्चे सॉकेट का अध्ययन कर रहा हूं। मैंने अपने आईपी हेडर बनाने के लिए आईपी_एचडीआरआईएनसीएल विकल्प का इस्तेमाल किया। आईपी ​​हेडर के बाद, मैं एक यूडीपी हेडर बना रहा हूं। फिर मैं अपने सिस्टम के लूपबैक पते पर पैकेट भेज रहा हूं। मेरे पास एक और प्रोग्राम चल रहा है जो यूडीपी पैकेट को पकड़ने के बाद पकड़ लेगा। यह जांचने के लिए कि पैकेट सही ढंग से गठित और प्राप्त किए जा रहे हैं, मेरे पास एक और प्रक्रिया चल रही है जो कच्चे आईपी डेटाग्राम पढ़ रहा है। मेरी समस्या यह है कि हालांकि दूसरी प्रक्रिया (कच्चे डेटाग्राम पढ़ने) अच्छी तरह से काम कर रही है (सभी आईपी और यूडीपी फ़ील्ड ठीक लगते हैं), लेकिन पहली प्रक्रिया (यूडीपी प्राप्त करना) मेरे द्वारा बनाए गए किसी भी पैकेट को प्राप्त नहीं कर रहा है। आईपी ​​हेडर में प्रोटोकॉल फ़ील्ड ठीक है और पोर्ट भी मेल खाता है ... मैं लिनक्स 2.6.35-22 का उपयोग कर रहा हूं। मैं जानना चाहता हूं कि यह नए कर्नेल में सामान्य है या नहीं? कृपया किसी भी बग के लिए नीचे दिए गए कोड को चेक करें। यूडीपी प्रक्रिया है जो पैकेट प्राप्त करना चाहिए एक सॉकेट एक ही मशीन पर पोर्ट 50000 के लिए बाध्य पर सुन रहा है ...रॉ सॉकेट सहायता: कच्चे सॉकेट द्वारा बनाए गए यूडीपी पैकेट कर्नेल यूडीपी द्वारा क्यों प्राप्त नहीं किए जा रहे हैं?

unsigned short in_cksum(unsigned short *addr, int len) 
{ 
    int nleft = len; 
    int sum = 0; 
    unsigned short *w = addr; 
    unsigned short answer = 0; 

    while (nleft > 1) { 
     sum += *w++; 
     nleft -= 2; 
    } 

    if (nleft == 1) { 
     *(unsigned char *) (&answer) = *(unsigned char *) w; 
     sum += answer; 
    } 

    sum = (sum >> 16) + (sum & 0xFFFF); 
    sum += (sum >> 16); 
    answer = ~sum; 
    return (answer); 
} 


main() 
{ 
    int fd=socket(AF_INET,SOCK_RAW,IPPROTO_UDP); 

    int val=1; 

    int ret=setsockopt(fd,IPPROTO_IP,IP_HDRINCL,&val,sizeof(val)); 

    char buf[8192]; 

    /* create a IP header */ 

    struct iphdr* ip=(struct iphdr*)buf;//(struct iphdr*) malloc(sizeof(struct iphdr)); 

    ip->version=4; 
    ip->ihl=5; 
    ip->tos=0; 
    ip->id=0; 
    ip->frag_off=0; 
    ip->ttl=255; 
    ip->protocol=IPPROTO_UDP; 
    ip->check=0; 
    ip->saddr=inet_addr("1.2.3.4"); 
    ip->daddr=inet_addr("127.0.0.1"); 


    struct udphdr* udp=(struct udphdr*)(buf+sizeof(struct iphdr));//(struct udphdr*) malloc(sizeof(struct udphdr)); 
    udp->source=htons(40000); 
    udp->dest=htons(50000); 
    udp->check=0; 
    char* data=(char*)buf+sizeof(struct iphdr)+sizeof(struct udphdr);strcpy(data,"Harry Potter and the Philosopher's Stone"); 
    udp->len=htons(sizeof(struct udphdr)+strlen(data)); 
    udp->check=in_cksum((unsigned short*) udp,8+strlen(data)); 

    ip->tot_len=htons(sizeof(struct iphdr)+sizeof(struct udphdr)+strlen(data)); 

    struct sockaddr_in d; 
    bzero(&d,sizeof(d)); 
    d.sin_family=AF_INET; 
    d.sin_port=htons(50000); 
    inet_pton(AF_INET,"localhost",&d.sin_addr.s_addr); 
    while(1) 
    sendto(fd,buf,sizeof(struct iphdr)+sizeof(struct udphdr)+strlen(data),0,(struct sockaddr*) &d,sizeof(d)); 
} 
+1

आग अप wireshark। क्या वे तार भी मार रहे हैं? – rook

+0

हां वे हैं ... और यह यूपीपी, गंतव्य पोर्ट 50000 के रूप में प्रोटोकॉल को सही ढंग से दिखा रहा है। लेकिन, स्रोत पोर्ट को "saftynetp" के रूप में लेबल किया जा रहा है। इसमें 40000 का सही मूल्य है लेकिन मुझे नहीं पता कि इसका अर्थ क्या है – pflz

+2

सामाजिक या कुछ द्वारा प्रेषित वास्तविक यूडीपी पैकेट को कैप्चर करें और फिर एक समान पैकेट को आजमाएं और फोर्ज करें। चेकसम सहित सबकुछ जांचना सुनिश्चित करें। पैकेट डंप पर मिश्रित एक diff प्रोग्राम चलाना अच्छी तरह से काम करता है। – rook

उत्तर

0

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

3

यूडीपी चेक-योग की गणना के साथ एक समस्या प्रतीत होती है।

udp->check=in_cksum((unsigned short*) udp,8+strlen(data)); 

यूडीपी चेक-योग में यूडीपी हेडर से पहले "छद्म-शीर्षलेख" नामक कुछ शामिल होना चाहिए। कोड केवल यूडीपी हेडर और पेलोड पर चेकसम की गणना करता है। यूडीपी प्राप्त करने की प्रक्रिया गलत चेक-रकम के कारण पैकेट नहीं मिल रही है।

वायरसहार्क में चेक-योग सत्यापन सक्षम करें और जांचें कि यूडीपी पैकेट के चेक-योग फ़ील्ड सही हैं या नहीं।

निम्नलिखित देखें:

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