报文解析各协议结构体

#pragma once

#include <WinSock2.h>


#pragma pack(1)

typedef struct tagEthernetIIPacketTail
{
	UCHAR chDesAddr[6];
	UCHAR chSrcAddr[6];
	USHORT type;
}tagEthernetIIPacketTail;

#pragma pack()


#pragma pack(1)
typedef struct CDataHead
{
	struct timeval ts;
	UINT32 caplen;     /* length of portion present */
	UINT32 len;        /* length this packet (off wire) */
}CDataHeader;

struct CDataHeadAndEthernet
{
	CDataHead header;
	tagEthernetIIPacketTail ethernet;

#define header_ts header.ts
#define header_caplen header.caplen
#define header_len header.len
};
#pragma pack()

#pragma pack(1)

struct iphdr {
	UCHAR ihl:4,
		  version:4;
	UCHAR	tos;
	USHORT	tot_len;
	USHORT	id;
	union{
		USHORT frag_off;

		struct ip_flag
		{
			UCHAR flag_unused:5,
				  flag_MoreFrag:1,
				  flag_DontFrag:1,
				  flag_Reserve:1;
			UCHAR reserve;
		}u_flag;
	}u_flag_off;

	UCHAR	ttl;
	UCHAR	protocol;
	USHORT	check;
	UINT32	saddr;
	UINT32	daddr;
	/*The options start here. */
};
#pragma pack()
#pragma pack(1)
typedef struct arphdr
{
	//arp首部
	unsigned short arp_hrd;    /* format of hardware address */
	unsigned short arp_pro;    /* format of protocol address */
	unsigned char arp_hln;    /* length of hardware address */
	unsigned char arp_pln;    /* length of protocol address */
	unsigned short arp_op;     /* ARP/RARP operation */

	unsigned char arp_sha[6];    /* sender hardware address */
	unsigned long arp_spa;    /* sender protocol address */
	unsigned char arp_tha[6];    /* target hardware address */
	unsigned long arp_tpa;    /* target protocol address */
}ARPHDR, *PARPHDR;
#pragma pack()
#pragma pack(1)
typedef struct DhcpPacketPart
{
	UCHAR op;   // 反向为2
	UCHAR hType;   // 硬件类别,ethernet为1
	UCHAR hLen;    // 硬件长度,ethernet为6 
	UCHAR hops;    // 若数据包需经过router传送,每站加1,若在同一网内,为0 
	UINT32 transactionID;    // 事务ID,是个随机数,用于客户和服务器之间匹配请求和相应消息
	USHORT seconds;    // 由用户指定的时间,指开始地址获取和更新进行后的时间
	USHORT Flags;    // 从0-15bits,最左一bit为1时表示server将以广播方式传送封包给 client,其余尚未使用; 
	UINT32 ciAddr;    // 用户IP地址; 
	UINT32 yiAddr;    // 客户IP地址; 
	UINT32 siAddr;    // 用于bootstrap过程中的IP地址; 
	UINT32 giAddr;    // 转发代理(网关)IP地址; 
	char chaddr[16];    // :client的硬件地址; 
	char sname[64];   // :可选server的名称,以0x00结尾; 
	char File[128];   // 启动文件名; 
	//? Options没有解析,有无表示该选项存在的标志
}DhcpPacketPart;
#pragma pack()
#pragma pack(1)
typedef struct option
{
	UCHAR type;
	UCHAR Len;
	CString value;
}option;
#pragma pack()
#pragma pack(1)
typedef struct DnsPacketPart
{
	unsigned short u16Identification;
	unsigned char rd:1
				  ,tc:1
				  ,aa:1
				  ,Opcode:4
				  ,qa:1;
	unsigned char rcod:4
		          ,cd:1
				  ,ad:1
				  ,z:1
				  ,ra:1;
	unsigned short u16Questions;
	unsigned short u16AnswerRRs;
	unsigned short u16AuthorityRRs;
	unsigned short u16AdditionalRRs;
}DnsPacketPart;
#pragma pack()
#pragma pack(1)
typedef struct tagQuestionInfo
{
	CString wsDomainName;
	USHORT u16Type;
	USHORT u16Class;
}tagQuestionInfo;
#pragma pack()
#pragma pack(1)
typedef struct tagResourceRecordInfo
{
	CString wsDomainName;
	USHORT u16Type;
	USHORT u16Class;
	UINT32 u32TTL;
	USHORT u16RdataLen;
	CString wsRdata;
}tagAnswerInfo;
#pragma pack()
#pragma pack(1)
typedef struct GtpPacketHeader
{
	UCHAR 
         pn:1
		,s:1
		,e:1
		,x:1
		,pt:1
        ,ver:3;   
	UCHAR messageType;   
	USHORT hLen;    
	UINT32 teId;
	USHORT sequenceNumber;  
	UCHAR npduNumber; 
	UCHAR nextExtensionHeaderType;
}GtpPacketHeader;
#pragma pack()
#pragma pack(1)
struct icmp6hdr {

