http协议解析 请求行的信息怎么提取 c语言源码

Python024

http协议解析 请求行的信息怎么提取 c语言源码,第1张

实现步骤:

1)用Wireshark软件抓包得到test.pcap文件

2)程序:分析pcap文件头 ->分析pcap_pkt头 ->分析帧头 ->分析ip头 ->分析tcp头 ->分析http信息

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<netinet/in.h>

#include<time.h>

#define BUFSIZE 10240

#define STRSIZE 1024

typedef long bpf_int32

typedef unsigned long bpf_u_int32

typedef unsigned short u_short

typedef unsigned long u_int32

typedef unsigned short u_int16

typedef unsigned char u_int8

//pacp文件头结构体

struct pcap_file_header

{

bpf_u_int32 magic /* 0xa1b2c3d4 */

u_short version_major /* magjor Version 2 */

u_short version_minor /* magjor Version 4 */

bpf_int32 thiszone /* gmt to local correction */

bpf_u_int32 sigfigs/* accuracy of timestamps */

bpf_u_int32 snaplen/* max length saved portion of each pkt */

bpf_u_int32 linktype /* data link type (LINKTYPE_*) */

}

//时间戳

struct time_val

{

long tv_sec/* seconds 含义同 time_t 对象的值 */

long tv_usec /* and microseconds */

}

//pcap数据包头结构体

struct pcap_pkthdr

{

struct time_val ts /* time stamp */

bpf_u_int32 caplen/* length of portion present */

bpf_u_int32 len /* length this packet (off wire) */

}

//数据帧头

typedef struct FramHeader_t

{ //Pcap捕获的数据帧头

u_int8 DstMAC[6] //目的MAC地址

u_int8 SrcMAC[6] //源MAC地址

u_short FrameType //帧类型

} FramHeader_t

//IP数据报头

typedef struct IPHeader_t

{ //IP数据报头

u_int8 Ver_HLen //版本+报头长度

u_int8 TOS //服务类型

u_int16 TotalLen //总长度

u_int16 ID //标识

u_int16 Flag_Segment //标志+片偏移

u_int8 TTL //生存周期

u_int8 Protocol //协议类型

u_int16 Checksum //头部校验和

u_int32 SrcIP //源IP地址

u_int32 DstIP //目的IP地址

} IPHeader_t

//TCP数据报头

typedef struct TCPHeader_t

{ //TCP数据报头

u_int16 SrcPort //源端口

u_int16 DstPort //目的端口

u_int32 SeqNO //序号

u_int32 AckNO //确认号

u_int8 HeaderLen //数据报头的长度(4 bit) + 保留(4 bit)

u_int8 Flags //标识TCP不同的控制消息

u_int16 Window //窗口大小

u_int16 Checksum //校验和

u_int16 UrgentPointer //紧急指针

}TCPHeader_t

//

void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len) //查找 http 信息函数

//

int main()

{

struct pcap_file_header *file_header

struct pcap_pkthdr *ptk_header

IPHeader_t *ip_header

TCPHeader_t *tcp_header

FILE *fp, *output

int pkt_offset, i=0

int ip_len, http_len, ip_proto

int src_port, dst_port, tcp_flags

char buf[BUFSIZE], my_time[STRSIZE]

char src_ip[STRSIZE], dst_ip[STRSIZE]

char host[STRSIZE], uri[BUFSIZE]

//初始化

file_header = (struct pcap_file_header *)malloc(sizeof(struct pcap_file_header))

ptk_header = (struct pcap_pkthdr *)malloc(sizeof(struct pcap_pkthdr))

ip_header = (IPHeader_t *)malloc(sizeof(IPHeader_t))

tcp_header = (TCPHeader_t *)malloc(sizeof(TCPHeader_t))

memset(buf, 0, sizeof(buf))

//

if((fp = fopen(“test.pcap”,”r”)) == NULL)

{

printf(“error: can not open pcap file\n”)

exit(0)

}

if((output = fopen(“output.txt”,”w+”)) == NULL)

{

printf(“error: can not open output file\n”)

exit(0)

}

//开始读数据包

pkt_offset = 24 //pcap文件头结构 24个字节

while(fseek(fp, pkt_offset, SEEK_SET) == 0) //遍历数据包

{

i++

//pcap_pkt_header 16 byte

if(fread(ptk_header, 16, 1, fp) != 1) //读pcap数据包头结构

{

printf(“\nread end of pcap file\n”)

break

}

pkt_offset += 16 + ptk_header->caplen //下一个数据包的偏移值

strftime(my_time, sizeof(my_time), “%Y-%m-%d %T”, localtime(&(ptk_header->ts.tv_sec))) //获取时间

// printf(“%d: %s\n”, i, my_time)

//数据帧头 14字节

fseek(fp, 14, SEEK_CUR) //忽略数据帧头

//IP数据报头 20字节

if(fread(ip_header, sizeof(IPHeader_t), 1, fp) != 1)

{

printf(“%d: can not read ip_header\n”, i)

break

}

inet_ntop(AF_INET, (void *)&(ip_header->SrcIP), src_ip, 16)

inet_ntop(AF_INET, (void *)&(ip_header->DstIP), dst_ip, 16)

ip_proto = ip_header->Protocol

ip_len = ip_header->TotalLen //IP数据报总长度

// printf(“%d: src=%s\n”, i, src_ip)

if(ip_proto != 0×06) //判断是否是 TCP 协议

{

continue

}

//TCP头 20字节

if(fread(tcp_header, sizeof(TCPHeader_t), 1, fp) != 1)

{

printf(“%d: can not read ip_header\n”, i)

break

}

src_port = ntohs(tcp_header->SrcPort)

dst_port = ntohs(tcp_header->DstPort)

tcp_flags = tcp_header->Flags

// printf(“%d: src=%x\n”, i, tcp_flags)

if(tcp_flags == 0×18) // (PSH, ACK) 3路握手成功后

{

if(dst_port == 80) // HTTP GET请求

{

http_len = ip_len – 40 //http 报文长度

match_http(fp, “Host: “, “\r\n”, host, http_len) //查找 host 值

match_http(fp, “GET “, “HTTP”, uri, http_len) //查找 uri 值

sprintf(buf, “%d: %s src=%s:%d dst=%s:%d %s%s\r\n”, i, my_time, src_ip, src_port, dst_ip, dst_port, host, uri)

//printf(“%s”, buf)

if(fwrite(buf, strlen(buf), 1, output) != 1)

{

printf(“output file can not write”)

break

}

}

}

} // end while

fclose(fp)

fclose(output)

return 0

}

