自己动手学TCP/IP–http协议(http报文头)

在前面的一篇文章中,简单了介绍了HTTP报文格式,详情参考http://www.firefoxbug.net/?cat=47

这里大概介绍下基本的,常见的HTTP包头格式。

POST /report/getComment.jsp HTTP/1.1
Host: yeeg.com
Connection: keep-alive
Content-Length: 161
Origin: http://www.1g1g.com
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7
content-type: application/x-www-form-urlencoded
Accept: */*
Referer: http://www.1g1g.com/player/loader.swf?uid=0.8106261373031884
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: JSESSIONID=C3F105F72E3602D6292D3E4561E8E400

上面是一个POST包的包头,其中Content-Length字段里面的值就是POST包数据段的长度。可以用

wireshark抓取POST包,会发现,post包是把报文头和数据内容分开来发的,会被TCP分片,然后重组。

具体这里不详细讨论。

GET /enclosure/2010-09-10T02_51_05-07_00.mp3 HTTP/1.1
Host: 805665086.podomatic.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7
Accept: */*
Referer: http://www.1g1g.com/player/loader.swf?uid=0.8106261373031884
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

上面是一个GET包,GET包请求的资源都是在URL里面的,所以数据段也就没有了,可以通过抓包分析。

HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 09:12:52 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Thu, 23 Dec 2010 19:29:26 GMT
ETag: "960fcf-4a6459-49818e3486374"
Accept-Ranges: bytes
Content-Length: 487
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: audio/mpeg

上面是一个http响应包,Content-Length指明了数据段的大小。

下面是我今天用C写了解析HTTP报文头的程序。注意:下面代码只主要用libcap实现实现了部分功能,具体

是解析GET包头,POST包头,还有HTTP相应包头,可能存在一些不足,希望大家多多交流。

