|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
|
|
typedef enum PROTOCOL_STATUS {
|
|
PS_NONE,
|
|
PS_SNIFF,
|
|
PS_HTTP_READ_HEADER,
|
|
PS_HTTP_READ_BODY,
|
|
PS_STREAM,
|
|
PS_ERROR
|
|
|
|
} PROTOCOL_STATUS;
|
|
|
|
typedef enum PROTOCOL_NAME {
|
|
PN_NONE,
|
|
PN_HTTP,
|
|
PN_HTTP_CHUNKED,
|
|
PN_HTTP_WEBSOCKET,
|
|
PN_HTTP_KEEP_ALIVE,
|
|
PN_HTTP_REQUEST,
|
|
PN_SSH,
|
|
PN_RAW,
|
|
PN_ERROR
|
|
} PROTOCOL_NAME ;
|
|
|
|
char * http_get_header_value(char * headers, char * key){
|
|
char * result = NULL;
|
|
char * start = strstr(headers, key);
|
|
if(!start){
|
|
return NULL;
|
|
}
|
|
start += strlen(key);
|
|
start += 2;
|
|
char * end = strstr(start, "\r\n");
|
|
if(!end){
|
|
return NULL;
|
|
}
|
|
result = (char *)malloc(end - start + 1);
|
|
strncpy(result, start, end - start);
|
|
result[end-start] = 0;
|
|
return result;
|
|
}
|
|
|
|
PROTOCOL_NAME protocol_sniff(int fd){
|
|
char buffer[4096] = {0};
|
|
|
|
ssize_t bytes_received = recv(fd, buffer,sizeof(buffer),MSG_PEEK);
|
|
buffer[bytes_received] = 0;
|
|
if(bytes_received <= 0){
|
|
return PN_ERROR;
|
|
}
|
|
|
|
if(strncmp(buffer,"HTTP",4) == 0){
|
|
if(strstr(buffer,"Transfer-Encoding: chunked"))
|
|
return PN_HTTP_CHUNKED;
|
|
if(strstr(buffer,"Connection: keep-alive")){
|
|
return PN_HTTP_KEEP_ALIVE;
|
|
}
|
|
return PN_HTTP;
|
|
}
|
|
if(!strncmp(buffer,"GET ",4) && strstr(buffer,"Upgrade: websocket")){
|
|
return PN_HTTP_WEBSOCKET;
|
|
}
|
|
if(!strncmp(buffer,"SSH ",4)){
|
|
return PN_SSH;
|
|
}
|
|
if(!strncmp(buffer,"GET ", 4)){
|
|
return PN_HTTP_REQUEST;
|
|
}
|
|
return PN_RAW;
|
|
} |