0

我编写了这个程序来在 eth0 上发送和接收来自 ipv6 的数据包:

#include<sys/socket.h>
#include<sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#include <errno.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main() {

    int sock,i;
    struct sockaddr_in6 *address;
    struct protoent *proto;
    struct ifreq ethreq, Interface, Interface1;
    unsigned char buffer[2048];
    unsigned char tbuff[2048];
    unsigned char *iphead, *ethhead,*phead;
    static const uint8_t mys6_addr[16]={0x54,0x04,0x20,0x49,0x0e,0x40,0xc7,0x03,0xa0};

    //open socket for receive ipv6 packet 
    sock=socket(AF_INET6, SOCK_RAW,255);
    //control error
    if(sock<0) {
        perror("socket");
        exit(1);
    }

    strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);
    if (ioctl(sock,SIOCGIFFLAGS, &ethreq) == -1) {
        perror("ioctl");
        close(sock);
        exit(1);
    }

    ethreq.ifr_flags |= IFF_PROMISC;
    if (ioctl(sock, SIOCSIFFLAGS, &ethreq) == -1) {
        perror("ioctl");
        close(sock);
        exit(1);
    }

    //bind to sock with eth0 
    memset(&Interface, 0, sizeof(Interface));
    strncpy(Interface.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);
    if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &Interface, sizeof(Interface))<0)
        close(sock);

    //open the RAW socket for sendto
    int s = socket (AF_INET6, SOCK_RAW, 255);
    struct sockaddr_in6 sin6; 
    memset(&sin6,0,sizeof(sin6));
    sin6.sin6_family = AF_INET6;
    sin6.sin6_port = htons(0);
    memcpy(sin6.sin6_addr.s6_addr, mys6_addr, sizeof(mys6_addr));
    //bind the sock descriptor with eth0
    memset(&Interface1, 0, sizeof(Interface1));
    strncpy(Interface1.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);
    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, &Interface1, sizeof(Interface1)) < 0) {
        close(s);
    }
    while (1) {

        printf("----------------------\n");
        i = recv(sock, buffer, sizeof(buffer), 0);
        printf("%d bytes read\n", i);
        // check header size: Ethernet = 14, IP = 20, TCP = 8 (sum = 42)
        i=43;
        if (i < 42) {
            perror("recvfrom():");
            printf("Incomplete packet (errno is %d)\n", errno);
            close(sock);
            exit(0);
        }
        phead = buffer + 14; // (skip ethernet  header)
        memcpy(tbuff,phead,i-14); 
        iphead=tbuff;
        if (*iphead == 0x45) {
            int ptrindex= iphead[9];
            switch(ptrindex){

            case 1:
            printf("The transport protocl is:ICMP\n");
            break;
            case 2:
            printf("The transport protol is:IGMP\n");
            break;
            case 6:
            printf("The transport protocol is:TCP\n");
            break;
            case 17:
            printf("The transport protocol is:UDP\n");
            break;
            case 103:
            printf("The transport protocol is:PIM\n"); 
            break; 
            default:
            printf("The transport protocol is:%d\n",iphead[9]);
        }           
        //printf("%d",*ptrindex);
        // printf("\n The transport protocol is :%u\n",iphead[9]); 
        printf("Source Address: %d.%d.%d.%d, Port: %d\n",
        iphead[12], iphead[13], iphead[14], iphead[15], (iphead[20] << 8) + iphead[21]);
        printf("Dest Address: %d.%d.%d.%d, Port: %d\n",
        iphead[16], iphead[17], iphead[18], iphead[19], (iphead[22] << 8) + iphead[23]);


        /* if(sendto(s,tbuff,i-14,0,(struct sockaddr_in6 *)&sin6,sizeof(sin6))<0)
        printf("error\n"); */

        if(send(s,tbuff,i-14,0)<0) {
            printf("error\n");

        } else {
            printf("\nThe received packet is send\n");
        }

        memset(buffer,0,sizeof(buffer));
        memset(tbuff,0,sizeof(tbuff));

        } else{
            printf("The non ip had received");
        }

    }
    close(sock);
    return 0;
} 

大部分代码是我读过的问题的一部分,但现在我不记得是什么了。该程序在 printf("----------------\n") 处陷入死锁。为什么?你能帮助我吗?

4

1 回答 1

0

死锁是一个循环的锁链。这里没有锁,因此也没有死锁。正在发生的recv()只是阻塞等待输入到达。

于 2012-04-11T00:43:48.377 回答