Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
插座未加工,可';在tcp握手中无法从tcp服务器获取响应_C_Sockets_Networking_Tcp - Fatal编程技术网

插座未加工,可';在tcp握手中无法从tcp服务器获取响应

插座未加工,可';在tcp握手中无法从tcp服务器获取响应,c,sockets,networking,tcp,C,Sockets,Networking,Tcp,我正在尝试使用socket raw和特殊结构sockaddr\u ll发送tcp SYN数据包,但我的数据包被忽略。我的程序应该发送SYN tcp数据包并接收SYN/ACK数据包。我试图找到一个错误,发现我的包有错误的校验和,我修复了它,但没有改变。如何修复它 我的包裹: 我的代码: int main(int argc, char *argv[]) { int sockfd; struct ifreq if_idx; struct ifreq if_mac; s

我正在尝试使用socket raw和特殊结构sockaddr\u ll发送tcp SYN数据包,但我的数据包被忽略。我的程序应该发送SYN tcp数据包并接收SYN/ACK数据包。我试图找到一个错误,发现我的包有错误的校验和,我修复了它,但没有改变。如何修复它

我的包裹:

我的代码:

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 tcphdr *tcph = (struct tcphdr *) (sendbuf + sizeof(struct ether_header) + sizeof(struct tcphdr));
    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_TCP)) == -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) + sizeof(struct tcphdr));
    iph->id = htonl (01);   //Id of this packet
    iph->frag_off = 0;
    iph->ttl = 64;
    iph->protocol = IPPROTO_TCP;
    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 = 0xce7c;//csum ((unsigned short *) sendbuf, iph->tot_len);
    tx_len += sizeof(struct iphdr);

    //tcp
    tcph->source = htons (20);
    tcph->dest = htons (43521);
    tcph->seq = 0;
    tcph->ack_seq = 0;
    tcph->doff = 5; 
    tcph->fin=0;
    tcph->syn=1;
    tcph->rst=0;
    tcph->psh=0;
    tcph->ack=0;
    tcph->urg=0;
    tcph->window = htons (8192);    
    tcph->check = 0;    //leave checksum 0 now, filled later by pseudo header
    tcph->urg_ptr = 0;

    //Now the TCP checksum
    struct pseudo_header psh; 
    char* pseudogram;

    psh.source_address = inet_addr(inet_ntoa((((struct sockaddr_in *)&(ifreq_ip.ifr_addr))->sin_addr)));
    psh.dest_address = inet_addr ( "127.0.0.1" );
    psh.placeholder = 0;
    psh.protocol = IPPROTO_TCP;
    psh.tcp_length = htons(sizeof(struct tcphdr));
    
    int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr);
    pseudogram = (char*)malloc(psize);
    
    memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
    memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr));
    
    tcph->check = csum( (unsigned short*) pseudogram , psize);

    tx_len+= sizeof(struct tcphdr);
    


    /* 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;
    socket_address.sll_family = AF_PACKET;  

    /* 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_头));
struct tcphdr*tcph=(struct tcphdr*)(sendbuf+sizeof(struct ether_头)+sizeof(struct tcphdr));
结构sockaddr\u ll套接字地址;
字符ifName[IFNAMSIZ];
/*获取接口名*/
如果(argc>1)
strcpy(ifName,argv[1]);
其他的
strcpy(ifName,默认值\u IF);
/*打开原始套接字进行发送*/
if((sockfd=socket(AF_数据包、SOCK_原始、IPPROTO_TCP))=-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)+sizeof(struct tcphdr));
iph->id=htonl(01);//此数据包的id
iph->frag_off=0;
iph->ttl=64;
iph->协议=IPPROTO_TCP;
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=0xce7c;//csum((无符号短*)sendbuf,iph->tot_len);
tx_len+=sizeof(结构iphdr);
//tcp
tcph->source=htons(20);
tcph->dest=htons(43521);
tcph->seq=0;
tcph->确认顺序=0;
tcph->doff=5;
tcph->fin=0;
tcph->syn=1;
tcph->rst=0;
tcph->psh=0;
tcph->ack=0;
tcph->urg=0;
tcph->window=htons(8192);
tcph->check=0;//现在保留校验和0,稍后由伪标头填充
tcph->urg_ptr=0;
//现在是TCP校验和
结构伪_头psh;
字符*伪码;
psh.source_address=inet_addr(inet_ntoa(((struct sockaddr_in*)和(ifreq_ip.ifr_addr))->sin_addr));
psh.dest_address=inet_addr(“127.0.0.1”);
psh.placeholder=0;
psh.protocol=IPPROTO_TCP;
psh.tcp_length=htons(sizeof(struct tcphdr));
int psize=sizeof(结构伪_头)+sizeof(结构tcphdr);
伪图=(char*)malloc(psize);
memcpy(伪程序(char*)&psh,sizeof(结构伪_头));
memcpy(伪gram+sizeof(struct pseudo_头)、tcph、sizeof(struct tcphdr));
tcph->check=csum((无符号短*)伪码,psize);
tx_len+=sizeof(结构tcphdr);
/*网络设备的索引*/
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;
socket\u address.sll\u family=AF\u数据包;
/*发送数据包*/
if(发送到(sockfd,sendbuf,tx_len,0,(struct sockaddr*)和socket_地址,sizeof(struct sockaddr_ll))<0)
printf(“发送失败\n”);
返回0;
}

MAC地址是否填写正确?您确定它已到达目标主机吗?您是否将其与TCP堆栈中的常规SYN进行了比较?您是否检查了接收器的统计信息(如netstat)对于错误?MAC地址是正确的,我在ubuntu中使用virtualBox。如果我使用socat tcp listen,我如何检查统计数据?当我必须查看原始标头(例如eth、IP、UDP、tcp)时,我在您的捕获中使用了
wireshark
,SRC和DST IP地址是127.0.0.1,这是环回。我猜您使用的代码是linux,它没有链接层(以太网)在环回上。如果你真的打算使用环回,你需要上一层,使用PF_INET/SOCK_RAW socket而不是PF_PACKET/SOCK_RAW。非常奇怪的是,你正在通过环回测试数据包RAW sockets。请尝试在适当的条件下进行测试。而且每个
peror()之后都必须有
return
s