	UCHAR		icmp6_type;
	UCHAR		icmp6_code;
	USHORT		icmp6_cksum;

	union {
		UINT32			un_data32[1];
		USHORT			un_data16[2];
		UCHAR			un_data8[4];

		struct icmpv6_echo {
			USHORT		identifier;
			USHORT		sequence;
		} u_echo;

		struct icmpv6_nd_advt {
			UINT32		router:1,
						solicited:1,
						override:1,
						reserved:29;
		} u_nd_advt;

		struct icmpv6_nd_ra {
			UCHAR		hop_limit;
			UCHAR		managed:1,
						other:1,
						router_pref:2,
						reserved:4;
			USHORT		rt_lifetime;
		} u_nd_ra;

	} icmp6_dataun;

#define icmp6_identifier	icmp6_dataun.u_echo.identifier
#define icmp6_sequence		icmp6_dataun.u_echo.sequence
#define icmp6_pointer		icmp6_dataun.un_data32[0]
#define icmp6_mtu		icmp6_dataun.un_data32[0]
#define icmp6_unused		icmp6_dataun.un_data32[0]
#define icmp6_maxdelay		icmp6_dataun.un_data16[0]
#define icmp6_nextHopMTU	icmp6_dataun.un_data16[1]
#define icmp6_router		icmp6_dataun.u_nd_advt.router
#define icmp6_solicited		icmp6_dataun.u_nd_advt.solicited
#define icmp6_override		icmp6_dataun.u_nd_advt.override
#define icmp6_ndiscreserved	icmp6_dataun.u_nd_advt.reserved
#define icmp6_hop_limit		icmp6_dataun.u_nd_ra.hop_limit
#define icmp6_addrconf_managed	icmp6_dataun.u_nd_ra.managed
#define icmp6_addrconf_other	icmp6_dataun.u_nd_ra.other
#define icmp6_rt_lifetime	icmp6_dataun.u_nd_ra.rt_lifetime
#define icmp6_router_pref	icmp6_dataun.u_nd_ra.router_pref
};
#pragma pack()
#pragma pack(1)
typedef struct RtpPacketPart
{
	USHORT 
		 pt:7
		,m:1
		,cc:4
		,x:1
		,p:1
		,ver:2;   
	USHORT sequenceNumber;   
	UINT32 timestamp;    
	UINT32 ssrc;    
	//? CSRC没有解析,有无表示该选项存在的标志
}RtpPacketPart;
#pragma pack()
#pragma pack(1)
typedef struct StpPacketPart
{
	USHORT protocolIndentifier;   
	UCHAR ver;   
	UCHAR messageType;    
	UCHAR flages; 
	USHORT rootPriority;
	UCHAR rootId[6];    
	UINT32 rotPathCost;  
	USHORT bridgePriority;
	UCHAR	bridgeId[6];    
	USHORT portId;    
	USHORT messageAge;    
	USHORT maximum;    
	USHORT helloTime;     
	USHORT forwardDelay;    
}StpPacketPart;
#pragma pack()
#pragma pack(1)
typedef struct tcphdr {
	USHORT	source;
	USHORT	dest;
	UINT32	seq;
	UINT32	ack_seq;
	UCHAR	res1:4,
		    doff:4;
	UCHAR	fin:1,
			syn:1,
			rst:1,
			psh:1,
			ack:1,
			urg:1,
			ece:1,
			cwr:1;
	USHORT	window;
	USHORT	check;
	USHORT	urg_ptr;
}TCPHDR,*PTCPHDR;
#pragma pack()
#pragma pack(1)
typedef struct tcpoption
{
	CString value;
}TCPOPTION;
#pragma pack()
#pragma pack(1)
typedef struct udphdr {
	USHORT  source;
	USHORT  dest;
	USHORT  len;
	USHORT check;
}UDPHDR, *PUDPHDR;
#pragma pack()
#pragma pack(1)
typedef struct VrrpPacketPart
{
	unsigned char u8VerAndType;
	unsigned char u8VirtualRtrID;
	unsigned char u8Priority;
	unsigned char u8CountIPAddrs;
	unsigned char u8AuthType;
	unsigned char u8AdverInt;
	USHORT	u16Checksum;
}VrrpPacketPart;

