gpt4 book ai didi

c - HTTP header 的起始位置并不总是相同

转载 作者:行者123 更新时间:2023-11-30 19:37:05 25 4
gpt4 key购买 nike

例如,我尝试计算数据包的 HTTP header 的开头

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 header 的一部分,但位置错误。我认为由于一些额外的字段,某些 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);
}

}

}

最佳答案

要解析 HTTP 请求,您需要将请求分成几行,每一行都单独解析。第一个是请求本身,然后是 header ,最后是数据。

每一行都以 "\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 请求远非简单。你应该意识到这一点。

由于您的代码有时可以工作,因此您可能在未发布的代码中的某处执行了未定义行为的操作。

关于c - HTTP header 的起始位置并不总是相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40292146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com