[cpp] view plaincopyprint?

  1. /*
  2. capture http packet by firefoxbug
  3. */
  4. #include <pcap.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/socket.h>
  9. #include <arpa/inet.h>
  10. #include <net/ethernet.h>
  11. #include <netinet/ip_icmp.h>  //Provides declarations for icmp header
  12. #include <netinet/udp.h>      //Provides declarations for udp header
  13. #include <netinet/tcp.h>      //Provides declarations for tcp header
  14. #include <netinet/ip.h>       //Provides declarations for ip header
  15. #define BUFFSIZE 1500
  16. typedef struct port{
  17. unsigned int src_port;
  18. unsigned int des_port;
  19. }Port;
  20. Port port;
  21. int tcp=0;
  22. FILE *logfile;
  23. int size;
  24. void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer);
  25. char *print_tcp_packet(const char *Buffer);
  26. void get_line(char *data,char *buff,int length);
  27. void print_http_req_packet(char *data);
  28. void print_http_ans_packet(char *data);
  29. int main(int argc,char *argv[])
  30. {
  31. pcap_if_t *alldevsp , *device;
  32. pcap_t *handle; //Handle of the device that shall be sniffed
  33. char errbuf[100] , *devname , devs[100][100];
  34. int count = 1 , n;
  35. //First get the list of available devices
  36. printf("Finding available devices ... ");
  37. if( pcap_findalldevs( &alldevsp , errbuf) )
  38. {
  39. printf("Error finding devices : %s" , errbuf);
  40. exit(1);
  41. }
  42. printf("Done");
  43. //Print the available devices
  44. printf("\nAvailable Devices are :\n");
  45. for(device = alldevsp ; device != NULL ; device = device->next)
  46. {
  47. printf("%d. %s - %s\n" , count , device->name , device->description);
  48. if(device->name != NULL)
  49. {
  50. strcpy(devs[count] , device->name);
  51. }
  52. count++;
  53. }
  54. //Ask user which device to sniff
  55. printf("Enter the number of the device you want to sniff : ");
  56. scanf("%d" , &n);
  57. devname = devs[n];
  58. //Open the device for sniffing
  59. printf("Opening device %s for sniffing ... " , devname);
  60. handle = pcap_open_live(devname , 65536 , 1 , 0 , errbuf);
  61. if (handle == NULL)
  62. {
  63. fprintf(stderr, "Couldn‘t open device %s : %s\n" , devname , errbuf);
  64. exit(1);
  65. }
  66. printf("Done\n");
  67. logfile=fopen("log.txt","w");
  68. if(logfile==NULL)
  69. {
  70. printf("Unable to create file.");
  71. }
  72. //Put the device in sniff loop
  73. pcap_loop(handle , -1 , process_packet , NULL);
  74. return 0;
  75. }
  76. void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer)
  77. {
  78. size = header->len;
  79. //  fprintf(logfile,"length of packet : %d \n",size);
  80. //Get the IP Header part of this packet , excluding the ethernet header
  81. struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
  82. switch (iph->protocol) //Check the Protocol and do accordingly...
  83. {
  84. case 6:  //TCP Protocol
  85. ++tcp;
  86. //  printf("TCP : %d \n", tcp);
  87. unsigned char *data = print_tcp_packet(buffer);
  88. if (size <= 0)
  89. break;
  90. if (port.des_port == 80)
  91. {
  92. print_http_req_packet(data);
  93. }
  94. else if ( port.src_port == 80 )
  95. {
  96. print_http_ans_packet(data);
  97. }
  98. break;
  99. }
  100. }
  101. char *print_tcp_packet(const char *Buffer)
  102. {
  103. //IP header
  104. struct iphdr *iph = (struct iphdr *)( Buffer  + sizeof(struct ethhdr) );
  105. unsigned int iphdrlen = iph->ihl*4;
  106. //TCP header
  107. struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen + sizeof(struct ethhdr));
  108. port.src_port = ntohs(tcph->source);
  109. port.des_port = ntohs(tcph->dest);
  110. // mac_header + ip_header + tcp_header
  111. int header_size =  sizeof(struct ethhdr) + iphdrlen + tcph->doff*4;
  112. size = size - header_size;
  113. //  fprintf(logfile,"length of header : %d \n",header_size );
  114. return (char *)(Buffer + header_size);
  115. }
  116. void print_http_req_packet(char *data)
  117. {
  118. if( strncmp(data,"GET",3) == 0 || strncmp(data,"POST",4) == 0 )
  119. {
  120. fprintf(logfile,"\n/***********************length of data : %d**********************/ \n",size);
  121. fprintf(logfile,"From %d To %d \n",port.src_port,port.des_port);
  122. int i = 0;
  123. for( ; i < size ; ++i)
  124. {
  125. fprintf(logfile,"%c",*(data + i));
  126. }
  127. fprintf(logfile,"/***************************** end *******************************/ \n\n");
  128. }
  129. return ;
  130. }
  131. void print_http_ans_packet(char *data)
  132. {
  133. if( strncmp(data,"HTTP",4) == 0 )
  134. {
  135. fprintf(logfile,"\n/***********************length of data : %d**********************/ \n",size);
  136. fprintf(logfile,"From %d To %d \n",port.src_port,port.des_port);
  137. char buff[BUFFSIZE] = {‘\0‘};
  138. get_line(data,buff,size);
  139. fprintf(logfile,"%s",buff);
  140. unsigned int off = strlen(buff);
  141. size = size - off;
  142. while(strcmp(buff,"\r\n") != 0)
  143. {
  144. memset(buff,‘\0‘,sizeof(buff));
  145. get_line(data + off,buff,size);
  146. fprintf(logfile,"%s",buff);
  147. off = off + strlen(buff);
  148. size = size - off;
  149. }
  150. fprintf(logfile,"/***************************** end *******************************/ \n\n");
  151. }
  152. }
  153. void get_line(char *data,char *buff,int length)
  154. {
  155. int i = 0;
  156. char ch;
  157. for ( ; i < length;++i)
  158. {
  159. ch = *(data + i);
  160. *(buff + i) = ch;
  161. if(ch == ‘\n‘)
  162. break;
  163. }
  164. }
时间: 2024-10-14 18:22:46

自己动手学TCP/IP–http协议(http报文头)的相关文章

TCP/IP网络协议

