RecvRawEth.c



/*
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 */

#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>

//00 0a 35 00 00 01
/*
#define DEST_MAC0 0x00
#define DEST_MAC1 0x1f
#define DEST_MAC2 0x44
#define DEST_MAC3 0x05
#define DEST_MAC4 0x80
#define DEST_MAC5 0x00
*/
//8c:ae:4c:f4:09:77 -VM mcahine
//VM machine
/*
#define DEST_MAC0 0x8c
#define DEST_MAC1 0xae
#define DEST_MAC2 0x4c
#define DEST_MAC3 0xf4
#define DEST_MAC4 0x09
#define DEST_MAC5 0x77
*/


//Zynq

#define DEST_MAC0 0x00
#define DEST_MAC1 0x0a
#define DEST_MAC2 0x35
#define DEST_MAC3 0x00
#define DEST_MAC4 0x00
#define DEST_MAC5 0x01


#define ETHER_TYPE 0x0800

#define DEFAULT_IF "eth0"
#define BUF_SIZ  1024

int main(int argc, char *argv[])
{
 char sender[INET6_ADDRSTRLEN];
 int sockfd, ret, i;
 int sockopt;
 ssize_t numbytes;
 struct ifreq ifopts; /* set promiscuous mode */
 struct ifreq if_ip; /* get ip addr */
 struct sockaddr_storage their_addr;
 uint8_t buf[BUF_SIZ];
 char ifName[IFNAMSIZ];
 
 /* Get interface name */
 if (argc > 1)
  strcpy(ifName, argv[1]);
 else
  strcpy(ifName, DEFAULT_IF);

 /* Header structures */
 struct ether_header *eh = (struct ether_header *) buf;
 struct iphdr *iph = (struct iphdr *) (buf + sizeof(struct ether_header));
 struct udphdr *udph = (struct udphdr *) (buf + sizeof(struct iphdr) + sizeof(struct ether_header));

 memset(&if_ip, 0, sizeof(struct ifreq));

 /* Open PF_PACKET socket, listening for EtherType ETHER_TYPE */
 if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
  perror("listener: socket"); 
  return -1;
 }

 /* Set interface to promiscuous mode - do we need to do this every time? */
 strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
 ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
 ifopts.ifr_flags |= IFF_PROMISC;
 ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
 /* Allow the socket to be reused - incase connection is closed prematurely */
 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
  perror("setsockopt");
  close(sockfd);
  exit(EXIT_FAILURE);
 }
 /* Bind to device */
 if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1) {
  perror("SO_BINDTODEVICE");
  close(sockfd);
  exit(EXIT_FAILURE);
 }

repeat: printf("listener: Waiting to recvfrom...\n");
 numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
 printf("listener: got packet %lu bytes\n", numbytes);

 /* Check the packet is for me */
 if (eh->ether_dhost[0] == DEST_MAC0 &&
   eh->ether_dhost[1] == DEST_MAC1 &&
   eh->ether_dhost[2] == DEST_MAC2 &&
   eh->ether_dhost[3] == DEST_MAC3 &&
   eh->ether_dhost[4] == DEST_MAC4 &&
   eh->ether_dhost[5] == DEST_MAC5) {
  printf("Correct destination MAC address\n");
 } else {
  printf("Wrong destination MAC: %x:%x:%x:%x:%x:%x\n",
      eh->ether_dhost[0],
      eh->ether_dhost[1],
      eh->ether_dhost[2],
      eh->ether_dhost[3],
      eh->ether_dhost[4],
      eh->ether_dhost[5]);
  ret = -1;
  goto done;
 }

 /* Get source IP */
 ((struct sockaddr_in *)&their_addr)->sin_addr.s_addr = iph->saddr;
 inet_ntop(AF_INET, &((struct sockaddr_in*)&their_addr)->sin_addr, sender, sizeof sender);

 /* Look up my device IP addr if possible */
 strncpy(if_ip.ifr_name, ifName, IFNAMSIZ-1);
 if (ioctl(sockfd, SIOCGIFADDR, &if_ip) >= 0) { /* if we can't check then don't */
  printf("Source IP: %s\n My IP: %s\n", sender,
    inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr));
  /* ignore if I sent it */
  if (strcmp(sender, inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr)) == 0) {
   printf("but I sent it :(\n");
   ret = -1;
   goto done;
  }
 }

 /* UDP payload length */
 ret = ntohs(udph->len) - sizeof(struct udphdr);

 /* Print packet */
 printf("\tData:");
 for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);
 printf("\n");

done: goto repeat;

 close(sockfd);
 return ret;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值