Click here to Skip to main content
15,897,891 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm using Win 7 and Visual Studio 2010. Currently I am getting TCP packets. I have the source address, destination address, Control Bit and Sequence Number. But how do you reassemble the packets to get the http header so that I can check content type of the assembled packet? Any help is appreciated!
Posted
Comments
Sergey Alexandrovich Kryukov 16-Aug-11 22:10pm    
Not clear. What's the purpose of it, of the whole application?
--SA
Member 7766180 17-Aug-11 1:08am    
What isnt clear? I want to reassemble tcp packets si that i can read the http header. Do you know how?
Emilio Garavaglia 17-Aug-11 6:25am    
How did you get the TCP packets?

You are probably operating at the wrong abstraction level.
Resembling of TCP packet should be in charge to the socket library.
You should not deal -at application level- with transport protocol details.
You should just see a stream of characters.
Member 7766180 17-Aug-11 11:49am    
I'm using a console program written in C++ It uses WSA to capture the sockets. I can post some code if needed.
Member 7766180 17-Aug-11 12:59pm    
// http://www.ietf.org/rfc/rfc1700.txt?number=1700


#pragma warning( disable: 4996 )
#include "StdAfx.h"
#include <iostream>
#include <http.h>
#include <conio.h>
#include <fstream>
#include <ws2tcpip.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <c:\\mysql\\include\\mysql.h>

#pragma comment( lib, "ws2_32.lib" ) // linker must use this lib for sockets

// *** Prototypes
void translate_ip(DWORD _ip, char *_cip);
void decode_tcp(char *_packet);
void decode_icmp(char *_packet);
void decode_udp(char *_packet);
void get_this_machine_ip(char *_retIP);

// *** Defines and Typedefs
#define LS_HI_PART(x) ((x>>4) & 0x0F)
#define LS_LO_PART(x) ((x) & 0x0F)
#define LS_MAX_PACKET_SIZE 65535

#ifndef SIO_RCVALL_OFF
# define SIO_RCVALL_OFF _WSAIOW(IOC_VENDOR,1)
#endif

typedef struct _IP_HEADER_
{
BYTE ver_ihl; // Version (4 bits) and Internet Header Length (4 bits)
BYTE type; // Type of Service (8 bits)
WORD length; // Total size of packet (header + data)(16 bits)
WORD packet_id; // (16 bits)
WORD flags_foff; // Flags (3 bits) and Fragment Offset (13 bits)
BYTE time_to_live; // (8 bits)
BYTE protocol; // (8 bits)
WORD hdr_chksum; // Header check sum (16 bits)
DWORD source_ip; // Source Address (32 bits)
DWORD destination_ip; // Destination Address (32 bits)
} IPHEADER;

typedef struct _TCP_HEADER_
{
WORD source_port; // (16 bits)
WORD destination_port; // (16 bits)
DWORD seq_number; // Sequence Number (32 bits)
DWORD ack_number; // Acknowledgment Number (32 bits)
WORD info_ctrl; // Data Offset (4 bits), Reserved (6 bits), Control bits (6 bits)
WORD window; // (16 bits)
WORD checksum; // (16 bits)
WORD urgent_pointer; // (16 bits)
} TCPHEADER;



