Linux 混杂模式

先在终端上运行:ifconfig eth0 -promisc

将网卡设置成混杂模式.然后运行代码如下:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <unistd.h>
#include <netinet/in.h>
/*
* set the interface to promisc mode.
*/
int set_netpromisc()
{
int fd, s;
struct ifreq ifr;

fd = socket(AF_INET, SOCK_PACKET, htons(0x800));
if (fd < 0)
{
  perror("can not get SOCK_PACKET socket");
  return 0;
}

strcpy(ifr.ifr_name, "eth0");

s = ioctl(fd, SIOCGIFFLAGS, &ifr);

if (s < 0)
{
  close(fd);
  perror("can not get flags");
  return 0;
}

ifr.ifr_flags |= IFF_PROMISC;

s = ioctl(fd, SIOCSIFFLAGS, &ifr);
if (s < 0)
{
  close(fd);
  perror("can not set flags");
  return 0;
}
return fd;
}
/*
* display characters
*/
void show_char(void *buff, int len)
{
while (len --)
{
  if (buff)
  {
   printf("%c", *((char *)(buff++)));
  }
  else
  {
   printf(".");
   buff ++;
  }
  
}
}

/*
* display a buff in Hex.
*/
void show_hex(void *buff, int len)
{
int i = 15, tmp;
while (len --)
{
  printf("%02x ", *(unsigned char *)(buff ++));
  if (i -- == 0)
  {
   printf("\t");
   show_char(buff - 16, 16);
   printf("\n");
   i = 15;
  }        
}
if (i != 0)
{
  tmp = i + 1;
  while (tmp --)
   printf(" %c ", '.');
  printf("\t");
  show_char(buff - 15 + i, 16 - i);
  printf("\n");
}
printf("\n\n");
}

/*
* the main function.
*/
int main()
{
int sockfd, ret;
char buff[4096];

set_netpromisc();
if((sockfd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL))) == -1)
{
  perror("socket error");
  return 0;
}

memset(buff, 0x00, 4096);

/*
* recvfrom all the packages.
*/
while ((ret = recvfrom(sockfd, buff, 4096, 0, NULL, NULL)) > 0)
{
  show_hex(buff, ret); // display it now..
  memset(buff, 0x00, ret);
}
close(sockfd);
return 0;
}