zoukankan      html  css  js  c++  java
  • 自己动手学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相应包头,可能存在一些不足,希望大家多多交流。

    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.   
    16. #define BUFFSIZE 1500  
    17.   
    18. typedef struct port{  
    19.     unsigned int src_port;  
    20.     unsigned int des_port;  
    21. }Port;  
    22.   
    23. Port port;  
    24. int tcp=0;  
    25. FILE *logfile;  
    26. int size;  
    27.   
    28. void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer);  
    29. char *print_tcp_packet(const char *Buffer);  
    30. void get_line(char *data,char *buff,int length);  
    31. void print_http_req_packet(char *data);  
    32. void print_http_ans_packet(char *data);  
    33.   
    34. int main(int argc,char *argv[])  
    35. {  
    36.     pcap_if_t *alldevsp , *device;  
    37.     pcap_t *handle; //Handle of the device that shall be sniffed  
    38.   
    39.     char errbuf[100] , *devname , devs[100][100];  
    40.     int count = 1 , n;  
    41.   
    42.     //First get the list of available devices  
    43.     printf("Finding available devices ... ");  
    44.     if( pcap_findalldevs( &alldevsp , errbuf) )  
    45.     {  
    46.         printf("Error finding devices : %s" , errbuf);  
    47.         exit(1);  
    48.     }  
    49.     printf("Done");  
    50.   
    51.     //Print the available devices  
    52.     printf(" Available Devices are : ");  
    53.     for(device = alldevsp ; device != NULL ; device = device->next)  
    54.     {  
    55.         printf("%d. %s - %s " , count , device->name , device->description);  
    56.         if(device->name != NULL)  
    57.         {  
    58.             strcpy(devs[count] , device->name);  
    59.         }  
    60.         count++;  
    61.     }  
    62.   
    63.     //Ask user which device to sniff  
    64.     printf("Enter the number of the device you want to sniff : ");  
    65.     scanf("%d" , &n);  
    66.     devname = devs[n];  
    67.   
    68.     //Open the device for sniffing  
    69.     printf("Opening device %s for sniffing ... " , devname);  
    70.     handle = pcap_open_live(devname , 65536 , 1 , 0 , errbuf);  
    71.   
    72.     if (handle == NULL)  
    73.     {  
    74.         fprintf(stderr, "Couldn't open device %s : %s " , devname , errbuf);  
    75.         exit(1);  
    76.     }  
    77.     printf("Done ");  
    78.   
    79.     logfile=fopen("log.txt","w");  
    80.     if(logfile==NULL)  
    81.     {  
    82.         printf("Unable to create file.");  
    83.     }  
    84.   
    85.     //Put the device in sniff loop  
    86.     pcap_loop(handle , -1 , process_packet , NULL);  
    87.   
    88.     return 0;  
    89. }  
    90.   
    91. void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer)  
    92. {  
    93.     size = header->len;  
    94. //  fprintf(logfile,"length of packet : %d  ",size);     
    95.     //Get the IP Header part of this packet , excluding the ethernet header  
    96.     struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));  
    97.     switch (iph->protocol) //Check the Protocol and do accordingly...  
    98.     {  
    99.   
    100.         case 6:  //TCP Protocol  
    101.             ++tcp;    
    102.         //  printf("TCP : %d  ", tcp);  
    103.             unsigned char *data = print_tcp_packet(buffer);   
    104.             if (size <= 0)  
    105.                 break;  
    106.             if (port.des_port == 80)              
    107.             {  
    108.                 print_http_req_packet(data);  
    109.             }  
    110.             else if ( port.src_port == 80 )  
    111.             {  
    112.                 print_http_ans_packet(data);  
    113.             }  
    114.             break;  
    115.     }  
    116.   
    117. }  
    118.   
    119. char *print_tcp_packet(const char *Buffer)  
    120. {  
    121.     //IP header  
    122.     struct iphdr *iph = (struct iphdr *)( Buffer  + sizeof(struct ethhdr) );  
    123.     unsigned int iphdrlen = iph->ihl*4;  
    124.     //TCP header  
    125.     struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen + sizeof(struct ethhdr));  
    126.       
    127.     port.src_port = ntohs(tcph->source);  
    128.     port.des_port = ntohs(tcph->dest);  
    129.   
    130.     // mac_header + ip_header + tcp_header  
    131.     int header_size =  sizeof(struct ethhdr) + iphdrlen + tcph->doff*4;  
    132.     size = size - header_size;   
    133. //  fprintf(logfile,"length of header : %d  ",header_size );  
    134.     return (char *)(Buffer + header_size);  
    135. }  
    136.   
    137. void print_http_req_packet(char *data)  
    138. {     
    139.     if( strncmp(data,"GET",3) == 0 || strncmp(data,"POST",4) == 0 )   
    140.     {  
    141.         fprintf(logfile," /***********************length of data : %d**********************/  ",size);  
    142.         fprintf(logfile,"From %d To %d  ",port.src_port,port.des_port);  
    143.         int i = 0;    
    144.         for( ; i < size ; ++i)  
    145.         {  
    146.             fprintf(logfile,"%c",*(data + i));  
    147.         }  
    148.         fprintf(logfile,"/***************************** end *******************************/  ");  
    149.     }  
    150.     return ;  
    151. }  
    152.   
    153. void print_http_ans_packet(char *data)  
    154. {  
    155.     if( strncmp(data,"HTTP",4) == 0 )   
    156.     {  
    157.         fprintf(logfile," /***********************length of data : %d**********************/  ",size);  
    158.         fprintf(logfile,"From %d To %d  ",port.src_port,port.des_port);  
    159.         char buff[BUFFSIZE] = {''};  
    160.         get_line(data,buff,size);  
    161.         fprintf(logfile,"%s",buff);  
    162.         unsigned int off = strlen(buff);  
    163.         size = size - off;  
    164.         while(strcmp(buff," ") != 0)  
    165.         {  
    166.             memset(buff,'',sizeof(buff));  
    167.             get_line(data + off,buff,size);  
    168.             fprintf(logfile,"%s",buff);  
    169.             off = off + strlen(buff);  
    170.             size = size - off;  
    171.         }  
    172.         fprintf(logfile,"/***************************** end *******************************/  ");  
    173.     }  
    174. }  
    175.   
    176. void get_line(char *data,char *buff,int length)  
    177. {  
    178.     int i = 0;  
    179.     char ch;  
    180.     for ( ; i < length;++i)  
    181.     {  
    182.         ch = *(data + i);  
    183.         *(buff + i) = ch;  
    184.         if(ch == ' ')  
    185.             break;  
    186.     }  
    187. }  
  • 相关阅读:
    省市区三级联动
    VUE项目PC端实现自适应rem
    (课堂笔记)第十三章GLSB涉及负载均衡算法
    LTM理解及配置笔记记录
    实验演示---GSLB部分(DC1)
    F5实验模拟拓扑
    (课堂笔记)第十三章:DNS 全局站点
    AbstractList类_Iterator内部类
    Oracle 时间格式化异常:无效数字
    Maven库镜像
  • 原文地址:https://www.cnblogs.com/lidabo/p/4595652.html
Copyright © 2011-2022 走看看