//查找 HTTP 信息

void match_http(FILE *fp, char *head_str, char *tail_str, char *buf, int total_len)

{

int i

int http_offset

int head_len, tail_len, val_len

char head_tmp[STRSIZE], tail_tmp[STRSIZE]

//初始化

memset(head_tmp, 0, sizeof(head_tmp))

memset(tail_tmp, 0, sizeof(tail_tmp))

head_len = strlen(head_str)

tail_len = strlen(tail_str)

//查找 head_str

http_offset = ftell(fp) //记录下HTTP报文初始文件偏移

while((head_tmp[0] = fgetc(fp)) != EOF) //逐个字节遍历

{

if((ftell(fp) – http_offset) >total_len) //遍历完成

{

sprintf(buf, “can not find %s \r\n”, head_str)

exit(0)

}

if(head_tmp[0] == *head_str) //匹配到第一个字符

{

for(i=1i<head_leni++) //匹配 head_str 的其他字符

{

head_tmp[i]=fgetc(fp)

if(head_tmp[i] != *(head_str+i))

break

}

if(i == head_len) //匹配 head_str 成功,停止遍历

break

}

}

// printf(“head_tmp=%s \n”, head_tmp)

//查找 tail_str

val_len = 0

while((tail_tmp[0] = fgetc(fp)) != EOF) //遍历

{

if((ftell(fp) – http_offset) >total_len) //遍历完成

{

sprintf(buf, “can not find %s \r\n”, tail_str)

exit(0)

}

buf[val_len++] = tail_tmp[0] //用buf 存储 value 直到查找到 tail_str

if(tail_tmp[0] == *tail_str) //匹配到第一个字符

{

for(i=1i<tail_leni++) //匹配 head_str 的其他字符

{

tail_tmp[i]=fgetc(fp)

if(tail_tmp[i] != *(tail_str+i))

break

}

if(i == tail_len) //匹配 head_str 成功,停止遍历

{

buf[val_len-1] = 0 //清除多余的一个字符

break

}

}

}

// printf(“val=%s\n”, buf)

fseek(fp, http_offset, SEEK_SET) //将文件指针 回到初始偏移

}

用jni

首先

java

public

class

testhello

{

static

{

system.loadlibrary("testhellos")

}

public

static

native

void

hello(string

msg)

public

native

void

getsysid()

public

native

string

getkeycode(string

sysid)

public

native

boolean

testkeycode(string

sysid,

string

keycode)

public

static

void

main(string[]

args)

{

//

hello("hello,kimm!")

testhello

t=

new

testhello()

t.getsysid()

}

}

用javac

testhello.java,

java

testhello,javah

-classpath

.

-verbose

testhello

。将生产的头文件用到c++

中的

heardfileds

中。然后在

sources

files

中实现

heardfieds

的方法。实现的方法,其实就是你要调用c++的方法、

用c语言实现文件自动下载并且解压1.自动下载 http://abc.com/test.rar 也可以下载FTP://abc.com/test.rar2.下载完成后自动解压到本路径下相同的文件夹里面,如:test.rar就是test文件夹3.如果test文件夹已经存在并且里面有内容就直接覆盖4.软件运行的时候提示用户输入存储路径5.下载过程中显示下载进度6.一个好的编程会在适当的地方加上适当的注释以上功能我已经用wget+winrar的做成批处理可以运行了,但是希望用C语言来实现先送50分,如果实现了在加送50分,不希望吧分数留给系统

希望采纳