如何传输以太网帧?

如何传输以太网帧?

问题描述:

我想将数据发送给我的朋友。我不知道他的IP地址。但我知道他的MAC地址。所以我必须使用以太网帧发送数据。如何传输以太网帧?

我写了一个程序,但它不工作。我不明白问题在哪里?我在哪里犯了一个错误?

客户端帧的发送:

main() 
{ 
    int size ; 
    char req[10]; 
    printf("enter to send\n"); 
    gets(req); 
    int fd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)); 
    if (fd==-1) 
    { 
    perror("socket"); 
    } 

    struct ifreq ifr; 
    char if_name[5]="eth0"; 
    int if_name_len=strlen(if_name); 
    if (if_name_len<sizeof(ifr.ifr_name)) 
    { 
    memcpy(ifr.ifr_name,if_name,if_name_len); 
    ifr.ifr_name[if_name_len]=0; 
    } 
    else 
    { 
    printf("interface name is too long"); 
    } 

    if (ioctl(fd,SIOCGIFINDEX,&ifr)==-1) 
    { 
    perror("ioctl"); 
    } 
    int ifindex=ifr.ifr_ifindex; 
    printf("ethernet interface id:%x\n",ifindex); 

    const unsigned char ether_broadcast_addr[]={0x00,0x1d,0x09,0x7a,0xDf,0x5e}; 

    struct sockaddr_ll addr={0}; 

    addr.sll_family=PF_PACKET; 
    addr.sll_ifindex=ifindex; 
    addr.sll_halen=ETHER_ADDR_LEN; 
    //addr.sll_protocol=htons(ETH_P_IP); 
    memcpy(&addr.sll_addr,ether_broadcast_addr,ETHER_ADDR_LEN); 
    addr.sll_hatype=772; 
    addr.sll_pkttype=PACKET_OUTGOING; 

    printf("size=%d\n",size); 
    if (size=sendto(fd,req,sizeof(req),0,(struct sockaddr*)&addr,sizeof(addr))==-1) 
    { 
    perror("sendto"); 
    } 
    printf("send size=%d\n",size); 

} 

框架在服务器端接收代码:

main() 
{ 

    int size; 
    char req[20]; 
    int fd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); 
    if (fd==-1) 
    { 
    perror("socket"); 
    } 

    struct ifreq ifr; 
    char if_name[5]="eth0"; 
    int if_name_len=strlen(if_name); 
    if (if_name_len<sizeof(ifr.ifr_name)) 
    { 
    memcpy(ifr.ifr_name,if_name,if_name_len); 
    ifr.ifr_name[if_name_len]=0; 
    } 
    else 
    { 
    printf("interface name is too long"); 
    } 

    if (ioctl(fd,SIOCGIFINDEX,&ifr)==-1) 
    { 
    perror("ioctl"); 
    } 
    int ifindex=ifr.ifr_ifindex; 
    printf("ethernet interface id:%x\n",ifindex); 

    const unsigned char ether_broadcast_addr[]={0x00,0x1d,0x09,0x7a,0xDf,0x5e}; 

    struct sockaddr_ll addr={0}; 

    addr.sll_family=PF_PACKET; 
    addr.sll_ifindex=ifindex; 
    addr.sll_halen=ETHER_ADDR_LEN; 
    addr.sll_protocol=htons(ETH_P_ALL); 
    memcpy(&addr.sll_addr,ether_broadcast_addr,ETHER_ADDR_LEN); 

    addr.sll_pkttype=PACKET_OUTGOING; 
    addr.sll_hatype=772; 

    bind (fd, (struct sockaddr*)&addr, sizeof(addr)); 

    printf("size=%d\n",size); 
    socklen_t a=sizeof(addr); 
    size=recvfrom(fd,req,sizeof(req),0,(struct sockaddr*)&addr,&a); 
    if(size==-1) 
    { 
    perror("recvfrom"); 
    } 
    printf("size=%d\n",size); 
    printf("recv msg=%s\n",req); 
} 
+4

'不工作'根本没有帮助我们。发生什么事情不应该发生?发生什么不该发生?你在调试过程中发现了什么?使用Wireshark等网络分析器检查线路时会发生什么? –

+0

找出IP地址会更快吗? –

,而你的程序可能会在发送数据帧在网络上工作,也不会在任何地方从那里.MAC地址不是分层的,这意味着地址空间是平坦的。知道MAC地址不会告诉你如何到达该地址。

拥有某人的MAC地址与拥有某人的姓名相同。你可能知道他们的名字,但你不能用他们的电话号码给他们打电话。现在如果你有他们的全名,你可以查看他们的电话号码。网络是类似的。

网络数据(数据包)从您的计算机发送到您的默认网关,该网关是连接到您的ISP的DSL或电缆调制解调器。当它收到数据包时,它会查看IP地址以决定将数据发送到哪里。由于您的帧(没有IP地址的数据称为帧)没有IP地址,网关将只删除它。更确切地说,因为它没有目标或源IP地址,所以它永远不会真正进入网关。它是在网络上传输的,没有做任何事情。