我是靠谱客的博主 文静天空,最近开发中收集的这篇文章主要介绍网络编程---以太网头 IP头 ARP包结构体封装及常用自定义网络转换函数(已测试),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  以下的结构体在实际工程中经过了测试是可以的,自定义函数也经过了测试,到目前为止没有出现问题。

// ---------------------------------------------
// TCP/IP基础结构体和通用函数
// ---------------------------------------------
#ifndef TCPIPCOMMON_H
#define TCPIPCOMMON_H

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <winsock2.h>

typedef unsigned char       u_char;
typedef unsigned short int  u_short;
typedef unsigned int        u_int;
typedef unsigned long       u_long;


// Ethernet
#define ETHERNET_HEAD_LENGTH    14
#define ARP_TYPE            0x0806          //以太头类型:ARP类型
#define IP_TYPE             0x0800          //以太头类型:IPV4类型
#define IPV6_TYPE           0x86dd          //以太头类型,IPV6类型

// ARP Body 28bytes
// ARP Packet(42bytes) = Ethernet(14bytes) + ARP Body(28bytes)
#define ARP_BODY_LENGTH         28
#define ARP_PACKET_LENGTH       42
#define MPLS_TYPE           0x8847
#define IPX_TYPE            0x8137
#define IS_IS_TYPE          0x8000
#define LACP_TYPE           0x8809
#define _802_1x_TYPE        0x888E
#define ARP_HARDWARE        0x0001          //ARP包中:以太网
#define ARP_REQUEST         0x0001
#define ARP_REPLY           0x0002

// IP Header 20bytes
#define IP_HEAD_LENGTH       20
#define IP_VERSION_4        0x04            //IPV4头,版本4
#define IP_VERSION_6        0x06            //IPV4头,版本6

#define IP_TCP_TYPE         0x06            //IPV4头中的协议类型:TCP
#define IP_UDP_TYPE         0x11            //IPV4头中的协议类型:UDP
#define IP_ICMP_TYPE        0x01            //IPV4头中的协议类型:ICMP

// TCP Header 20bytes 因为还没用到,所以没写
#define TCP_HEAD_LENGTH         20


//***********************************************************************************
//常用网络协议自定义结构体
//***********************************************************************************
// Ethernet addresses are 6 bytes
#define ETHER_ADDR_LEN 6
typedef struct _EthernetHeader
{
    u_char DestMAC[ETHER_ADDR_LEN];          //目的MAC地址 6字节
    u_char SourMAC[ETHER_ADDR_LEN];          //源MAC地址 6字节
    u_short EthType;                         //上一层协议类型,如0x0800代表上一层是IP协议,0x0806为arp  2字节
}EthernetHeader;

// 4 bytes IP address
typedef struct _IPAddress{
    u_char byte1;
    u_char byte2;
    u_char byte3;
    u_char byte4;
}IPAddress;

// IPv4 header 20bytes
// IPv6 header 40bytes,这里只是IPv4的协议头
typedef struct _IpHeader{
    u_char  VerIhl;         // 版本4 + 首部长度4Version (4 bits) + Internet header length (4 bits)
    u_char  Tos;            // 服务类型Type of service
    u_short Tlen;           // 总长度Total length,包括IP20字节的头
    u_short Identification; // 标识Identification
    u_short FlagsFo;        // 标志(4 bits)+片偏移(12 bits)Flags (3 bits) + Fragment offset (13 bits)
    u_char  Ttl;            // 生存时间Time to live
    u_char  Proto;          // 协议类型:TCP(6)、UDP(17)、ICMP(1)
    u_short Crc;            // 首部校验和Header checksum
    u_char SourceIpAdd[4];  // 源地址Source address
    u_char DestIpAdd[4];    // 目标地址Destination address
}IPHeader;

// TCP数据包的头部 20 bytes
typedef struct _TCPPacketHeader {
    u_short SrcPort;        //源端口
    u_short DestPort;       //目的端口
    u_int   Seq;            //序列号
    u_int   Ack;            //确认序列号
    u_short Lenres;         //数据偏移4+保留区6+URG+ACK+PSH+RST+SYN+FIN
    u_short Win;            //窗口
    u_short Sum;            //校验和
    u_short Urp;            //紧急指针
}TCPPacketHeader;

// UDP header
typedef struct _UDPHeader{
    u_short SrcPort;        // Source port
    u_short DestPort;       // Destination port
    u_short Len;            // Datagram length
    u_short Crc;            // Checksum
}UDPHeader;


// 28 bytes ARP request/reply
typedef struct _ArpHeader {
    u_short HardwareType;          //硬件类型,2字节,定义运行ARP的网络的类型,以太网是类型1
    u_short ProtocolType;          //协议类型,2字节,定义上层协议类型,对于IPV4协议,该字段值为0800
    u_char HardwareAddLen;         //硬件地址长度,8位字段,定义对应物理地址长度,以太网中这个值为6
    u_char ProtocolAddLen;         //协议地址长度,8位字段,定义以字节为单位的逻辑地址长度,对IPV4协议这个值为4
    u_short OperationField;        //操作字段,数据包类型,ARP请求(值为1),或者ARP应答(值为2)
    u_char SourceMacAdd[6];        //源(发送端)mac地址,可变长度字段,对以太网这个字段是6字节长
    u_char SourceIpAdd[4];         //源(发送短)ip地址,发送端协议地址,可变长度字段,对IP协议,这个字段是4字节长
    u_char DestMacAdd[6];          //目的(接收端)mac地址
    u_char DestIpAdd[4];           //目的(接收端)ip地址,注意不能为u_int型,结构体对其
}ArpHeader;

