网络数据包查看

本文深入探讨了网络数据包中的UDP、ICMP和TCP头部格式,详细解析了各部分字段,帮助读者理解网络通信的基础原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

#include<stdio.h>
#include<string.h>
#include<Winsock2.h>
#include<ws2tcpip.h>
#include<time.h>
#pragma comment(lib,"WS2_32.lib") //载入windows下socket
/*========================================================*/
/* 下面这段程序为兼容windows环境下各版本socket定义                                */
/*=========================================================*/
#ifndef _MSTCPIP_INC
#define _MSTCPIP_INC
// Copyright (C) Microsoft Corporation, 1996-1999
#if _MSC_VCR >1000
#pragma once
#endif
/* Argument structure for SIO_KEEPALIVE_VALS */
struct tcp_keepalive
{
 u_long onoff;
 u_long keepalivetime;
 u_long keepaliveinterval;
};
/* New WSAIoctl Options */
#define SIO_RCVALL                 _WSAIOW(IOC_VENDOR,1)
#define SIO_RCVALL_MCAST           _WSAIOW(IOC_VENDOR,2)
#define SIO_RCVALL_IGMPMCAST       _WSAIOW(IOC_VENDOR,3)
#define SIO_KEEPALIVE_VALS         _WSAIOW(IOC_VENDOR,4) 
#define SIO_ABSORB_RTRALERT        _WSAIOW(IOC_VENDOR,5)
#define SIO_UCAST_IF             _WSAIOW(IOC_VENDOR,6)
#define SIO_LIMIT_BROADCASTS        _WSAIOW(IOC_VENDOR,7)
#define SIO_INDEX_BIND              _WSAIOW(IOC_VENDOR,8)
#define SIO_INDEX_MCASTIF           _WSAIOW(IOC_VENDOR,9)
#endif 
/*=================================================================*/
/*start..                                                          */
struct IPHeader
{
 unsigned char Version_HLen;    //版本号
 unsigned char TOS;             //服务类型
 unsigned short Length;         //总长度
 unsigned short Ident;          //标识
 unsigned short Flags_Offset;   //段偏移量
 unsigned char TTL;              //生存周期
 unsigned char Protocol;          //协议
 unsigned short Checksum;         //校验和
 unsigned int  SourceAddr;        //源地址
 unsigned int  DestinationAddr;    //目的地址
};
struct TcpHeader
{
 unsigned short SrcPort;
 unsigned short DstPort;
 unsigned int SequenceNum;
 unsigned int Acknowledgment;
 unsigned char HdrLen;
 unsigned char Flags;
 unsigned short AdvertisedWindow;
 unsigned short Checksum;
 unsigned short UrgPtr;
};
struct UdpHeader
{
 unsigned short SrcPort;
 unsigned short DstPort;
 unsigned short Length;
 unsigned short Checksum;
};
struct IcmpHeader
{
 BYTE Type;
 BYTE Code;
 USHORT Checksum;
 USHORT ID;
 USHORT Sequence;
};
struct IcmpHeaderEcho
{
 BYTE Type;
 BYTE Code;
 USHORT Checksum;
 USHORT ID;
 USHORT Sequence;
};
/*=================================================================*/
/* main函数,可在dos命令下启动.                                    */
int main(int argc, char **argv)
{
 SOCKET SnifferSocket;
 int Result;
 char Packet[65535]={0};
 char Name[255];
 HANDLE hCon;
 WSADATA wsaData;
 DWORD dwBufferLen[10];  //双字结构缓冲区
 DWORD dwBufferInLen=1;
 DWORD dwBytesReturned=0;
 struct hostent *pHostent; // 主机名
 Result=WSAStartup(MAKEWORD(2,1),&wsaData); //启动 socket
 if(Result == SOCKET_ERROR)
 {
  printf("WSAstartup failed with error %d\n",Result);
  return 0;
 }
 SnifferSocket=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
 if(Result == SOCKET_ERROR)
 {
  printf("socket failed with error %d\n",WSAGetLastError());
  closesocket(SnifferSocket);
  return 0;
 }
 Result=gethostname(Name,255); //取主机的前255字符做网络名称
 if(Result == SOCKET_ERROR)
 {
  printf("gethostname failed with error %d\n",WSAGetLastError());
  closesocket(SnifferSocket);
  return 0;
 }
 pHostent=(struct hostent *)malloc(sizeof(struct hostent));
 pHostent=gethostbyname(Name);
 SOCKADDR_IN sock;
 sock.sin_family=AF_INET;
 sock.sin_port=htons(6666); // 设定主机端口为666666
 memcpy(&sock.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_length);
 Result=bind(SnifferSocket,(PSOCKADDR)&sock,sizeof(sock)); //绑定主机端口与IP
 if(Result == SOCKET_ERROR)
 {
  printf("%d",SOCKET_ERROR);
  printf("OK");
  printf("bind failed with error %d\n",WSAGetLastError());
  closesocket(SnifferSocket);
  return 0;
 }
 Result=WSAIoctl(SnifferSocket,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,
  sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);
 if(Result == SOCKET_ERROR)
 {
  printf("WSAIoctl failed with error %d\n",WSAGetLastError());
  closesocket(SnifferSocket);
  return 0;
 }
 hCon=GetStdHandle(STD_OUTPUT_HANDLE); //获得进程句柄
 CONSOLE_SCREEN_BUFFER_INFO bInfo;
 GetConsoleScreenBufferInfo(hCon,&bInfo);
 printf("-----------------获取网络上数据包---------------\n");
 while(true)
 {
  memset(Packet,0,sizeof(Packet));
  Result=recv(SnifferSocket,Packet,sizeof(Packet),0);
  if(Result==SOCKET_ERROR)
  {
   printf("recv failed with error %d\n",WSAGetLastError());
   closesocket(SnifferSocket);
   return 0;
  }
  SetConsoleTextAttribute(hCon,15);//文本颜色设置为15号
  int static packetcount=0;
  packetcount++;
  time_t temp;
  time(&temp);
  printf("\n");
  printf("Packet:%d Time:%s",packetcount,ctime(&temp));
  SetConsoleTextAttribute(hCon,bInfo.wAttributes);
  //将捕获的数据输出到控制台缓冲区
  SetConsoleTextAttribute(hCon,14);
  printf("IP Header:\n");
  struct IPHeader *ip=(struct IPHeader *)Packet;
  int IpHeaderLength=(ip->Version_HLen &0x0f)*4;
  printf("Version:%d\n",ip->Version_HLen>>4);
  printf("Header Length:%d\n",(ip->Version_HLen &0x0f)*4);
  printf("TOS:%d\n",ip->TOS);
  printf("Length:%d\n",ntohs(ip->Length));
  printf("Flags:%d\n",ntohs(ip->Flags_Offset)>>13);
  printf("---Reserved bit:%d\n",(ntohs(ip->Flags_Offset)&0x8000)>>15);
  printf("---Don't fragment:%d\n",(ntohs(ip->Flags_Offset)&0x4000)>>14);
  printf("---More fragments:%d\n",(ntohs(ip->Flags_Offset)&0x2000)>>13);
  printf("Fragment offset:%d\n",ntohs(ip->Flags_Offset)&0x1fff);
  printf("Ident:%d\n",ntohs(ip->Ident));
  printf("TTL:%d",ip->TTL);
  printf("Protocol:%d\n",ip->Protocol);
  printf("Checksum:%d\n",ntohs(ip->Checksum));
  SOCKADDR_IN addr;
  addr.sin_addr.s_addr=ip->SourceAddr;
  printf("Source IP:%s\n",inet_ntoa(addr.sin_addr));
  addr.sin_addr.s_addr=ip->DestinationAddr;
  printf("Destination IP:%s\n",inet_ntoa(addr.sin_addr));
  SetConsoleTextAttribute(hCon,bInfo.wAttributes);
  int Protocol=ip->Protocol;
  if(Protocol == 6)  // 协议号为6,TCP 协议
  {
   SetConsoleTextAttribute(hCon,13);
   int IpHeaderLength=(ip->Version_HLen &0x0f)*4;
   printf("TCP Header:\n");
   struct TcpHeader *tcp=(struct TcpHeader *)(Packet + IpHeaderLength);
   printf("Source Port:%d\n",ntohs(tcp->SrcPort));
   printf("Destination Port:%d\n",ntohs(tcp->DstPort));
   printf("SequenceNum:%u\n",ntohl(tcp->SequenceNum));
   printf("Acknowledgement:%u\n",ntohl(tcp->Acknowledgment));
   printf("Header Length:%d\n",(tcp->HdrLen>>4)*4);
   printf("Flags:\n");
   /*打印6个标识位,这里需将flags里面的位进行过滤,第一个标识和0x01进行按位与,第二个标识与0x02按位与,
   依次类推*/
   printf("---FIN:%d\n",(tcp->Flags &0x01)>0?1:0);
   printf("---SYN:%d\n",(tcp->Flags &0x02)>0?1:0);
   printf("---RST:%d\n",(tcp->Flags &0x04)>0?1:0);
   printf("---PSH:%d\n",(tcp->Flags &0x08)>0?1:0);
   printf("---ACK:%d\n",(tcp->Flags &0x10)>0?1:0);
   printf("---URG:%d\n",(tcp->Flags &0x20)>0?1:0);
   printf("AdvertisedWindow:%d\n",ntohs(tcp->AdvertisedWindow));
   printf("Checkesum:%d\n",ntohs(tcp->Checksum));
   printf("UrgPtr:%d\n",ntohs(tcp->UrgPtr));
   SetConsoleTextAttribute(hCon,bInfo.wAttributes);
  }
  if(Protocol ==17) //协议号17,UDP协议
  {
   SetConsoleTextAttribute(hCon,12);
   printf("UDP Header:\n");
   struct UdpHeader *udp=(struct UdpHeader *)(Packet + IpHeaderLength);
   printf("Source Port:%d\n",ntohs(udp->SrcPort));
   printf("Destination Port:%d\n",ntohs(udp->DstPort));
   printf("Length:%u\n",ntohs(udp->Length));
   printf("Checksum:%u\n",ntohs(udp->Checksum));
   SetConsoleTextAttribute(hCon,bInfo.wAttributes);
  }
  if(Protocol ==1) //协议号1,ICMP协议
  {
   SetConsoleTextAttribute(hCon,11);
   printf("ICMP Header:\n");
   struct IcmpHeader *icmp=(struct IcmpHeader *)(Packet + IpHeaderLength);
   printf("Type:%d\n",icmp->Type);
   printf("Code:%d\n",icmp->Code);
   printf("Checksum:%u\n",ntohs(icmp->Checksum));
   int Type=icmp->Type;
   int Code=icmp->Code;
   // ICMP请求数据包
   if(Type==0 && Code==0)
   {
    printf("Echo Reply\n");
    struct IcmpHeaderEcho *echo=(struct IcmpHeaderEcho *)(Packet + IpHeaderLength);
    printf("ID:%d\n",ntohs(echo->ID));
    printf("Sequence:%d\n",ntohs(echo->Sequence));
   }
   if(Type==8 && Code==0) // ICMP 回执数据包
   {
    printf("Echo Request\n");
    struct IcmpHeaderEcho *echo=(struct IcmpHeaderEcho *)(Packet + IpHeaderLength);
    printf("ID:%d\n",ntohs(echo->ID));
    printf("Sequence:%d\n",ntohs(echo->Sequence));
   }
   if(Type == 13)
    printf("Timestamp Request\n");
   if(Type == 14)
    printf("Timestamp Reply\n");
   if(Type == 17)
    printf("Mask Request\n");
   if(Type == 18)
    printf("Mask Reply\n");
   SetConsoleTextAttribute(hCon,bInfo.wAttributes);
  }
  printf("IP Data:\n");
  unsigned char*IpData=(unsigned char *)Packet + IpHeaderLength;
  int IpTotalLength=ntohs(ip->Length);
  int IpDataLength=IpTotalLength-IpHeaderLength;
  char IpDataOut[65535]={0};
  int end=0;
  if(IpDataLength > 0)
  {
   for(int i=0;i<IpDataLength;i++)
   {
    SetConsoleTextAttribute(hCon,14);
    printf("%OX",IpData[i]);
    SetConsoleTextAttribute(hCon,bInfo.wAttributes);
    if(isgraph(IpData[i]))
     IpDataOut[end]=IpData[i];
    else if(IpData[i] == ' ')
     IpDataOut[end]=IpData[i];
    else
     IpDataOut[end]='.';
    ++end;
    if(i%16 == 15)
    {
     SetConsoleTextAttribute(hCon,10);
     IpDataOut[end]=0;
     printf("    %s",IpDataOut);
     end=0;
     printf("\n");
     SetConsoleTextAttribute(hCon,bInfo.wAttributes);
    }
   }
   if(end>0)
   {
    for(int k=end*2;k<32;k++)
     printf(" ");
    IpDataOut[end]=0;
    SetConsoleTextAttribute(hCon,10);
    printf("    %s",IpDataOut);
    SetConsoleTextAttribute(hCon,bInfo.wAttributes);
    printf("\n");
   }
  }
 }
 if(closesocket(SnifferSocket) == SOCKET_ERROR) //捕获异常
 {
  printf("closesocket failed with error %d\n",WSAGetLastError());
  return 0;
 }
 if(WSACleanup() == SOCKET_ERROR)
 {
  printf("WSACleanup failed with error %d\n",WSAGetLastError());
  return 0;
 }
 return 1;
}


  UDP头部格式

 

ICMP头部格式

 

 

TCP头部格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值