编译链接都没问题,运行时提示bind failed#include "stdafx.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "iostream.h"
#include "stdio.h"
#pragma comment(lib, "ws2_32.lib")typedef struct _IP_HEADER  //定义IP头
{
union
{
BYTE Version;      //版本(前4位)
BYTE HdrLen;       //IHL(后4位),IP头的长度
};
BYTE ServiceType;      //服务类型
WORD TotalLen;         //总长
WORD ID;               //标识
union
{
WORD Flags;        //标志(前3位)
WORD FragOff;      //分段偏移(后13位)
};
BYTE TimeToLive;       //生命期
BYTE Protocol;         //协议
WORD HdrChksum;        //头校验和
DWORD SrcAddr;         //源地址
DWORD DstAddr;         //目的地址
BYTE Options;          //选项
}IP_HEADER;
//逐位解析IP头中的信息
void getVersion(BYTE b,BYTE & version)
{
version=b>>4;
}void getIHL(BYTE b,BYTE & result)
{
result=(b & 0x0f)*4;
}
char * parseServiceType_getProcedence(BYTE b)
{
switch(b>>5)
{
case 7:
return "Network Control";
break;
case 6:
return "Internet work Control";
break;
case 5:
return "CRITIC/ECP";
break;
case 4:
return "Flash Override";
break;
case 3:
return "Flash";
break;
case 2:
return "Immdiate";
break;
case 1:
return "Priority";
break;
case 0:
return "Routine";
break;
default:
return "Unknown"; }
}char * parseServiceType_getTOS(BYTE b)
{
b=(b>>1)&0x0f;
switch(b)
{
case 0:
return "Normal service";
break;
case 1:
return "Minimize monetary cost";
break;
case 2:
return "Maximize reliability";
break;
case 4:
return "Maximize throughput";
break;
case 8:
return "Minimize security";
break;
case 15:
return "Maximize security";
break;
default:
return "Unknown";
}
}void getFlags(WORD w, BYTE & DF, BYTE & MF)
{
DF = (w>>14)&0x01;
MF = (w>>13)&0x01;
}void getFragOff(WORD w, WORD & fragOff)
{
fragOff = w&0x1fff;
}char * getProtocol(BYTE Protocol)
{
switch(Protocol)
{
case 1:
return "ICMP";
case 2:
return "IGMP";
case 4:
return "IP in IP";
case 6:
return "TCP";
case 8:
return "EGP";
case 17:
return "UDP";
case 41:
return "IPv6";
case 46:
return "RSVP";
case 89:
return "OSPF";
default:
return "UNKNOWN";
}
}
void ipparse(FILE* file ,char *buffer)
{
  IP_HEADER ip=*(IP_HEADER *)buffer;
fseek(file,0,SEEK_END);
   
   /*解析版本信息*/
  BYTE version;
  getVersion(ip.Version,version);
  fprintf(file,"版本=%d\r\n",version);
   
  /*解析IP头长度*/
  BYTE headerLen;
  getIHL(ip.HdrLen,headerLen);
  fprintf(file,"头长度=%d(BYTE)\r\n",headerLen);
   
  /*解析服务类型*/
  fprintf(file,"服务类型=%s,%s\r\n",
  parseServiceType_getProcedence(ip.ServiceType),
  parseServiceType_getTOS(ip.ServiceType));
 
  /*解析数据报长度*/
  fprintf(file,"数据报长度=%d(BYTE)\r\n",ip.TotalLen);
 
  /*解析数据报ID*/
  fprintf(file,"数据报ID=%d\r\n",ip.ID);
   
  /*解析标志位*/
  BYTE DF,MF;
  getFlags(ip.Flags,DF,MF);
  fprintf(file,"分段标志 DF=%d,MF=%d\r\n",DF,MF);
 
  /*解析分段偏移*/
  WORD fragOff;
getFragOff(ip.FragOff,fragOff);
  fprintf(file,"分段偏移值=%d\r\n",fragOff);
 
  /*解析生存期*/
  fprintf(file,"生存期=%d(hops)\r\n",ip.TimeToLive);
 
  /*解析协议*/
  fprintf(file,"协议=%s\r\n",getProtocol(ip.Protocol));
 
  /*解析头校验和*/
  fprintf(file,"头校验和=0x%0x\r\n",ip.HdrChksum);
   
  /*解析源IP地址*/
  fprintf(file,"源IP地址=%s\r\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
 
  /*解析目的IP地址*/
  fprintf(file,"目的IP地址=%s\r\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
  fprintf(file,"--------------------------------------------\r\n");
 }
   
 int main(int argc, char * argv[])
 {
  if(argc !=2)
  {
  printf("usage error!\n");
  return -1;
  }
  FILE *file;
  if((file=fopen(argv[1],"wb+"))==NULL)
   {
  printf("fail to open file &s",argv[1]);
return -1;
   }
  WSADATA WSAData;
   /*如果初始化失败,程序退出*/
  if((WSAStartup(MAKEWORD(2,2),&WSAData))!=0)
  {
    printf("WSAStartuo failed!\n");
    return -1;
   }
   //建立原始socket
   SOCKET sock;
   if(sock=(socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET)
 {
  printf("create socket failed!\n");
    return -1;
 }
   bool flag= true;

 //设置ip头操作选项,其中flag设置为true,用户可以亲自对ip头进行处理
 if((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)))==SOCKET_ERROR)
 { 
  printf("setsockopt failed!\n");
  return -1;
 }
     // 获取本机名
 char hostName[128];
 if((gethostname(hostName,100)) ==SOCKET_ERROR)
 {
printf("gethostname failed!\n");
return -1;
 }

//获取本地IP地址
hostent *pHostIP;
if((pHostIP=gethostbyname(hostName))==NULL)
{
printf("gethostbyname failed\n");
return -1;
}

//填充SOCKADDR_IN结构
sockaddr_in addr_in;
addr_in.sin_addr =*(in_addr *)pHostIP->h_addr_list[0];
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);
// addr_in.sin_addr = *(in_addr *)pHostIP->h_addr_list[0]; //IP
// addr_in.sin_family = AF_INET;
// addr_in.sin_port = htons(6000);
//把原始socket绑定到本地网卡上
if((bind(sock,(PSOCKADDR)&addr_in, sizeof(addr_in)))==SOCKET_ERROR)
{
printf("bind failed");
return -1;
}
DWORD dwValue =1;
//设置SOCK_RAW 为SIO_RCVALL,以便接收所有的ip包
#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)
DWORD dwBufferLen[10];
DWORD dwBufferInLen=1;
DWORD dwBytesReturned=0;
if(WSAIoctl(sock,IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),
&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL)==SOCKET_ERROR)
{
printf("ioctlsocket failed\n");
return -1;
}
//设置接收数据包的缓冲区长度
#define BUFFER_SIZE 65535
    char buffer[BUFFER_SIZE];
//监听网卡
printf("开始解析经过本机的IP数据包!\n\n");
while(true)
{
int size=recv(sock,buffer,BUFFER_SIZE,0);
if(size >0)
{
ipparse(stdout,buffer);
ipparse(file,buffer);
}
    }
fclose(file);
return 0;
}

解决方案 »

  1.   

    初学者没有看到WSAGetLastError啊,,哪位大虾帮帮忙,急啊,,谢谢!!!
      

  2.   

    我调试了一下,
    首先
    if(sock=(socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET)
    -----------------------------------------------------------------
    括号位置不对,改成下面这样
    if ( (sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP)) == INVALID_SOCKET)
    然后
    你的问题不是bind 问题,而是在setsockopt  那里执行不下去
    bool flag= true;
    ---------------------------------------------------------------------------
    改成这样
    BOOL flag= TRUE;
    然后,运行正常,这个程序挺不错的,哈哈
      

  3.   

    都改了,可是还是不行,还是说bind failed,是不是我的编译器有问题还是因为系统问题,我用的是VC6.0和xp
      

  4.   

    开始是用2003的,刚才用6.0 试了一下,也没问题啊,偶是2000 server,没有xp