// *********************************************************************
// MAIN PROGRAM
// *********************************************************************
int main( int _argc, char *_argv[] )
{
MYSQL_RES *res_set;
MYSQL* conn;
MYSQL_ROW LEGIT;
MYSQL_ROW MX;
MYSQL_ROW TTL;
conn = mysql_init(NULL);

struct sockaddr_in sock_sniff;
SOCKET sniff_socket = -1;
WSAData sa_data;
WORD ver;
IPHEADER *ip_header = NULL;
int optval = 1;
DWORD dwLen = 0;
char packet[LS_MAX_PACKET_SIZE];
int iRet = 0;
int ip_header_size = 0;
char ipSrc[20], ipDest[20], LIP[20];
BOOL bShowTCP = TRUE, bShowICMP = TRUE, bShowUDP = TRUE;

// Init Windows sockets version 2.2
ver = MAKEWORD(2,2);
WSAStartup(ver, &sa_data);

// Get a socket in RAW mode
sniff_socket = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
if ( sniff_socket == SOCKET_ERROR )
{
printf( "Error: socket = %ld\n", WSAGetLastError() );
exit(-1);
}

// Bind it
memset( LIP, 0x00, sizeof(LIP) );
get_this_machine_ip(LIP);

sock_sniff.sin_family = AF_INET;
sock_sniff.sin_port = htons(0);


// If your machine has more than one IP you might put another one instead LIP value
sock_sniff.sin_addr.s_addr = inet_addr(LIP);

if ( bind( sniff_socket, (struct sockaddr *)&sock_sniff, sizeof(sock_sniff) ) == SOCKET_ERROR )
{
printf( "Error: bind = %ld\n", WSAGetLastError() );
exit(-2);
}

//Set Socket
if ( WSAIoctl( sniff_socket,
SIO_RCVALL_OFF,
&optval,
sizeof(optval),
NULL,
0,
&dwLen,
NULL,
NULL ) == SOCKET_ERROR )

{
printf( "Error: WSAIoctl = %ld\n", WSAGetLastError() );
exit(-3);
}

while ( TRUE )
{
(void) memset( packet, 0x00, sizeof(packet) );

iRet = recv( sniff_socket, packet, LS_MAX_PACKET_SIZE, 0 );
if ( iRet < sizeof(IPHEADER) )
continue;

ip_header = (IPHEADER *)packet;

// I only want IPv4 not IPv6
if ( LS_HI_

1 solution

It would probably be easier if you use the HTTP Services[^] library.
 
Share this answer
 
Comments
Member 7766180 17-Aug-11 11:53am    
THis all seems very interesting! One question, I'm basically trying to capture all traffic between the internet and my local computer. I want to check for content type and html source code. Do I really need a sniffer or would this do the trick? I am researching this further!
Richard MacCutchan 17-Aug-11 12:18pm    
You need a packet sniffer, but you should also pass all messages along to their final destination. Of course you can write your own but there are a few free ones around.
Member 7766180 17-Aug-11 13:12pm    
I have this code for reassembly. But how do I marry this to the code I posted above?
#include "stdafx.h"
#include <winsock.h>
#include <assert.h>

static const int prefix_size = 2;
static char g_holding_buffer[1000];
static int g_held_bytes = 0;

// Pass in the socket handle, a pointer to a buffer large enough to hold
// the packet, and the size of that buffer. Returns the size of the
// packet received on success, or 0 on failure.

int recv_packet(SOCKET sd, char* p_out_buffer, int buffer_size)
{
int bytes_read = 0;
int packet_size;
bool building_prefix = true;

assert(buffer_size == sizeof(g_holding_buffer));

// Copy any data remaining from previous call into output buffer.
if (g_held_bytes > 0) {
assert(buffer_size >= g_held_bytes);
memcpy(p_out_buffer, g_holding_buffer, g_held_bytes);
bytes_read += g_held_bytes;
g_held_bytes = 0;
}

// Read the packet
while (1) {
if (building_prefix) {
if (bytes_read >= prefix_size) {
packet_size = 0;
for (int i = 0; i < prefix_size; ++i) {
packet_size <<= 8;
packet_size |= p_out_buffer[i];
}
building_prefix = false;
if (packet_size > buffer_size) {
// Buffer's too small to hold the packet!
// Do error handling here.
return 0;
}
}
}

if (!building_prefix && (bytes_read >= packet_size)) {
break; // finished building packet
}

int new_bytes_read = recv(sd, p_out_buffer + bytes_read,
buffer_size - bytes_read, 0);
if ((new_bytes_read == 0) || (new_bytes_read == SOCKET_ERROR)) {
return 0; // do proper error handling here!
}
bytes_read += new_bytes_read;
}

// If anything is left in the read buffer, keep a copy of it
// for the next call.
g_held_bytes = bytes_read - packet_size;
memcpy(g_holding_buffer, p_out_buffer + packet_size, g_held_bytes);

return packet_size;
}
Richard MacCutchan 17-Aug-11 13:51pm    
This is too difficult to read. Please edit your original question and put all your code in the one place.
Member 7766180 17-Aug-11 14:31pm    
Hey Richard perhaps a brief tutorial. It seemds that I have that problem a lot. I'm using VS 2010 and copying the code and pasting here or copying and pasting to notepad, cleaning it up and then pasting it here, Neither with good results! Any suggestions? Thanks!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900