I try to calculate the start of the HTTP header of a packet, for example
GET /test.html HTTP1.1
Host: example.com
...
With WinPcap in C i try
ih = (ip_header *) (pkt_data + 14);
ip_len = (ih->ver_ihl & 0xf) * 4;
th = (tcp_header *) ((u_char*)ih + ip_len);
tcp_len = (((u_char*)ih)[ip_len + 12] >> 4) * 4;
tcp_payload = (u_char*)ih + ip_len + tcp_len;
url = tcp_payload + 4;
end_url = strchr((char*)url, ' ');
url_length = end_url - url;
req_url = (u_char*)malloc(url_length+1);
strncpy((char*)req_url, (char*)url, url_length);
req_url[url_length] = '\0';
printf("%s", req_url);
The output is sometimes correct but sometimes it prints some part of a cookie or cept-Encodin
what is definitely part of the http headerbut at the wrong position. i think maybe some tcp payloads are different in length because of some extra fields but i have no idea how to check? Thank you
#include <stdio.h>
#include <string.h>
#include "pcap.h"
#include <windows.h>
#include <winsock.h>
/* 4 bytes IP address */
typedef struct ip_address{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;
/* IPv4 header */
typedef struct ip_header{
u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
u_char tos; // Type of service
u_short tlen; // Total length
u_short identification; // Identification
u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
u_char ttl; // Time to live
u_char proto; // Protocol
u_short crc; // Header checksum
ip_address saddr; // Source address
ip_address daddr; // Destination address
u_int op_pad; // Option + Padding
}ip_header;
typedef struct tcp_header // structure TCP Header
{
//Pour processeur de type little-endian
unsigned short source; // port source
unsigned short dest; // port de destination
unsigned int seq; // Sequence number
unsigned int ack_seq; // acknowledge sequence
unsigned short res1:4, // Reserved 1 : 4 bits
doff:4, // Data Offset
fin:1, // Flag FINISH
syn:1, // Flag SYNCHRONIZE
rst:1, // Flag RESET
psh:1, // Flag PUSH
ack:1, // Flag ACKNOLEDGE
urg:1, // Flag URGENT
res2:2; // Reserved 2 : 2 bits (res1 + res2 = 6 bits reserved)
unsigned short window;
unsigned short check; // checksum
unsigned short urg_ptr; // urgent
}tcp_header;
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int main(int argc, char *argv[]) {
pcap_loop(adhandle, 0, packet_handler, NULL);
/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {
ip_header *ih;
tcp_header *th;
u_int ip_len;
int tcp_len, url_length, udp_len;
u_char *url, *cont, *end_url, *final_url, *tcp_payload;
/* position of the ip header */
ih = (ip_header *) (pkt_data + 14); //length of ethernet header
ip_len = (ih->ver_ihl & 0xf) * 4;
/* position of the tcp header */
th = (tcp_header *) ((u_char*)ih + ip_len);
tcp_len = (((u_char*)ih)[ip_len + 12] >> 4) * 4;
tcp_payload = (u_char*)ih + ip_len + tcp_len;
url = tcp_payload + 4; // skip "GET "
end_url = strchr((char*)url, ' ');
url_length = end_url - url;
if(url_length>0) {
final_url = (u_char*)malloc(url_length+1);
strncpy(final_url, url, url_length);
final_url[url_length] = '\0';
printf("\n%s\n", final_url);
}
}
}