-1

我想将数据发送给我的朋友。我不知道他的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

1 回答 1

0

虽然您的程序可能会向网络发送数据帧,但它不会从那里得到任何地方。MAC 地址是非分层的,这意味着地址空间是平坦的。知道 MAC 地址不会告诉您如何到达该地址。

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

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

于 2014-02-27T01:03:40.720 回答