无名侠 发表于 2015-4-12 10:17:27

原始套接字代码笔记,可做嗅探器

本帖最后由 无名侠 于 2015-4-12 10:20 编辑

当是我学习计算机网络的笔记吧,不过是代码。得到数据没特别的处理,只是提取出IP报头里面的源地址和目的地址。如果上层是TCP/IP协议就提取出目的端口和源端口。
什么用?
    嗅探工具的基础。实现FTP密码嗅探是很容易的哦。typedef struct _iphdr
{
    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;       //16位偏移量
    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地址
}IP_HEADER;
typedef struct _tcphdr               //定义TCP首部
{
    USHORT th_sport;                //16位源端口
    USHORT th_dport;               //16位目的端口
    unsigned int th_seq;                  //32位序列号
    unsigned int th_ack;               //32位确认号
    unsigned char th_lenres;            //4位首部长度/6位保留字
    unsigned char th_flag;            //6位标志位
    USHORT th_win;               //16位窗口大小
    USHORT th_sum;            //16位校验和
    USHORT th_urp;               //16位紧急数据偏移量
}TCP_HEADER;#include "stdafx.h"
#include <WinSock2.h>
#define   SIO_RCVALL   _WSAIOW(IOC_VENDOR,1)
#pragma comment(lib,"ws2_32.lib")

typedef struct _iphdr
{
    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;       //16位偏移量
    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地址
}IP_HEADER;
typedef struct _tcphdr               //定义TCP首部
{
    USHORT th_sport;                //16位源端口
    USHORT th_dport;               //16位目的端口
    unsigned int th_seq;                  //32位序列号
    unsigned int th_ack;               //32位确认号
    unsigned char th_lenres;            //4位首部长度/6位保留字
    unsigned char th_flag;            //6位标志位
    USHORT th_win;               //16位窗口大小
    USHORT th_sum;            //16位校验和
    USHORT th_urp;               //16位紧急数据偏移量
}TCP_HEADER;


//////////////////////////////////////////////////////////////////////////
//初始化套接字
bool InitSocket()
{
    WSADATA wsdata={0};
    return !WSAStartup(MAKEWORD(2,2),&wsdata);
}
//解析TCP头部
void DecodeTcpPacket(char *pData)
{
    TCP_HEADER *pTcp;
    pTcp=(TCP_HEADER *)pData;
    printf("端口:%d\n",ntohs(pTcp->th_sport));
}
//解码IP头部
void DecodeIpPacket(char *pData)
{
    IP_HEADER *pIp;
    in_addr Sip,Dip;
    char szDip={0},szSip={0};
    pIp = (IP_HEADER *)pData;
    Sip.S_un.S_addr = pIp->sourceIP;
    Dip.S_un.S_addr=pIp->destIP;
    strcpy(szDip,inet_ntoa(Dip));
    strcpy(szSip,inet_ntoa(Sip));
    printf("源IP:%s\n目标IP:%s\n",szSip,szDip);
    switch (pIp->proto)
    {
    case IPPROTO_TCP:
      printf("协议:TCP\n");
      DecodeTcpPacket(&pData);
      break;
    case IPPROTO_UDP:
      printf("协议:UDP\n");
      break;
    caseIPPROTO_ICMP:
      printf("协议:ICMP\n");
      break;
    default:
      break;
    }
}
//////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
    if (!InitSocket())
    {
      printf("初始化Socket库失败!\n");
      getchar();
    }
    /////   变量      /////
    SOCKETsock;
    SOCKADDR_IN SourceAddr={0};      //源地址
    char HostName={0};   //主机名
    char DataBuffer={0};   //数据缓冲区
    ////    代码      ////
    sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
    if(sock==INVALID_SOCKET)
    {
      printf("创建套接字失败!\n");
      getchar();
    }
    if(SOCKET_ERROR==gethostname(HostName,sizeof(HostName)))
    {
herr:

      printf("获取主机名失败!\n");
      closesocket(sock);
      getchar();
    }
    printf("主机名:%s\n",HostName);
    HOSTENT *host=gethostbyname(HostName);
    if(!host)goto herr;
    memcpy(&SourceAddr.sin_addr.S_un.S_addr,host->h_addr_list,host->h_length);
    SourceAddr.sin_port=0;
    SourceAddr.sin_family=AF_INET;
    //打印主机IP
    printf("IP:%s\n",inet_ntoa(SourceAddr.sin_addr));
    //绑定
    if(SOCKET_ERROR==bind(sock,(PSOCKADDR)&SourceAddr,sizeof(SOCKADDR_IN)))
    {
      printf("绑定失败!\n");
      closesocket(sock);
      getchar();
    }
    //// 设置混杂模式
    DWORD dw=1;
    if(ioctlsocket(sock,SIO_RCVALL,&dw)!=0)
    {
      printf("设置混杂模式失败!\n");
      closesocket(sock);
      getchar();
    }

    while (true)
    {
      DWORD DataLen;
      DataLen=recv(sock,DataBuffer,1024,0);
      if (DataLen>0)
      {
            printf("------------------------------------\n");
            DecodeIpPacket(DataBuffer);
      }
    }

    return 0;
}


拈花小仙 发表于 2015-4-12 16:26:18

{:7_139:}侠侠好厉害,多多分享哦~

myqicq 发表于 2015-4-12 21:21:32

谢谢分享,祝君好运.

zhai_123 发表于 2015-5-12 23:42:56

:titter:

citian3094 发表于 2015-5-22 17:03:04

谢谢分享!!!

溯月0503 发表于 2015-5-25 18:00:36

{:1_1:}

逆战时代 发表于 2015-5-27 19:48:04

LZ好人。。。。。。。。

zhy755788055 发表于 2017-2-22 16:35:29

不能抓取链路层的包
页: [1]
查看完整版本: 原始套接字代码笔记,可做嗅探器