Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3921942
  • 博文数量: 534
  • 博客积分: 10470
  • 博客等级: 上将
  • 技术积分: 4800
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-26 14:08
文章分类

全部博文(534)

文章存档

2024年(1)

2021年(1)

2019年(1)

2017年(1)

2016年(2)

2013年(2)

2012年(10)

2011年(43)

2010年(10)

2009年(17)

2008年(121)

2007年(252)

2006年(73)

分类:

2007-08-21 11:21:07

参考了很多网上的资料写了一个小的测试code:

<测试环境>
RedHat 9.0 kernel 2.4.20-8

<编译方法>
$gcc -Wall -o sniffer sniffer.c
产生sniffer可执行文件就可以测试了.


         

#include <stdio.h>
#include <unistd.h>

#include <signal.h>
#include <string.h>
#include <errno.h>

#include <sys/socket.h>
#include <linux/if_ether.h>
#include <linux/in.h>

#include <sys/ioctl.h>
#include <linux/sockios.h>
#include <net/if.h>

#define    SNIF_BUFFER_SIZE    2048

#define    _XFF(t)            ((t)&0xFF)
#define    SNIF_ADDR_MAC(p)     \
    _XFF((p)[0]),_XFF((p)[1]),_XFF((p)[2]),_XFF((p)[3]),_XFF((p)[4]),_XFF((p)[5])
#define    SNIF_ADDR_IP(p)        _XFF((p)[0]),_XFF((p)[1]),_XFF((p)[2]),_XFF((p)[3])

static int isc;
static void exit_while(int signo)
{
  isc = 0;
}

int main(int argc, char **argv)
{
  int        sd, rlen;
  char        buf[SNIF_BUFFER_SIZE];
  char        *p;
  struct ifreq    ethreq;

  /* Ctrl+C */
  signal(SIGINT, exit_while);

  if ((sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 0)
  {
    fprintf(stderr, "socket create error: %s\n", strerror(errno));
    goto err_ret;
  }

  strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ);
  ioctl(sd, SIOCGIFFLAGS, &ethreq);
  ethreq.ifr_flags |= IFF_PROMISC;
  ioctl(sd, SIOCSIFFLAGS, &ethreq);

  isc = 1;
  while (isc)
  {
    rlen = recvfrom(sd, buf, SNIF_BUFFER_SIZE, 0, NULL, NULL);
    if (rlen < 42)
    {
      fprintf(stderr, "Recv incomplete header information. \n");
      continue;
    }

    p = buf;

    /* dest mac addr [6] | src mac addr [6] | type [2]
     * | ip data packet
     */

    printf("MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X ==> %.2X:%.2X:%.2X:%.2X:%.2X:%.2X "
    , SNIF_ADDR_MAC(&p[6]), SNIF_ADDR_MAC(p));

    /* other ip data [12] | src ip addr [4] | dest ip addr [4]
     * | tcp/udp data packet
     */

    p += (6 + 6 + 2 + 12);
    printf("IP %d.%d.%d.%d ==> %d.%d.%d.%d \n"
    , SNIF_ADDR_IP(p), SNIF_ADDR_IP(&p[4]));
  }

  close(sd);

  return (0);

err_ret:
  return (-1);
}



以root运行, 看到奇怪的东西:
MAC: 00:00:00:00:00:00 ==> 00:00:00:00:00:00 IP 127.0.0.1 ==> 127.0.0.1
很多MAC 0地址, 不知为何?

原来在学校学习的TCP/IP什么的还以为没什么用处, 现在感觉学的太少, 还得补噢!

google到http://www.cnblogs.com/flier/archive/2004/07/08/22270.html, 以下为解释, 广播?
    前两天同事抓到了包括MAC地址全0的包,在讨论和请教牛人后,大概得出的结论是这种MAC地址在共享网络下面是有效的。据说 long long ago时这种MAC地址和主机地址部分全0的IP地址一样,是用于广播的(rain提供)。不过现在这种MAC好像已经不再作为特殊地址保留(scz测 试),而部分系统如BSD系列还保留主机地址全0的IP地址的广播效果。
     scz的详细测试结果如下:

    以下为引用:

         1) Linux

         Linux下ifconfig修改MAC地址前必须先down掉相应接口,改了MAC之后再
         up。但是Linux下将MAC设置成全零后(此时无错误提示),相应接口up失败:

         ifconfig eth0 hw ether 00:00:00:00:00:00

         Linux虽然自身无法设置全零MAC,但可与全零MAC的系统正常通信。


         2) x86/Solaris

         x86/Solaris 9不必down/unplumb接口,可直接修改MAC地址:

         ifconfig dnet0 ether 00:00:00:00:00:00

         全零MAC地址可与同一HUB上的Windows系统通信。


         3) Windows 98/NT/2000/XP/2003

         Windows XP通过GUI界面设置全零MAC时无错误提示,但真实通信时仍然使用原MAC,
         "ipconfig -all"查看得到的MAC地址也是原MAC。

         Windows 98/2000/XP都可与全零MAC的系统正常通信,NT/2003未测试,应该也是可以
         的。

         XP下MAC地址在注册表中的相应位置:

         HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlClass{4D36E972-E325-11CE-BFC1-08002bE10318}

         NetCfgInstanceId    REG_SZ  {可变串}
         NetworkAddress      REG_SZ  000000111111


         4) x86/FreeBSD

         FreeBSD下ifconfig修改MAC地址前不必down掉相应接口,可直接修改,并且全零MAC
         地址与同一HUB上的Windows系统通信无误:

         ifconfig lnc0 ether lladdr 00:00:00:00:00:00

         各种系统是否接受全零MAC地址是实现相关的,并不统一。注意,上述系统不但在同
         一子网,而且在同一HUB上。一般交换机不接受全零MAC地址,导致ARP解析失败,无
         法获取目标MAC,IP通信自然也就失败。

==============================
应该不是上面说的那样, 应该是: 环回接口

大多数的产品都支持环回接口(Loopback Interface),以允许运行在同一台主机上的客户程序和服务器程序通过TCP/IP进行通信。A类网络号127就是为环回接口预留的。根据惯例,大多数系统把IP地址127.0.0.1分配给这个接口,并命名为localhost。一个传给环回接口的IP数据报不能在任何网络上出现。
    我们想象,一旦传输层检测到目的端地址是环回地址时,应该可以省略部分传输层和所有网络层的逻辑操作。但是大多数的产品还是照样完成传输层和网络层的所有过程,只是当IP数据报离开网络层时把它返回给自己。


阅读(1898) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~