diff options
Diffstat (limited to 'src/main/c/PcapOne/PcapOne.c')
-rw-r--r-- | src/main/c/PcapOne/PcapOne.c | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/src/main/c/PcapOne/PcapOne.c b/src/main/c/PcapOne/PcapOne.c deleted file mode 100644 index 2eb9e25..0000000 --- a/src/main/c/PcapOne/PcapOne.c +++ /dev/null @@ -1,311 +0,0 @@ -/* TODO fix this bullshit */ -typedef unsigned u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; -#include <pcap/pcap.h> -/* endOf TODO */ - - -/* System */ -#include <assert.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> - -static char const*const DEV_STDIN = "/dev/stdin"; - -#define FLG_isHelp (1<<0) -#define FLG_isTcpPsh (1<<3) -#define FLG_isTcpRst (1<<4) -#define FLG_isTcpSyn (1<<5) -#define FLG_isTcpFin (1<<6) -#define FLG_isHttpReq (1<<7) -#define FLG_isLlLinux (1<<12) -#define FLG_isHdrPrinted (1<<13) -#define FLG_INIT (0) - -typedef struct PcapOne PcapOne; - - -struct PcapOne { - uint_least16_t flg; - const char *dumpFilePath; - char *pcapErrbuf; - pcap_t *pcap; - unsigned long frameNr; - struct/*most recent frame*/{ - int llProto; - int llHdrEnd; - }; - struct/*most recent packet*/{ - int netProto; - int netBodyLen; - int netHdrEnd; - int_fast32_t netTotLen; - uint_least32_t ipSrcAddr, ipDstAddr; - }; - struct/*most recent segment*/{ - int trspBodyLen; - int trspSrcPort, trspDstPort; - int trspHdrEnd; - }; - struct/*most recent http requst*/{ - const uint8_t *httpReqHeadline; - int httpReqHeadline_len; - int httpReq_off; /* pkg offset from begin of most recent request */ - }; -}; - - -/*BEG func fwd decl*/ -static void parse_ll_LINUX_SLL( PcapOne*, const struct pcap_pkthdr*, const u_char* ); -static void parse_net_IPv4( PcapOne*, const struct pcap_pkthdr*, const u_char* ); -static void parse_trsp_TCP( PcapOne*, const struct pcap_pkthdr*, const u_char* ); -static void parse_appl_HTTP_req( PcapOne*, const struct pcap_pkthdr*, const u_char* ); -static void printParsingResults( PcapOne*, const struct pcap_pkthdr* ); -/*END func fwd decl*/ - -static void printHelp(){ - #define STRQUOT_21a9ffbe344c0792ed88688d6c676359(s) #s - #define STRQUOT(s) STRQUOT_21a9ffbe344c0792ed88688d6c676359(s) - const char *basename = "/"__FILE__ + sizeof("/"__FILE__); - for(; basename[-1] != '/'; --basename ); - printf("%s%s%s", " \n" - " ", basename, " " STRQUOT(PROJECT_VERSION) "\n" - " \n" - " Options:\n" - " \n" - " --pcap-stdin\n" - " Like --pcap but reading from stdin.\n" - " \n" - " --pcap <path>\n" - " Pcap file to operate on. Compressed files are NOT supported.\n" - " \n"); - #undef STRQUOT_21a9ffbe344c0792ed88688d6c676359 - #undef STRQUOT -} - - -static int parseArgs( PcapOne*app, int argc, char**argv ){ - app->flg = FLG_INIT; - app->dumpFilePath = NULL; - for( int iA = 1 ; iA < argc ; ++iA ){ - const char *arg = argv[iA]; - if(0){ - }else if( !strcmp(arg,"--help") ){ - app->flg |= FLG_isHelp; return 0; - }else if( !strcmp(arg,"--pcap") ){ - arg = argv[++iA]; - if( arg == NULL ){ fprintf(stderr, "EINVAL --pcap needs value\n"); return -1; } - app->dumpFilePath = arg; - }else if( !strcmp(arg,"--pcap-stdin") ){ - app->dumpFilePath = DEV_STDIN; - }else{ - fprintf(stderr, "EINVAL: %s\n", arg); return -1; - } - } - if( app->dumpFilePath == NULL ){ - fprintf(stderr, "EINVAL Arg missing: --pcap <path>\n"); return -1; } - return 0; -} - - -static void onPcapPkg( u_char*user, const struct pcap_pkthdr*hdr, const u_char*buf ){ - PcapOne *const app = (void*)user; - - /* prepare for this new packet */ - app->frameNr += 1; - app->flg &= ~(FLG_isTcpPsh | FLG_isTcpRst | FLG_isTcpSyn | FLG_isTcpFin | FLG_isHttpReq); - - /* data-link layer */ - switch( pcap_datalink(app->pcap) ){ - case 0x71: parse_ll_LINUX_SLL(app, hdr, buf); break; - default: assert(!fprintf(stderr,"pcap_datalink() -> 0x%02X\n", pcap_datalink(app->pcap))); - } - - /* network layer */ - switch( app->llProto ){ - case 0x0800: parse_net_IPv4(app, hdr, buf); break; - default: printf("???, proto=0x%04X, network-layer\n", app->llProto); return; - } - - /* transport layer */ - switch( app->netProto ){ - case 0x06: parse_trsp_TCP(app, hdr, buf); break; - default: printf("???, proto=0x%02X, transport-layer\n", app->netProto); return; - } - - assert(app->trspBodyLen >= 0); - - /* application layer, towards server */ - switch( app->trspDstPort ){ - case 80: parse_appl_HTTP_req(app, hdr, buf); break; - case 7012: parse_appl_HTTP_req(app, hdr, buf); break; - case 8080: parse_appl_HTTP_req(app, hdr, buf); break; - } - - printParsingResults(app, hdr); -} - - -static void parse_ll_LINUX_SLL( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){ - assert(hdr->caplen >= 15); - app->llProto = buf[14]<<8 | buf[15]; - app->llHdrEnd = 16; -} - - -static void parse_net_IPv4( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){ - assert(hdr->caplen >= app->llHdrEnd+19 && "TODO_775afde7f19010220e9df8d5e2924c3e"); - int_fast8_t netHdrLen = (buf[app->llHdrEnd+0] & 0x0F) * 4; - app->netTotLen = buf[app->llHdrEnd+2] << 8 | buf[app->llHdrEnd+3]; - app->netProto = buf[app->llHdrEnd+9]; - app->ipSrcAddr = 0 - | ((uint_least32_t)buf[app->llHdrEnd+12]) << 24 - | ((uint_least32_t)buf[app->llHdrEnd+13]) << 16 - | buf[app->llHdrEnd+14] << 8 - | buf[app->llHdrEnd+15] ; - app->ipDstAddr = 0 - | ((uint_least32_t)buf[app->llHdrEnd+16]) << 24 - | ((uint_least32_t)buf[app->llHdrEnd+17]) << 16 - | buf[app->llHdrEnd+18] << 8 - | buf[app->llHdrEnd+19] ; - app->netHdrEnd = app->llHdrEnd + netHdrLen; - app->netBodyLen = app->netTotLen - netHdrLen; -} - - -static void parse_trsp_TCP( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){ - assert(hdr->caplen >= app->netHdrEnd+12 && "TODO_058d5f41043d383e1ba2c492d0db4b6a"); - app->trspSrcPort = buf[app->netHdrEnd+0] << 8 | buf[app->netHdrEnd+1]; - app->trspDstPort = buf[app->netHdrEnd+2] << 8 | buf[app->netHdrEnd+3]; - int tcpHdrLen = (buf[app->netHdrEnd+12] >> 4) * 4; - app->trspHdrEnd = app->netHdrEnd + tcpHdrLen; - app->trspBodyLen = app->netBodyLen - tcpHdrLen; -} - - -static void parse_appl_HTTP_req( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){ - app->flg |= FLG_isHttpReq; - app->httpReqHeadline = buf + app->trspHdrEnd; - app->httpReqHeadline_len = 0; - for(;; ++app->httpReqHeadline_len ){ - if( (app->trspHdrEnd + app->httpReqHeadline_len) > hdr->caplen ) break; - if( app->httpReqHeadline[app->httpReqHeadline_len] == '\r' ) break; - if( app->httpReqHeadline[app->httpReqHeadline_len] == '\n' ) break; - } - /* TODO improve, as now its like a guess only */ - int isNewRequest = 0 - | !memcmp(buf + app->trspHdrEnd, "GET ", 4) - | !memcmp(buf + app->trspHdrEnd, "PUT ", 4) - | !memcmp(buf + app->trspHdrEnd, "POST ", 5) - | !memcmp(buf + app->trspHdrEnd, "DELETE ", 7) - ; - if( isNewRequest ){ - app->httpReq_off = 0; - }else{ - app->httpReq_off = 42; /*TODO make more accurate*/ - } -} - - -static void printParsingResults( PcapOne*app, const struct pcap_pkthdr*hdr ){ - - int isHttpRequest = (app->flg & FLG_isHttpReq); - int isHttpReqBegin = isHttpRequest && app->httpReq_off == 0; - - if( isHttpRequest && isHttpReqBegin ){ - /* find http method */ - const uint8_t *method = app->httpReqHeadline; - int method_len = 0; - for(;; ++method_len ){ - if( method_len > app->httpReqHeadline_len ) break; - if( method[method_len] == ' ' ) break; - } - /* find http uri */ - const uint8_t *uri = method + method_len + 1; - int uri_len = 0; - for(;; ++uri_len ){ - if( method_len + uri_len > app->httpReqHeadline_len ) break; - if( uri[uri_len] == ' ' ) break; - } - if( !(app->flg & FLG_isHdrPrinted) ){ - app->flg |= FLG_isHdrPrinted; - printf("h;Title;HTTP requests\n"); - printf("c;epochSec;srcIp;dstIp;srcPort;dstPort;http_method;http_uri\n"); - } - /* print it as a quick-n-dirty CSV record */ - printf("r;%ld.%06ld;%d.%d.%d.%d;%d.%d.%d.%d;%d;%d;%.*s;%.*s\n", - hdr->ts.tv_sec, hdr->ts.tv_usec, - app->ipSrcAddr >> 24, app->ipSrcAddr >> 16 & 0xFF, app->ipSrcAddr >> 8 & 0xFF, app->ipSrcAddr & 0xFF, - app->ipDstAddr >> 24, app->ipDstAddr >> 16 & 0xFF, app->ipDstAddr >> 8 & 0xFF, app->ipDstAddr & 0xFF, - app->trspSrcPort, app->trspDstPort, - method_len, method, uri_len, uri); - } -} - - -static int run( PcapOne*app ){ - int err; - err = pcap_init(PCAP_CHAR_ENC_UTF_8, app->pcapErrbuf); - if( err == PCAP_ERROR ){ - fprintf(stderr, "libpcap: %s\n", app->pcapErrbuf); err = -1; goto endFn; } - app->pcap = pcap_open_offline( - (app->dumpFilePath == DEV_STDIN) ? "-" : app->dumpFilePath, - app->pcapErrbuf); - if( app->pcap == NULL ){ - fprintf(stderr, "libpcap: %s\n", app->pcapErrbuf); err = -1; goto endFn; } - for(;;){ - err = pcap_dispatch(app->pcap, -1, onPcapPkg, (void*)app); - switch( err ){ - case PCAP_ERROR: - fprintf(stderr, "pcap_dispatch(): %s\n", pcap_geterr(app->pcap)); - err = -1; goto endFn; - case PCAP_ERROR_BREAK: - case PCAP_ERROR_NOT_ACTIVATED: - fprintf(stderr, "pcap_dispatch() -> %d\n", err); - err = -1; goto endFn; - } - if( err > 0 ){ - fprintf(stderr, "Processed %d packages in this turn.\n", err); - continue; - } - break; - } - err = 0; -endFn: - if( app->pcap != NULL ){ pcap_close(app->pcap); app->pcap = NULL; } - return err; -} - - -int main( int argc, char**argv ){ - int err; - static char errbuf[PCAP_ERRBUF_SIZE]; - errbuf[0] = '\0'; - PcapOne app = { - .flg = FLG_INIT, - .pcapErrbuf = errbuf, - .pcap = NULL, - .frameNr = 0, - .trspBodyLen = 0, - }; - #define app (&app) - - err = parseArgs(app, argc, argv); - if( err ){ goto endFn; } - - if( app->flg & FLG_isHelp ){ - printHelp(); goto endFn; } - - err = run(app); - -endFn: - if( err < 0 ) err = -err; - if( err > 0x7F ) err = 1; - return err; - #undef app -} - - |