我尝试计算数据包的HTTP标头的开头,例如
GET /test.html HTTP1.1
Host: example.com
...
使用C中的WinPcap尝试
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);
输出有时是正确的,但有时会输出cookie的某些部分或cept-Encodin
什么是http标题的一部分,但位置错误。我想也许一些tcp有效载荷的长度不同,因为一些额外的字段,但我不知道如何检查?谢谢
#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);
}
}
}
答案 0 :(得分:0)
要解析HTTP请求,您需要按行分解请求,每行都要单独解析。第一个是请求本身,然后是标题,最后是数据。
每一行以"\r\n"
组合结束,因此您应该搜索该字符,第一行始终是请求行。
例如
char *end_of_line;
end_of_line = strstr(tcp_payload, "\r\n");
if (end_of_line != NULL) {
// Your request line goes from `tcp_payload' to `end_of_line'.
}
解析HTTP请求远非简单。你应该知道这一点。
由于您的代码有时会正常工作,因此您可能会在代码中的某个地方执行某些未发布的操作。