Window下c++原始套接字来截包

来源:互联网 发布:安居客网络经纪人平台 编辑:程序博客网 时间:2024/06/04 18:11

最近要交这个作业,紧赶慢赶写出来了,不过写出来后有时候好用有时候不好用,真是醉了,原来是获取本地IP地址时候多块网卡,有时候IP就获取错了,所以运行时最好先看看是哪块网卡,对应的IP对不对。

// WinSocketRaw.cpp : 定义控制台应用程序的入口点。//#include <iostream>#include "winsock2.h"#pragma comment(lib, "ws2_32.lib")using namespace std;struct IP //定义IP首部{    unsigned char h_lenver; //4位首部长度+4位IP版本号    unsigned char tos; //8位服务类型TOS    unsigned short total_len; //16位总长度(字节)    unsigned short ident; //16位标识    unsigned short frag_and_flags; //3位标志位    unsigned char ttl; //8位生存时间 TTL    unsigned char proto; //8位协议 (TCP, UDP 或其他)    unsigned short checksum; //16位IP首部校验和    unsigned int sourceIP; //32位源IP地址    unsigned int destIP; //32位目的IP地址};struct TCP//定义TCP首部{    unsigned short source_port; //16    unsigned short dest_port;    unsigned sequence;   //32    unsigned ack;    unsigned char lenres;   //8    unsigned char flag;    unsigned short win;   //16    unsigned short sum;    unsigned short urp;};struct UDP//定义UDP首部{    unsigned short sport;//16位源端口    unsigned short dport;//16位目的端口    unsigned short len;//UDP 长度    unsigned short cksum;//检查和};/*不处理ICMP数据struct ICMP//定义ICMP首部{    unsigned short sport;    unsigned short dport;    unsigned char type;    unsigned char code;    unsigned short cksum;    unsigned short id;    unsigned short seq;    unsigned long timestamp;};*/int main(){    SOCKET sock;    WSADATA wsd;    char recvInf[65535] = { 0 }; //收到的信息    DWORD dwBytesRet;    int pCount = 0; //收到的包数量    unsigned int optval = 1; //参数值    char * ip = NULL; //对ip数据的指针    char * tcp = NULL; //对tcp数据的指针    char * udp = NULL; //对udp数据的指针    int lentcp, lenudp;    WSAStartup(MAKEWORD(2, 1), &wsd);    if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == SOCKET_ERROR)    {        cout << "启动原始嵌套字出错!" << endl;        exit(-1);    }    //获取本机地址    char  name[MAXBYTE];    gethostname(name, MAXBYTE);    cout << name << endl;    struct hostent FAR * pHostent;    pHostent = (struct hostent *)malloc(sizeof(struct hostent));    pHostent = gethostbyname(name);    //设置    SOCKADDR_IN sa;    sa.sin_family = AF_INET;    sa.sin_addr.s_addr = INADDR_ANY;    //就是这!    memcpy(&sa.sin_addr, pHostent->h_addr_list[2], pHostent->h_length); //设置本机地址*/cout << inet_ntoa(*((struct in_addr*)pHostent->h_addr_list[2])) << endl;//看下IP地址    if (SOCKET_ERROR == bind(sock, (SOCKADDR *)&sa, sizeof(sa)))    {        cout << "绑定出错!" << endl;        exit(-2);    }    //将网卡设置为混杂模式    if(SOCKET_ERROR == WSAIoctl(sock, (IOC_IN|IOC_VENDOR|1), &optval, sizeof(optval), nullptr, 0, &dwBytesRet, nullptr, nullptr))    {        cout << "混杂失败!" << endl;    }    IP * pip = NULL;//IP数据块指针    TCP * ptcp = NULL;//TCP数据块指针    UDP * pudp = NULL;//UDP数据块指针    char szSourceIP[32];//源IP    char szDestIP[32];//目的IP    SOCKADDR_IN saSource;//源地址结构体    SOCKADDR_IN saDest;//目的地址结构体    int lenfrom = sizeof(saSource);    pip = (IP*)recvInf;    while (true)    {        recv(sock, recvInf, sizeof(recvInf), 0);//接收包        //将32位IP地址转为数字 .形式        //只处理TCP UDP信息包        if (!(pip->proto == IPPROTO_TCP || pip->proto == IPPROTO_UDP))            continue;        pCount++;        saSource.sin_addr.s_addr = pip->sourceIP;        strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), 32);        saDest.sin_addr.s_addr = pip->destIP;        strncpy(szDestIP, inet_ntoa(saDest.sin_addr), 32);        lentcp = ntohs(pip->total_len) - (sizeof(IP) + sizeof(TCP));        lenudp = ntohs(pip->total_len) - (sizeof(IP) + sizeof(UDP));        system("cls");        cout << "################第"<< pCount <<  " 号包#######################" << endl;        cout << "******************  IP头部信息  *********************" << endl;        cout << "源IP: " << szSourceIP << endl << "目的IP:" << szDestIP << endl;        //处理TCP包        if (pip->proto == IPPROTO_TCP && lentcp != 0)        {            ptcp = (TCP *)(recvInf + sizeof(IP));            char * data = recvInf + sizeof(IP) + sizeof(TCP); //TCP数据指针            cout << "**************  TCP头部信息  ********************" << endl;            cout << "源端口号:" << ptcp->source_port << endl << "目的端口号:" << ptcp->dest_port << endl;            cout << "数据:" << data << endl;        }        //处理UDP包        if (pip->proto == IPPROTO_UDP && lenudp != 0)        {            pudp = (UDP *)(recvInf + sizeof(IP));            char * data = recvInf + sizeof(IP) + sizeof(UDP); //UDP数据指针            cout << "**************  UDP头部信息  ********************" << endl;            cout << "源端口号:" << pudp->sport << endl << "目的端口号:" << pudp->dport << endl;            cout << "数据:" << data << endl;        }        memset(recvInf, 0, sizeof(recvInf));//清空缓冲区    }}
0 0