2 kostart123 kostart123 于 2016.02.28 20:41 提问

为什么我编的抓包程序抓的TCP包源地址都是本机地址啊,下面是源码,新手求大神指点!!

#include
#include
#include

using namespace std;

#define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1)
#define MAXLEN 65535
//定义IP报头
typedef struct _iph
{
unsigned char ver_len;
unsigned char ser;
unsigned short datalen;
unsigned short ident;
unsigned short flag;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;
}iph;

//定义TCP报头
typedef struct _tcph
{
unsigned short sourceport;
unsigned short destport;
unsigned int linum;
unsigned int trnum;
unsigned char flag;
unsigned char baoliu;
unsigned char ident;
unsigned short win;
unsigned short checksum;
unsigned short jinji;
}tcph;

//定义ICMP报头
typedef struct _icmphdr //定义 ICMP 报头(回送与或回送响应)
{

unsigned char i_type;//8 位类型
unsigned char i_code; //8 位代码

unsigned short i_cksum; //16 位校验和

unsigned short i_id; //识别号(一般用进程号作为识别号)

unsigned short i_seq; //报文序列号

unsigned int timestamp;//时间戳

}icmph;

void main()
{
//加载套接字库
WSAData data;
if(::WSAStartup(MAKEWORD(2,0),&data))
{
cout<<"winsock库加载失败!"<<endl;
return;
}

//创建原始套接字
SOCKET sock;
sockaddr_in addr;
sock=::socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(INVALID_SOCKET==sock)
{
    cout<<"sock初始化失败!"<<endl;
    return;
}

//获得本机一个IP地址
char name[30]="";
::gethostname(name,30);
hostent *h=::gethostbyname(name);
::memcpy(&addr.sin_addr.S_un.S_addr,h->h_addr_list[h->h_length-1],h->h_length);
addr.sin_family=AF_INET;
addr.sin_port=htons(0);

//绑定地址
if(SOCKET_ERROR==::bind(sock,(SOCKADDR*)&addr,sizeof(addr)))
{
    cout<<"sock绑定失败!!"<<endl;
    return;
}

//设置网卡为混杂模式
u_long mk=1;
if(SOCKET_ERROR==::ioctlsocket(sock,SIO_RCVALL,&mk))
{
    cout<<"网卡的混杂模式设置失败!错误号:"<<::WSAGetLastError()<<endl;
    return;
}

cout<<"协议   源地址           目的地址    数据长度    TTL"<<endl;

char buf[MAXLEN]="";
iph *iphead;
tcph *tcphead=(tcph*)(buf+sizeof(iph));
icmph *icmphead=(icmph*)(buf+sizeof(iph));
int i=0;
sockaddr_in add;

//接收IP包
while(i<100)
{
    if(SOCKET_ERROR==::recv(sock,buf,MAXLEN,0))
    {
        cout<<"接收发生错误!!"<<endl;
        return;
    }
    iphead=(iph*)buf;
    if(iphead->proto==6)                    //TCP
    {
        add.sin_addr.S_un.S_addr=iphead->sourceIP;
        cout<<"TCP  "<<inet_ntoa(add.sin_addr)<<':'<<ntohs(tcphead->sourceport)<<"  ";
        add.sin_addr.S_un.S_addr=iphead->destIP;
        cout<<inet_ntoa(add.sin_addr)<<':'<<ntohs(tcphead->destport)<<" "<<ntohs(iphead->datalen)<<"        "<<(int)iphead->ttl<<endl;
    }
    if(iphead->proto==1)                    //ICMP
    {
        add.sin_addr.S_un.S_addr=iphead->sourceIP;
        cout<<"ICMP  "<<inet_ntoa(add.sin_addr)<<"   ";
        add.sin_addr.S_un.S_addr=iphead->destIP;
        cout<<inet_ntoa(add.sin_addr)<<"  ";
        char *p=buf+sizeof(iph)+sizeof(icmph)-4;
        cout<<p<<endl;
    }
    memset(buf,0,MAXLEN);
}

}


1个回答

mengyin521
mengyin521   2016.02.28 22:26
已采纳

先看下 《SOCKET 网络编程》吧!
把套接字 地址 监听 绑定 阻塞 这些都搞明白了 你就清楚了!

kostart123
kostart123 回复M醉清风Y: 好哒,谢了。
接近 2 年之前 回复
mengyin521
mengyin521 回复kostart123: 注意在接收消息的时候 线程的掌握 有问题可以在找我
接近 2 年之前 回复
kostart123
kostart123 回复M醉清风Y: 恩,看来还是要稳扎稳打,我就看了几个例子就自己随便写了下,结果出错了也不知道怎么回事。谢谢你的推荐,那我就采纳了。
接近 2 年之前 回复
mengyin521
mengyin521 回复kostart123: 就搜索 SOCKET 编程 就好,这块不难 到了后期优化和效率 涉及的技术会多一些,例如进程池、线程池、内存池,服务器架构模型、登录 安全 数据库 一系列的就全来了
接近 2 年之前 回复
kostart123
kostart123 你那里有这些资源吗?网上找了好久,没找到好的。原始套接字这方面好多不懂,有什么这方面的比较详细的教程推荐下。谢谢!
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!