בעיה בשליחת חבילות inet raw
-
עשיתי שרת udp שמקבל מערך של בתים שמייצג חבילות raw והוא צריך לשלוח את זה לרשת בצורה של raw.
עכשיו הבעיה שזה שולח חבילות dns אז אחרי זה הקרנל משנה את הפורט מקור מ53 ל1.#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <linux/types.h> #include <errno.h> #include <limits.h> #include <netinet/udp.h> #include <netinet/ip.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <arpa/inet.h> void printBufHex(unsigned char* buf,int len){ int i; for(i = 0;i<len;i++){ printf("0x%02x ,",buf[i]); if((i%16) == 16-1) printf("\n"); } printf("\n"); } int main(int argc, char**argv) { int sockfd,n; int raw_socket; struct sockaddr_in servaddr,cliaddr; socklen_t len; char mesg[10000]; sockfd =socket(AF_INET,SOCK_DGRAM,0); raw_socket = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr("127.0.7.7"); servaddr.sin_port=htons(7777); bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); //int flag = 0; //int setsockoptr = setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL, &flag, sizeof(flag)); //printf(">>>>>> setsockoptr %d \n",setsockoptr); for (;;) { len = sizeof(cliaddr); n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len); struct iphdr *out_ip_header = (struct iphdr *)&mesg; struct sockaddr_in outaddr; outaddr.sin_port = 0; outaddr.sin_family = AF_INET; memcpy(&outaddr.sin_addr, &out_ip_header->daddr, sizeof(struct in_addr)); int sendto_in = sendto(raw_socket , mesg, n , MSG_DONTWAIT, (struct sockaddr *)&outaddr, sizeof(struct sockaddr_in)); printf(">>>>>> sendto In %d \n",sendto_in); printBufHex((unsigned char*)&mesg, n); } }
אם אני עושה את זה ככה בלי שרת אלא שולח מערך של בתים כאילו קיבלתי מהשרת. אז הקרנל משנה את הפורט יעד.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <linux/types.h> #include <errno.h> #include <limits.h> #include <netinet/udp.h> #include <netinet/ip.h> #include <string.h> char buf[] = { 0x45 ,0x00 ,0x00 ,0x62 ,0x00 ,0x00 ,0x40 ,0x00 ,0x3c ,0x11 ,0x1f ,0x72 ,0x08 ,0x08 ,0x08 ,0x08 , 0x0a ,0x05 ,0x05 ,0x05 ,0x00 ,0x35 ,0xe8 ,0xd3 ,0x00 ,0x4e ,0x00 ,0x00 ,0x61 ,0xda ,0x81 ,0x80 , 0x00 ,0x01 ,0x00 ,0x02 ,0x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x74 ,0x61 ,0x6c ,0x6b ,0x06 ,0x67 ,0x6f , 0x6f ,0x67 ,0x6c ,0x65 ,0x03 ,0x63 ,0x6f ,0x6d ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c ,0x00 , 0x05 ,0x00 ,0x01 ,0x00 ,0x00 ,0x54 ,0x4d ,0x00 ,0x09 ,0x04 ,0x74 ,0x61 ,0x6c ,0x6b ,0x01 ,0x6c , 0xc0 ,0x11 ,0xc0 ,0x2d ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x01 ,0x19 ,0x00 ,0x04 ,0x4a ,0x7d , 0x88 ,0x7d }; int main(int argc, char **argv) { struct iphdr *_udp_ip_header ; _udp_ip_header = (struct iphdr *)&buf; int udp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); printf("socket %d \n",udp_socket); struct sockaddr_in sin; sin.sin_port = 0; sin.sin_family = AF_INET; memcpy(&sin.sin_addr, &_udp_ip_header->daddr, sizeof(struct in_addr)); int i =0; int sendto_i; for(;i<7;i++){ sendto_i = sendto(udp_socket , buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)); printf("sendTo %d Bytes \n",sendto_i); } exit(0); }
איך אפשר לשלוח חבילות בלי שהקרנל ישנה לי את התוכן שלהם.
פורסם במקור בפורום CODE613 ב14/02/2014 12:35 (+02:00)
-
מג'יקוד מטיל כאן מושגים מפחידים מעולם ה cpp בלי לפרש, בלי להסביר. אתה הרי יודע כמה אנשים רחוקים מהעולם הזה של c, עם כל השאיפה להכיר את התחום אינני יודע כמה מחברי הפורום באמת יודעים היטיב את נבכי השיעמום של c.
אז קודם כל תודה על המושגים החדשים, אנסה ללמוד אותם... בשלב זה אני מציע לך לשים את התוכנה חצי שעה בשמש אולי זה יסתדר :lol: :lol: :lol: :lol: :lol: :lol:
פורסם במקור בפורום CODE613 ב14/02/2014 13:25 (+02:00)
-
זה עובד בלינוקס.
כל מה שצריך לעשות כדי להריץ את זה.
לכתוב את זה בקובץ נניח app.c ולקמפל את זה ככה. בשורת הפקודה.
gcc app.c -o app
אחרי זה מריצים את זה ככה.
sudo ./app
צריך להריץ את זה עם sudo כי לשלוח חבילות בraw מצריך הרשאות מנהל.
את התוצאה של החבילות אני בודק עם wireshark
פורסם במקור בפורום CODE613 ב15/02/2014 21:49 (+02:00)
-
אז בוינדוס זה גם לא יתקמפל, נכון ?
אגב אם אני רוצה להתקין את לינוקס [במחשב וירטואלי] איך עושים את זה?יכול להיות שזה יתקמפל אני לא יודע.
אם אתה רוצה להקין על וירטואלי אני חושב שזה הדרך הכי טובה.
תוריד את התוכנה הזאת.
http://www.vmware.com/products/player
אני חושב שהיא הכי מהירה בוירטואלי.פה אתה יכול להוריד בחינם
http://www.vmware.com/go/downloadplayerאם אתה רוצה משהו שזה קוד פתוח תוריד את זה.
https://www.virtualbox.org/את הiso של לינוקס מפה.
http://www.linuxmint.com/
אני ממליץ על ההפצה הזאת לדעתי זה הפצה ממש טובה.
קח את גירסת קינמון.ב vmware אתה יוצר שם מכונה חדשה מגדיר לה בדיסקים את ה iso וזה ממשק פשוט להתקנה כמו וינדוס.
אפשר להתקין גם בעברית.פורסם במקור בפורום CODE613 ב15/02/2014 22:06 (+02:00)
-
יכול להיות שזה יתקמפל אני לא יודע.
לא מותקן לי GCC, אז כנראה שאין מצב לקמפל את זה בוינדוס
תודה על ההדרכה של הלינוקס.
בלינוקס יש GCC בברירת מחדל או צריך להוריד ולהתקין בנפרד?
ועוד שאלה הכי חשובה לפני שאני מתקין את לינוקס:
אפשר להתקין שם את נתיב או ששם הכל פרוץ?פורסם במקור בפורום CODE613 ב15/02/2014 22:37 (+02:00)
-
טוב אז כנראה הבעיה נגרמת בגלל שהקרנל משנה את הפורט בשכבת network layer .
יעוין פה.http://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg
אבל מצאתי דרך לפתוח סוקט שישתמש ישר בשכבת link layer .
ככה פותחים אותו.
socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
זה מצריך להגדיר interface ולהדגיר כתובות mac כי בשכבה הזאת אין ניתוב אוטמטי.
פורסם במקור בפורום CODE613 ב18/02/2014 14:54 (+02:00)