Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

hi_server.c

Go to the documentation of this file.
00001 /**
00002 **  @file       hi_server.c
00003 **  
00004 **  @author     Daniel Roelker <droelker@sourcefire.com>
00005 **  
00006 **  @brief      Handles inspection of HTTP server responses.
00007 **  
00008 **  HttpInspect handles server responses in a stateless manner because we
00009 **  are really only interested in the first response packet that contains
00010 **  the HTTP response code, headers, and the payload.
00011 **  
00012 **  The first big thing is to incorporate the HTTP protocol flow
00013 **  analyzer.
00014 **  
00015 **  NOTES:
00016 **      - Initial development.  DJR
00017 */
00018 #include <stdio.h>
00019 
00020 #include "hi_ui_config.h"
00021 #include "hi_si.h"
00022 #include "hi_return_codes.h"
00023 #include "hi_server.h"
00024 
00025 /**
00026 **  NAME
00027 **    IsHttpServerData::
00028 */
00029 /**
00030 **  Inspect an HTTP server response packet to determine the state.
00031 **  
00032 **  We inspect this packet and determine whether we are in the beginning
00033 **  of a response header or if we are looking at payload.  We limit the
00034 **  amount of inspection done on responses by only inspecting the HTTP header
00035 **  and some payload.  If the whole packet is a payload, then we just ignore
00036 **  it, since we inspected the previous header and payload.
00037 **  
00038 **  We limit the amount of the payload by adjusting the Server structure
00039 **  members, header and header size.
00040 **  
00041 **  @param Server      the server structure
00042 **  @param data        pointer to the beginning of payload
00043 **  @param dsize       the size of the payload
00044 **  @param flow_depth  the amount of header and payload to inspect
00045 **  
00046 **  @return integer
00047 **  
00048 **  @retval HI_INVALID_ARG invalid argument
00049 **  @retval HI_SUCCESS     function success
00050 */
00051 static int IsHttpServerData(HI_SERVER *Server, u_char *data, int dsize,
00052                             int flow_depth)
00053 {
00054     /* 
00055     ** HTTP:Server-Side-Session-Performance-Optimization
00056     ** This drops Server->Client packets which are not part of the 
00057     ** HTTP Response header. It can miss part of the response header 
00058     ** if the header is sent as multiple packets.
00059     */
00060     if(!data)
00061     {
00062         return HI_INVALID_ARG;
00063     }
00064 
00065     /*
00066     **  Let's set up the data pointers.
00067     */
00068     Server->header      = data;
00069     Server->header_size = dsize;
00070 
00071     /*
00072     **  This indicates that we want to inspect the complete response, so
00073     **  we don't waste any time otherwise.
00074     */
00075     if(flow_depth < 1)
00076     {
00077         return HI_SUCCESS;
00078     }
00079 
00080     if(dsize > 4 )
00081     {
00082         if( (data[0]!='H') || (data[1]!='T') || 
00083             (data[2]!='T') || (data[3]!='P') )
00084         {
00085             Server->header_size = 0;
00086             Server->header      = NULL;
00087 
00088             return HI_SUCCESS;
00089         }
00090 
00091         /*
00092         **  OK its an HTTP response header.
00093         **
00094         **  Now, limit the amount we inspect,
00095         **  we could just examine this whole packet, 
00096         **  since it's usually full of HTTP Response info.
00097         **  For protocol analysis purposes we probably ought to 
00098         **  let the whole thing get processed, or have a 
00099         **  different pattern match length and protocol inspection 
00100         **  length.
00101         */
00102 
00103         if(dsize > flow_depth)
00104         {
00105             Server->header_size = flow_depth;  
00106         }
00107     }
00108 
00109     return HI_SUCCESS;
00110 }
00111 
00112 static int ServerInspection(HI_SESSION *Session, unsigned char *data,
00113                             int dsize)
00114 {
00115     HI_SERVER *Server;
00116     int       iRet;
00117 
00118     Server = &(Session->server);
00119 
00120     /*
00121     **  There's really only one thing that we do right now for server
00122     **  responses, that's HTTP flow.
00123     */
00124     if((iRet = IsHttpServerData(Server, data, dsize, 
00125                          Session->server_conf->flow_depth)))
00126     {
00127         return iRet;
00128     }
00129 
00130     return HI_SUCCESS;
00131 }
00132 
00133 int hi_server_inspection(void *S, unsigned char *data, int dsize)
00134 {
00135     HI_SESSION *Session;
00136 
00137     int iRet;
00138 
00139     if(!S || !data || dsize < 1)
00140     {
00141         return HI_INVALID_ARG;
00142     }
00143 
00144     Session = (HI_SESSION *)S;
00145 
00146     /*
00147     **  Let's inspect the server response.
00148     */
00149     if((iRet = ServerInspection(Session, data, dsize)))
00150     {
00151         return iRet;
00152     }
00153 
00154     return HI_SUCCESS;
00155 }

Generated on Sun May 14 14:51:15 2006 by  doxygen 1.4.2