我来我网
https://5come5.cn
 
您尚未 登录  注册 | 菠菜 | 软件站 | 音乐站 | 邮箱1 | 邮箱2 | 风格选择 | 更多 » 
 

本页主题: 用RAW Socket实现IP包的捕获 显示签名 | 打印 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题

rchlz



性别: 帅哥 状态: 该用户目前不在线
等级: 鹤立鸡群
发贴: 1056
威望: 0
浮云: 1149
在线等级:
注册时间: 2004-09-15
最后登陆: 2008-03-11

5come5帮你背单词 [ expensive /iks'pensiv/ a. 昂贵的,奢侈的 ]


用RAW Socket实现IP包的捕获

项目需要,接触了linux下的sniffer(用libpcap实现),后来不用sniffer了,直接操作skb_buff内核态收包,所以就把sniffer淡忘了。昨天突然想看看windows下的sniffer,结果却看了RAW Socket抓包的,这个抓包只能抓到IP包,对其他包如ARP包[屏蔽]为力,既然忙活了半天,就老老实实地实践了一下。
 
  贴出我的源码,只希望抛砖引玉,能够使师弟们对网络编程产生兴趣。也欢迎各位高手指导。

  代码在Win XP+VC++6.0,Win XP+VS2005,Win 2K+VC++6.0下测试均通过。

Copy code

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define IP_HDRINCL 2 //在ws2tcpip.h里定义了的,他的值就是2

int main()
{
  WSADATA WSAdata;
  // 加载正确版本的winsock库
  if(WSAStartup(MAKEWORD(2,2),&WSAdata)!=0)
  {
    printf("WSAStartup failed: %d\n",GetLastError());
    return 1;
  }

  // 创建原始套节字
  SOCKET rs;
  rs=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
  if(rs==INVALID_SOCKET)
  {
    printf("Socket() failed: %d\n",WSAGetLastError());
    return 1;
  }
 
  // 设置IP头操作选项,flag为TRUE,亲自对IP头部处理
  BOOL flag = true;
  if(setsockopt(rs,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
  {
    printf("setsockopt() failed: %d\n",WSAGetLastError());
    return 1;
  }

  // 获取机器名和IP地址
  char LocalName[255];
  struct hostent *pHost;
  gethostname(LocalName,sizeof(LocalName)-1);
  pHost = gethostbyname((char *)LocalName);

  // 填充SOCKADDR_IN结构
  SOCKADDR_IN sa;
  sa.sin_family = AF_INET;
  sa.sin_port = htons(10000);
  //sa.sin_addr.S_un.S_addr = inet_addr("172.24.22.222");  
  //sa.sin_addr =* (in_addr *)pHost->h_addr_list[0]; //填充IP
  memcpy(&sa.sin_addr,pHost->h_addr_list[0],pHost->h_length);   //这三种填充IP的方式都可以
  //printf("IP: %s \n",pHost->h_addr);

  // 将原始套节字绑定到某个确定的网络接口上
  if(bind(rs,(PSOCKADDR)&sa,sizeof(sa))==SOCKET_ERROR)
  {
    printf("bind() failed: %d\n",WSAGetLastError());
    closesocket(rs);
    return 1;
  }

  // 设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
  DWORD dwBufferLen[10];
  DWORD dwBufferInLen = 1;
  DWORD dwBytesReturned = 0;
  if(WSAIoctl(rs,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)==SOCKET_ERROR)
  {
    printf("WSAIoctl() failed: %d\n",WSAGetLastError());
    closesocket(rs);
    return 1;
  }
 
  // 从绑定的套节字不断接收数据,并打印出来
  char buf[65535]={0};
  int i=1;
  while(true)
  {
    int ret = recv(rs,buf,sizeof(buf),0);
    if(ret>0)
    {
        for(int j=0;j<255;j++)
        {
          printf("%02x",buf[j]);
        }
        printf("\n我已经抓了%d个包啦     \n",i);
        i++;
    }
  }
  closesocket(rs);
  return 1;
}

顶端 Posted: 2007-06-10 02:24 | [楼 主]
threes



性别: 帅哥 状态: 该用户目前不在线
等级: 鹤立鸡群
发贴: 1484
威望: 0
浮云: 1109
在线等级:
注册时间: 2006-11-27
最后登陆: 2013-06-05

5come5帮你背单词 [ eastern /'i:stən/ a. 东方的,东部的 ]


lz是强人
但就是入不了gate
不知有何高见
顶端 Posted: 2007-06-10 02:36 | [1 楼]
rchlz



性别: 帅哥 状态: 该用户目前不在线
等级: 鹤立鸡群
发贴: 1056
威望: 0
浮云: 1149
在线等级:
注册时间: 2004-09-15
最后登陆: 2008-03-11

5come5帮你背单词 [ durable /'djuərəbl/ a. 耐久的 ]


Quote:
引用第1楼threes于2007-06-10 02:36发表的:
lz是强人
但就是入不了gate
不知有何高见


给自己找压力学习。
如果本身有压力就不要了哈~~
能够参与项目当然是最好的了。

再就是兴趣了。
有一个能引导你的老师。
顶端 Posted: 2007-06-10 02:44 | [2 楼]
我来我网·5come5 Forum » 程序员之家

Total 0.011698(s) query 5, Time now is:11-23 09:21, Gzip enabled
Powered by PHPWind v5.3, Localized by 5come5 Tech Team, 黔ICP备16009856号