#pragma pack()

#pragma pack(1)

typedef union {
	unsigned char b[4];
	UINT32 l;
} IPaddr;

#pragma pack()


最近在做中国银行的一个快捷支付渠道,使用的是 ISO8583 协议,一开始用的是JPOS框架,但是感觉框架比较臃肿,而且文档也比较少。在等待银行专线的过程中,自己闭门造车做了一个简单的8583报文解析框架 —— Simple8583,将程序重写了一遍,渠道中的代码量少了不少,这几天中行的接口在测试环境终于调试完成了。抽空分享一下这段时间自己学到的知识。 数据类型与编码格式: 根据接触到的数据类型将数据分为如下几种类型:          CHAR(asc编码,直接使用字符串的getBytes(ENCODING)方法获取字节数组)   BINARY(二进制编码,在打包时将8位01值组装为一个字节),             NUMERIC(BCD编码,即8421码),                LLVAR(变长域,采用ASC编码,每个LLVAR类型的域前会有1字节的域字节长度,表示长度的字节用BCD编码表示)                LLLVAR(变长域,与LLVAR域类似,不同之处在于每个LLLVAR域前会有2字节的域字节长度,长度同样以BCD编码表示)             LLVAR_NUMERIC(变长域,采用BCD编码,前有1字节的长度,长度为域值的长度,而非字节长,如域值为123456,编码后长度为3字节,但是表示域长的字节值为6)       如果用到其它数据类型可以在IsoType中进行添加,并在IsoField中添加处理操作 BitMap:        BitMap是ISO8583报文的精髓所在,ISO8583报文支持64域和128域两种,但是并非每次请求都会将所有域都请求过去,BItMap就起到了标识哪些域是有效的请求域,接收方也会根据BitMap中约定的值对域进行解析。   那么BitMap又是如何工作的呢?          首先,BItMap分为8字节和16字节两种情况,分别表示支持64域和128域,其第一位值为1,表示BitMap为16字节,否则为8字节。       其次,BitMap中的每一位对应数据域的第几域,有效域会置为1,比如01001000表示第二域和第5域为有效位。 在Simple8583中具体的实现是通过BitMap类实现的,具体可参考源码。 mti:            mti即 message type identifier消息类型标识,为4位bcd编码的数字标识符,用于描述信息的类型。 同一个mti可以用于标识多个不同的交易,比如一般常用的0200可以用来表示消费交易,消费撤销,分期付款消费和分期付款撤销,但是对于同一个mti标识的数据域类型定义是类似的。           具体的实现,我将Simple8583的xml文件设置为了两部分,一部分为公用的报文头,如msgLength,tpdu,bitmap等,另外一部分分按照mti的不同分为多个package体。 粗略的实现流程:          1)组装请求的Map数据(只组装需要的数据域,key值为对应的数据域或包头的值)          2)请求数据进入SimpleClient代理,SimpleClient根据传入的值解析xml文件(jaxb实现,做了缓存)          3)根据传入值的mti寻找对应的IsoPackage类,对找到的IsoPackage类进行clone(避免污染),对clone值中的域进行值处理和格式化         4)生成BitMap,计算Mac值(如有)          5)使用ByteArrayOutputStream将组装成的IsoPackage域值进行拼装成为一个大的byte数组,在byte前拼装两个字节的长度          6)通过Socket将数据发送并接受响应(读取前两个字节长度,根据长度获取其剩余报文),根据IsoPackage解析报文域,解析得到BitMap后根据BitMap对数据域进行解析,并将值都放入到对应的field中          7)将数据都放在Map中返回,并进行MAC校验(如有) 标签:Simple8583
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT_NEU_2009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值