Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 以太网数据包通过套接字raw具有尾部udp报头_C++_C_Sockets_Networking_Wireshark - Fatal编程技术网

C++ 以太网数据包通过套接字raw具有尾部udp报头

C++ 以太网数据包通过套接字raw具有尾部udp报头,c++,c,sockets,networking,wireshark,C++,C,Sockets,Networking,Wireshark,我尝试使用socket raw和特殊结构的sockaddr\ll发送udp数据包,但我只得到一个带尾部的以太网报头和没有udp报头的ip报头。我想发送一个正常的udp数据包,没有拖车,并得到我的消息。我用wireshark检查了包裹。我怎样才能解决这个问题? 我的包裹: 我的代码: int main(int argc, char *argv[]) { int sockfd; struct ifreq if_idx; struct ifreq if_mac; stru

我尝试使用socket raw和特殊结构的sockaddr\ll发送udp数据包,但我只得到一个带尾部的以太网报头和没有udp报头的ip报头。我想发送一个正常的udp数据包,没有拖车,并得到我的消息。我用wireshark检查了包裹。我怎样才能解决这个问题? 我的包裹:

我的代码:

int main(int argc, char *argv[])
{
    int sockfd;
    struct ifreq if_idx;
    struct ifreq if_mac;
  struct ifreq ifreq_ip;
    int tx_len = 0;
    unsigned char* sendbuf;
  sendbuf=(unsigned char*)malloc(64); 
    memset(sendbuf,0,64);

    struct ether_header *eh = (struct ether_header *) sendbuf;
    struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header));
  struct udphdr *uph = (struct udphdr *) (sendbuf + sizeof(struct ether_header) + sizeof(struct iphdr));
    struct sockaddr_ll socket_address;
    char ifName[IFNAMSIZ];
    
    /* Get interface name */
    if (argc > 1)
        strcpy(ifName, argv[1]);
    else
        strcpy(ifName, DEFAULT_IF);

    /* Open RAW socket to send on */
    if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
        perror("socket");
    }

    /* Get the index of the interface to send on */
    memset(&if_idx, 0, sizeof(struct ifreq));
    strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1);
    if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
        perror("SIOCGIFINDEX");
    /* Get the MAC address of the interface to send on */
    memset(&if_mac, 0, sizeof(struct ifreq));
    strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1);
    if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
        perror("SIOCGIFHWADDR");
  /* get ip */
  memset(&ifreq_ip,0,sizeof(ifreq_ip));
    strncpy(ifreq_ip.ifr_name,ifName,IFNAMSIZ-1);
  if(ioctl(sockfd,SIOCGIFADDR,&ifreq_ip)<0)
    {
        printf("error in SIOCGIFADDR \n");
    }



    /* Construct the Ethernet header */
    /* Ethernet header */
    eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
    eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
    eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
    eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
    eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
    eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
    eh->ether_dhost[0] = MY_DEST_MAC0;
    eh->ether_dhost[1] = MY_DEST_MAC1;
    eh->ether_dhost[2] = MY_DEST_MAC2;
    eh->ether_dhost[3] = MY_DEST_MAC3;
    eh->ether_dhost[4] = MY_DEST_MAC4;
    eh->ether_dhost[5] = MY_DEST_MAC5;
    /* Ethertype field */
    eh->ether_type = htons(ETH_P_IP);
    tx_len += sizeof(struct ether_header);

    /* ip header */
    iph->ihl = 5;
    iph->version = 4;
    iph->tos = 0;
    iph->tot_len = htons(sizeof (struct iphdr));
    iph->id = htonl (54321);    //Id of this packet
    iph->frag_off = 0;
    iph->ttl = 255;
    iph->protocol = IPPROTO_UDP;
    iph->check = 0;     
    iph->saddr = inet_addr(inet_ntoa((((struct sockaddr_in *)&(ifreq_ip.ifr_addr))->sin_addr)));    
    iph->daddr = inet_addr ( "127.0.0.1" );
    
    //Ip checksum
    iph->check = csum ((unsigned short *) sendbuf, iph->tot_len);
  tx_len += sizeof(struct iphdr);

  uph->source   = htons(80);
    uph->dest   = htons(43521);
    uph->check  = 0;

    tx_len+= sizeof(struct udphdr);
    sendbuf[tx_len++]   =   0xAA;
    sendbuf[tx_len++]   =   0xBB;
    sendbuf[tx_len++]   =   0xCC;
    sendbuf[tx_len++]   =   0xDD;
    sendbuf[tx_len++]   =   0xEE;
    uph->len        = htons((tx_len - sizeof(struct iphdr) - sizeof(struct ethhdr)));

    /* Index of the network device */
    socket_address.sll_ifindex = if_idx.ifr_ifindex;
    /* Address length*/
    socket_address.sll_halen = ETH_ALEN;
    /* Destination MAC */
    socket_address.sll_addr[0] = MY_DEST_MAC0;
    socket_address.sll_addr[1] = MY_DEST_MAC1;
    socket_address.sll_addr[2] = MY_DEST_MAC2;
    socket_address.sll_addr[3] = MY_DEST_MAC3;
    socket_address.sll_addr[4] = MY_DEST_MAC4;
    socket_address.sll_addr[5] = MY_DEST_MAC5;

    /* Send packet */
    if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
        printf("Send failed\n");

    return 0;
}
intmain(intargc,char*argv[])
{
int-sockfd;
结构ifreq if_idx;
结构ifreq if_mac;
结构ifreq ifreq_ip;
int tx_len=0;
无符号字符*sendbuf;
sendbuf=(无符号字符*)malloc(64);
memset(sendbuf,0,64);
结构Ethernet_头*eh=(结构Ethernet_头*)sendbuf;
结构iphdr*iph=(结构iphdr*)(sendbuf+sizeof(结构ether_头));
结构udphdr*uph=(结构udphdr*)(sendbuf+sizeof(结构ether_头)+sizeof(结构iphdr));
结构sockaddr\u ll套接字地址;
字符ifName[IFNAMSIZ];
/*获取接口名*/
如果(argc>1)
strcpy(ifName,argv[1]);
其他的
strcpy(ifName,默认值\u IF);
/*打开原始套接字进行发送*/
if((sockfd=socket(AF_数据包、SOCK_原始、IPPROTO_原始))=-1){
佩罗(“插座”);
}
/*获取要发送的接口的索引*/
memset(&if_idx,0,sizeof(struct ifreq));
strncpy(如果为idx.ifr\U名称、ifName、IFNAMSIZ-1);
if(ioctl(sockfd、SIOCGIFINDEX和if_idx)<0)
perror(“SIOCGIFINDEX”);
/*获取要发送的接口的MAC地址*/
memset(&if_mac,0,sizeof(struct ifreq));
strncpy(如果mac.ifr\U名称、ifName、IFNAMSIZ-1);
if(ioctl(sockfd、SIOCGIFHWADDR和if_mac)<0)
perror(“SIOCGIFHWADDR”);
/*获取ip*/
memset(&ifreq_ip,0,sizeof(ifreq_ip));
strncpy(ifreq\u ip.ifr\u名称、ifName、IFNAMSIZ-1);
if(ioctl(sockfd、SIOCGIFADDR和ifreq_ip)以太存储[0]=((uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[0];
eh->ether_shost[1]=(uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[1];
eh->ether_shost[2]=(uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[2];
eh->ether_shost[3]=(uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[3];
eh->ether_shost[4]=((uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[4];
eh->ether_shost[5]=((uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[5];
eh->ether\u dhost[0]=我的目的地0;
eh->ether\u dhost[1]=我的目的地1;
eh->ether\u dhost[2]=我的目的地2;
eh->ether\u dhost[3]=我的目的地3;
eh->ether\u dhost[4]=我的目的地4;
eh->ether\u dhost[5]=我的目的地5;
/*醚型场*/
eh->乙醚类型=htons(乙醚类型);
tx_len+=sizeof(结构以太网头);
/*ip报头*/
iph->ihl=5;
iph->version=4;
iph->tos=0;
iph->tot_len=htons(sizeof(struct iphdr));
iph->id=htonl(54321);//此数据包的id
iph->frag_off=0;
iph->ttl=255;
iph->protocol=IPPROTO_UDP;
iph->check=0;
iph->saddr=inet_addr(inet_ntoa((((struct sockaddr_in*)和(ifreq_ip.ifr_addr))->sin_addr));
iph->daddr=inet_addr(“127.0.0.1”);
//Ip校验和
iph->check=csum((无符号短*)sendbuf,iph->tot_len);
tx_len+=sizeof(结构iphdr);
uph->source=htons(80);
uph->dest=htons(43521);
uph->check=0;
tx_len+=sizeof(结构udphdr);
sendbuf[tx_len++]=0xAA;
sendbuf[tx_len++]=0xBB;
sendbuf[tx_len++]=0xCC;
sendbuf[tx_len++]=0xDD;
sendbuf[tx_len++]=0xEE;
uph->len=htons((tx_len-sizeof(struct iphdr)-sizeof(struct ethhdr));
/*网络设备的索引*/
socket\u address.sll\u ifindex=if\u idx.ifr\u ifindex;
/*地址长度*/
socket_address.sll_halen=ETH_ALEN;
/*目的地MAC*/
socket\u address.sll\u addr[0]=MY\u DEST\u MAC0;
socket\u address.sll\u addr[1]=我的目的地MAC1;
socket\u address.sll\u addr[2]=MY\u DEST\u MAC2;
socket\u address.sll\u addr[3]=MY\u DEST\u MAC3;
socket\u address.sll\u addr[4]=我的目的地MAC4;
socket\u address.sll\u addr[5]=我的目的地MAC5;
/*发送数据包*/
if(发送到(sockfd,sendbuf,tx_len,0,(struct sockaddr*)和socket_地址,sizeof(struct sockaddr_ll))<0)
printf(“发送失败\n”);
返回0;
}

IP总长度字段只有20个字节,这只是IP头的大小,就IP而言,没有有效负载。您需要确保IP总长度字段设置为IP头的大小加上整个有效负载的大小。特别是,此行是错误的:

iph->tot_len = htons(sizeof (struct iphdr));

以太网在有效载荷之后需要一个四个八位组的FCS拖车。以太网帧的有效载荷是网络(如IP)数据包,网络数据包的有效载荷是传输(如UDP)数据报,而传输数据报的有效载荷是应用程序数据。@RonMaupin如何解决此问题?我尝试使用socat发送udp数据包,但没有看到fcs拖车。我应该在哪里添加fcs?