Packet Dissection

Hi,

I am trying to dissect a packet from an NDIS Protocol Driver, but i am having trouble disecting from an IP packet to a TCP packet.

Here is the code:



pIPHeader = (PIP_V4) aPacket->Packet;
UINT Length = (pIPHeader->IP_hl & 0xf) * 4;

if(pIPHeader->IP_p == IPV4_TCP)
{
pTCPHeader = (PTCP_HDR) ((PUCHAR) pIPHeader+Length);
DbgPrint(“DPORT: %d SPORT %d”,pTCPHeader->TCP_DPort,pTCPHeader->TCP_SPort);
}

Regards,

Robert, W.

The problem is the converstion from IP to the TCP as the values are incorrect (SPORT and DPORT)

I am using the following Structures for converstion (Based on the Extended PassThrough Driver)


typedef struct _IP_V4
{
#if BYTE_ORDER == LITTLE_ENDIAN
UCHAR IP_hl:4, IP_v:4;
#endif

#if BYTE_ORDER == BIG_ENDIAN
UCHAR IP_v:4, IP_hl:4;
#endif
UCHAR IP_tos;
USHORT IP_len;
USHORT IP_id;
USHORT IP_off;
#define IP_RF 0x8000
#define IP_DF 0x4000
#define IP_MF 0x2000
#define IP_OFFMASK 0x1fff
UCHAR IP_ttl;
UCHAR IP_p;
USHORT IP_sum;
IPV4_ADDRESS IP_src,IP_dst;
} IP_V4, *PIP_V4;


typedef struct TCP_HEADER
{
USHORT TCP_SPort;
USHORT TCP_DPort;
ULONG TCP_Seq;
ULONG TCP_Ack;

#if BYTE_ORDER == LITTLE_ENDIAN
UINT TCP_X2:4, //(unused)
TCP_Off:4; // data offset
#endif

#if BYTE_ORDER == BIG_ENDIAN
UINT TCP_Off:4, //data offset
TCP_X2:4; // (unused)
#endif
UCHAR TCP_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)

USHORT TCP_Win; // window
USHORT TCP_Sum; // checksum
USHORT TCP_Urp; // urgent pointer
} TCP_HDR, *PTCP_HDR;

You need to byte swap the fields into network byte order. Windows offers RtlUshortByteSwap, and the compiler offers _byteswap_ushort.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, February 24, 2011 3:03 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Packet Dissection

The problem is the converstion from IP to the TCP as the values are incorrect (SPORT and DPORT)

I am using the following Structures for converstion (Based on the Extended PassThrough Driver)


typedef struct _IP_V4
{
#if BYTE_ORDER == LITTLE_ENDIAN
UCHAR IP_hl:4, IP_v:4;
#endif

#if BYTE_ORDER == BIG_ENDIAN
UCHAR IP_v:4, IP_hl:4;
#endif
UCHAR IP_tos;
USHORT IP_len;
USHORT IP_id;
USHORT IP_off;
#define IP_RF 0x8000
#define IP_DF 0x4000
#define IP_MF 0x2000
#define IP_OFFMASK 0x1fff
UCHAR IP_ttl;
UCHAR IP_p;
USHORT IP_sum;
IPV4_ADDRESS IP_src,IP_dst;
} IP_V4, *PIP_V4;


typedef struct TCP_HEADER
{
USHORT TCP_SPort;
USHORT TCP_DPort;
ULONG TCP_Seq;
ULONG TCP_Ack;

#if BYTE_ORDER == LITTLE_ENDIAN
UINT TCP_X2:4, //(unused)
TCP_Off:4; // data offset
#endif

#if BYTE_ORDER == BIG_ENDIAN
UINT TCP_Off:4, //data offset
TCP_X2:4; // (unused)
#endif
UCHAR TCP_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)

USHORT TCP_Win; // window
USHORT TCP_Sum; // checksum
USHORT TCP_Urp; // urgent pointer
} TCP_HDR, *PTCP_HDR;


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks That Worked!!!

xxxxx@gmail.com wrote:

The problem is the converstion from IP to the TCP as the values are incorrect (SPORT and DPORT)

I am using the following Structures for converstion (Based on the Extended PassThrough Driver)


typedef struct _IP_V4
{
#if BYTE_ORDER == LITTLE_ENDIAN
UCHAR IP_hl:4, IP_v:4;
#endif
#if BYTE_ORDER == BIG_ENDIAN
UCHAR IP_v:4, IP_hl:4;
#endif

Where did you get that code? I appreciate the sentiment, but those #ifs
are not correct. The ordering of bitfields has no relation to the
endianness of the processor, nor is it related to byte ordering.
Bitfield ordering is strictly a compiler implementation detail. So, you
might say:

#if BITFIELD_ORDER == LSB_FIRST
UCHAR IP_hl:4, IP_v:4;
#endif
#if BITFIELD_ORDER == MSB_FIRST
UCHAR IP_v:4, IP_hl:4;
#endif


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

On Thu, 24 Feb 2011 09:30:32 -0800
Tim Roberts wrote:

> Where did you get that code? I appreciate the sentiment, but those
> #ifs are not correct. The ordering of bitfields has no relation to
> the endianness of the processor, nor is it related to byte ordering.
> Bitfield ordering is strictly a compiler implementation detail.

There’s a suggestion to do something like that (changing the order of
fields depending on the endianess) at
http://stackoverflow.com/questions/724404/converting-endianess-on-a-bit-field-structure .


Bruce Cran

Bruce Cran wrote:

On Thu, 24 Feb 2011 09:30:32 -0800
Tim Roberts wrote
>> Where did you get that code? I appreciate the sentiment, but those
>> #ifs are not correct. The ordering of bitfields has no relation to
>> the endianness of the processor, nor is it related to byte ordering.
>> Bitfield ordering is strictly a compiler implementation detail.
> There’s a suggestion to do something like that (changing the order of
> fields depending on the endianess) at
> http://stackoverflow.com/questions/724404/converting-endianess-on-a-bit-field-structure .

Unfortunately, most of the answers on that page are simply wrong.
Processor endianness is unrelated to bit field ordering. It’s quite
possible to have two compilers on the same computer use opposite
ordering for bitfields. So, given this:

union {
unsigned char x;
struct {
unsigned char b1 : 1;
unsigned char b2 : 7;
};
} abc;
abc.x = 0;
abc.b1 = 1;
printf( “%02x\n”, abc.x );

Unless you happen to have detailed documentation, the only way to know
whether that will print out 01 or 80 is to try it.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.