如何使用以太网预告片发送数据报?如果我使用SocketType.Raw,我将不得不发送整个IP头,我不知道该怎么做。
答案 0 :(得分:2)
该预告片用于将以太网帧填充到其最小长度(46字节的有效负载)。所以发送一个小的UDP数据包 - 小于18个字节(因为IP + UDP通常是28个字节)
答案 1 :(得分:2)
或许这样的事情?
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <linux/if_packet.h> #include <linux/if_ether.h> #include <linux/if_arp.h> #include <sys/ioctl.h> int s; unsigned char buffer[513]; struct sockaddr_ll socket_address; int main ( void ) { unsigned char seq; unsigned int ra; int length; struct ifreq ifr; s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (s == -1) { printf("error creating socket\n"); return(1); } memset(&ifr,0, sizeof(struct ifreq)); strncpy(ifr.ifr_name,"eth0",IFNAMSIZ); if(ioctl(s, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl SIOCGIFINDEX"); exit(1); } printf("index %d\n",ifr.ifr_ifindex); printf("socket created\n"); memset(&socket_address,0,sizeof(socket_address)); socket_address.sll_family = PF_PACKET; socket_address.sll_protocol = htons(ETH_P_ALL); socket_address.sll_ifindex = ifr.ifr_ifindex; if (bind(s, (struct sockaddr *)(&socket_address), sizeof(socket_address)) < 0) { perror("bind error"); exit(1); } printf("bound\n"); length=27; memset(buffer,0,sizeof(buffer)); //destination buffer[ 0]=0xFF; buffer[ 1]=0xFF; buffer[ 2]=0xFF; buffer[ 3]=0xFF; buffer[ 4]=0xFF; buffer[ 5]=0xFF; //source buffer[ 6]=0x00; buffer[ 7]=0x19; buffer[ 8]=0xd1; buffer[ 9]=0x02; buffer[10]=0xdc; buffer[11]=0xb3; //length buffer[12]=((length-14)>>8)&0xFF; buffer[13]=((length-14)>>0)&0xFF; //payload buffer[14]=0x12; buffer[15]=0x34; for(ra=0;ra<20;ra++) { buffer[16]=ra; if(send(s,buffer,length,0) < 0 ) { printf("sendto failed\n"); break; } else { printf("sent\n"); } } close(s); return(1); }
那应该给你一个可以在wireshark上看到的原始数据包。如果你想拥有ip eader,或者使它成为一个udp或类似的东西,你可以使用这个方法并自己构建头文件(这很简单看一下rfcs或者只是使用wireshark查看一堆其他的包头) 。请注意,对于udp,您不必计算校验和0x0000是一个应该传递的有效校验和。
如果你想要的只是一个udp数据包,最后的零点有点相同,可能更容易,请告诉我。