//arp packet = 14 bytes ethernet header + 28 bytes request/reply
typedef struct _ArpPacket {
    EthernetHeader ed;
    ArpHeader ah;
}ArpPacket;

// host infomation
typedef struct _HostInfo{
    u_char mac[6];
    char ip[16];
    char netmask[16];
    char getwayIp[16];
    u_char gatewayMac[6];
}HostInfo;
//***********************************************************************************
//网络常用转换函数声明和说明
//***********************************************************************************
//my_htonl函数,本机字节序转网络字节序(32位字节序)
//my_ntohl函数,网络字节序转本机字节序(32位字节序)
//my_htons函数,本机字节序转网络字节序(16位字节序)
//my_ntohs函数,网络字节序转本机字节序(16位字节序)
//my_iptos函数,将字节序ip地址转为点分十进制的字符串地址
//iptos   函数,将字节序ip地址转为点分十进制的字符串地址,并获取
//my_inet_addr

// 本机大端返回1,小端返回0
inline int checkCPUendian();

// 模拟htonl函数,本机字节序转网络字节序
inline u_long my_htonl(u_long h);
// 模拟ntohl函数,网络字节序转本机字节序
inline u_long my_ntohl(u_long n);

// 模拟htons函数,本机字节序转网络字节序
inline u_short my_htons(u_short h);

// 模拟ntohs函数,网络字节序转本机字节序
inline u_short my_ntohs(u_short n);

// 数字类型的IP地址转换成点分十进制字符串类型的
inline char *iptos(u_long in,char * ipStr);

// 将字节序ip地址转为点分十进制的字符串地址,并获取
inline char *my_iptos(u_long in);

// 将点分十进制的字符串地址转网络字节整形
inline u_int my_inet_addr(const char *ptr);


//***********************************************************************************
//网络常用转换函数和宏集
//***********************************************************************************

// 短整型大小端互换
#define BigLittleSwap16(A)  ((((u_short)(A) & 0xff00) >> 8) | 
                            (((u_short)(A) & 0x00ff) << 8))
// 长整型大小端互换
#define BigLittleSwap32(A)  ((((u_long)(A) & 0xff000000) >> 24) | 
                            (((u_long)(A) & 0x00ff0000) >> 8) | 
                            (((u_long)(A) & 0x0000ff00) << 8) | 
                            (((u_long)(A) & 0x000000ff) << 24))

// 本机大端返回1,小端返回0
int checkCPUendian()
{
    union{
          u_long i;
          u_char s[4];
    }c;

    c.i = 0x12345678;
    return (0x12 == c.s[0]);
}

// 模拟htonl函数,本机字节序转网络字节序
u_long my_htonl(u_long h)
{
    // 若本机为大端,与网络字节序同,直接返回
    // 若本机为小端,转换成大端再返回
    return checkCPUendian() ? h : BigLittleSwap32(h);
}

// 模拟ntohl函数,网络字节序转本机字节序
u_long my_ntohl(u_long n)
{
    // 若本机为大端,与网络字节序同,直接返回
    // 若本机为小端,网络数据转换成小端再返回
    return checkCPUendian() ? n : BigLittleSwap32(n);
}

// 模拟htons函数,本机字节序转网络字节序
u_short my_htons(u_short h)
{
    // 若本机为大端,与网络字节序同,直接返回
    // 若本机为小端,转换成大端再返回
    return checkCPUendian() ? h : BigLittleSwap16(h);
}

// 模拟ntohs函数,网络字节序转本机字节序
u_short my_ntohs(u_short n)
{
    // 若本机为大端,与网络字节序同,直接返回
    // 若本机为小端,网络数据转换成小端再返回
    return checkCPUendian() ? n : BigLittleSwap16(n);
}

// 数字类型的IP地址转换成点分十进制字符串类型的
char *iptos(u_long in,char * ipStr)
{
    u_char *p;
    p = (u_char *)&in;
    sprintf(ipStr, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    return ipStr;
}

#define IPTOSBUFFERS    12
char *my_iptos(u_long in)
{
    static char output[IPTOSBUFFERS][3*4+3+1];
    static short which;
    u_char *p;

    p = (u_char *)&in;
    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
    sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    return output[which];
}

u_int my_inet_addr(const char *ptr)
{
    int a[4],i=0;
    char str[255] = {0};
    u_long num;

    strcpy(str,ptr);
    char *p1=str,*p2,*p3;
    while(*p1!='' && i<4 ){
        p2=strstr(p1,".");
        if(i!=3){
            p3=p2+1;
            *p2='';
        }
        a[i] = atoi(p1);
        if(a[i]<0 || a[i]>255){
            printf("Invalid IP address!n");
            exit(1);
        }
        p1=p3;
        i++;
     }
     num=a[0]*256*256*256+a[1]*256*256+a[2]*256+a[3];
     return num;
}


#endif // TCPIPCOMMON_H

最后

以上就是文静天空为你收集整理的网络编程---以太网头 IP头 ARP包结构体封装及常用自定义网络转换函数(已测试)的全部内容,希望文章能够帮你解决网络编程---以太网头 IP头 ARP包结构体封装及常用自定义网络转换函数(已测试)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部