#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;
}