什么是协议?协议就是双方约定的规则.同理,在网络中,计算机之间的相互通信需要共同遵守一定的规则,这些规则就称为网络协议. 下面是我百度的定义: TCP/IP是“transmission Control Protocol/Internet Protocol”的简写,中文译名为传输控制协议/互联网络协议)协议, TCP/IP(传输控制协议/网间协议)是一种网络通信协议,它规范了网络上的所有通信设备,尤其是一个主机与另一个主机之间的数据往来格式以及传送方式.TCP/IP是INTERNET的基础协议,也

对TCP/IP网络协议的深入浅出归纳

前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网络协议有了初步的认识,在这里总结出来,可以梳理一下我对网络协议的理解,加深印象. 话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样.一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没办法沟通.两台电脑之间进行通讯所共同遵守的规则,就是网络协议. 那么

OSI七层协议和TCP/IP四层协议对比

OSI七层协议: 1. 物理层 2. 数据链路层 3. 网络层 4. 传输层 5. 会话层 6. 表示层 7. 应用层 TCP/IP四层协议 1. 数据链路层 2. 网络层 3. 传输层 4. 应用层 应用层 1. 主要功能:用户接口,用户程序 2. 典型设备:网关 表示层 1. 主要功能:数据的表示,加密与压缩等 2. 典型设备:网关 会话层 1. 主要功能:会话的建立与结束 2. 典型设备:网关 传输层 1. 主要功能:端到端的控制 2. 典型设备:网关 3. 典型协议:TCP,UDP,SP

对TCP/IP网络协议的深入浅出归纳(转)

前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网络协议有了初步的认识,在这里总结出来,可以梳理一下我对网络协议的理解,加深印象. 话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样.一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没办法沟通.两台电脑之间进行通讯所共同遵守的规则,就是网络协议. 那么

[转]对TCP/IP网络协议的深入浅出归纳

转自:http://blog.jobbole.com/74795/ 前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网络协议有了初步的认识,在这里总结出来,可以梳理一下我对网络协议的理解,加深印象. 话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样.一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没

转:对TCP/IP网络协议的深入浅出归纳

前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网络协议有了初步的认识,在这里总结出来,可以梳理一下我对网络协议的理解,加深印象. 话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样.一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没办法沟通.两台电脑之间进行通讯所共同遵守的规则,就是网络协议. 那么

计算机网络【1】—— OSI七层协议和TCP/IP四层协议

新开一贴,专门用来记录计算机网络相关知识. 一.OSI七层协议 物理层.数据链路层.网络层.传输层.会话层.表示层.应用层 二.TCP/IP四层协议 网络接口层.网际层.运输层.应用层 三.五层协议 物理层.数据链路层.网络层.运输层.应用层 四.每层对应的协议及作用 物理层:RJ45.CLOCK.IEEE802.3 (中继器,集线器) 数据链路:PPP.FR.HDLC.VLAN.MAC (网桥,交换机) 网络层:IP.ICMP.ARP.RARP.OSPF.IPX.RIP.IGRP. (路由器)

重学TCP/IP协议和三次握手四次挥手

计算机网络体系结构 在计算机网络的基本概念中,分层次的体系结构是最基本的.计算机网络体系结构的抽象概念较多,在学习时要多思考.这些概念对后面的学习很有帮助. 网络协议是什么? 在计算机网络要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则,比如交换数据的格式.是否需要发送一个应答信息.这些规则被称为网络协议. 为什么要对网络协议分层? 简化问题难度和复杂度.由于各层之间独立,我们可以分割大问题为小问题. 灵活性好.当其中一层的技术变化时,只要层间接口关系保持不变,其他层不受影响. 易于实现

TCP/IP网络协议初识

目录 一.什么是协议? 二.什么是TCP/IP协议? 三.TCP/IP为什么这么多协议? 四.TCP/IP协议为什么分层? 五.TCP/IP协议如何入门? 六.TCP/IP 的分层: 七.各协议层打包和拆包过程: 八.浏览器访问网页的整个流程: 九.举例:网上购物的请求流程 一.什么是协议? 协议就是两个或多个对象之间为了某个或多个需求而设置的约定,即在什么时间,遇到什么情况该做什么. 举例: 小强和小明约定周末一起去玩小霸王游戏机,但是如果遇上停电就去掏鸟窝. 二.什么是TCP/IP协议? T