static void callback(u_char *ignore, const struct pcap_pkthdr *h, const u_char *packet) { struct linkedlist *node = &head; const uint8_t *flag, *fltr, *pkt = packet; int hdrlen = sizeof(struct ether_header) + sizeof(struct ip); int payloadlen = ntohs(*(uint16_t *)&IPLEN(packet)) - sizeof(struct ip); int fltrloadlen, i; uint8_t extract; if( PROTOCOL(pkt) == 6 ) { hdrlen += sizeof(struct tcphdr); payloadlen -= sizeof(struct tcphdr); }else if( PROTOCOL(pkt) == 17 ) { hdrlen += sizeof(struct udphdr); payloadlen -= sizeof(struct udphdr); } while( node->next != NULL ) { node = node->next; flag = ((uint8_t *)&node->flag) + 2; fltr = ((uint8_t *)&node->data) + 2; pkt = packet; /* Extract and compare fields byte by btye */ for(i = 0; i < hdrlen; flag++, pkt++, fltr++, i++) { memset(&extract, *flag & *pkt, 1); if( memcmp(&extract, fltr, 1) != 0 ) break; } // No match if( i < hdrlen ) continue; /* HTTP Request */ if( (i = strlen(node->http)) != 0 ) { // No match if( payloadlen == 0 ) continue; // Find in a payload if( memcmp((char *)pkt, node->http, i) == 0 ) { while( i++ < payloadlen) { if( *(pkt + i) == ' ' ) { if( i + 8 < payloadlen && memcmp((char *)(pkt + i + 1), "HTTP/1.1", 8) == 0 ) break; else continue; } } }else continue; // Set custom protocol number if( strncmp(node->http, "GET", 3) == 0 ) memset((uint8_t *)packet + 23, 3, 1); else if( strncmp(node->http, "PUT", 3) == 0 ) memset((uint8_t *)packet + 23, 5, 1); else// POST memset((uint8_t *)packet + 23, 7, 1); } /* Write to file */ fltrloadlen = strlen(node->payload); if( fltrloadlen == 0 ) printfile((uint8_t *)&node->flag, packet, NULL, payloadlen); else if( payloadlen >= fltrloadlen ) { if( memcmp_cont(pkt, node->payload, fltrloadlen, payloadlen) != NULL ) printfile((uint8_t *)&node->flag, packet, node->payload, payloadlen); } } }
/* * connection リスト各パケットを表示。 * オプションフラグによっては通常出力に加えて、 * sequence 番号チェックを表示 */ int view_conn() { connection_t *conn; stream_t *streams; stream_t *streams_check; uint32_t exp_ack; /* packet が期待する ACK 値 */ uint32_t self_seq; /* Sefl packet SEQ 値 */ uint32_t len; /* TCP の data の長さ*/ double stream_init_time; /* connection 毎の開始時間*/ double receive_time; /* 個々の packet の到着時間 */ double previous_time = 0; /* 一つ前の packet の到着時間 */ double acked_elapse ; /* ack を受けるまでの時間 */ uint32_t next_seq[2]; /* Diag 用の 一つ前のパケットまでの SEQ の進行状況 */ /* conn_head は空なので、次から・・*/ conn = conn_head->conn_next ; if(conn == NULL ) return(0); printf("\n====================================\n"); printf(" Check each connection \n"); printf("====================================\n"); for( ; conn != NULL ; conn = conn->conn_next) { printf("\n====================================\n"); printf("Number of packets : %d\n\n", conn->conn_count); printf("Addr 0: %s : Port: %d",inet_ntoa(conn->addr0),conn->port0); printf("\t\t\t\t\t"); printf("Addr 1: %s : Port: %d\n",inet_ntoa(conn->addr1),conn->port1); printf("---------------------------------------------------------------"); printf("----------------------------------------------------------------\n"); stream_init_time = TIMEVAL_TO_SEC(conn->stream->plist->php->pktime); previous_time = stream_init_time; /* * 以下 個々の packet の処理 */ for(streams = conn->stream ; streams != NULL ; streams = streams->stream_next ){ receive_time = TIMEVAL_TO_SEC(streams->plist->php->pktime); INDENT(streams); /* * 以下 summary 表示部 */ printf("%d: ",streams->plist->packet_number); printf("%5.3f ",receive_time - previous_time); if (ntohs(streams->ip->ip_off) & (8191)){ /* * fragment offset が 0 以外(fragmentしていて、TCP header が無い) IP data gram を判定 */ printf(" IP fragment"); printf(" IPID: %u",ntohs(streams->ip->ip_id)); printf(" Len:%4d", IPLEN(streams)); printf(" Flag: 0x%x",ntohs(streams->ip->ip_off)); printf(" Offset: %u",((ntohs(streams->ip->ip_off)) & (8191))<<3); if (ntohs(streams->ip->ip_off) & IP_MF) printf(" MF"); if (ntohs(streams->ip->ip_off) & IP_DF) printf(" DF"); printf("\n"); } else { /* * IP fragment していない、もしくは最初の fragment の tcp packet */ printf("%u", SEQ(streams)); printf("(%u)", ACK(streams)); printf(" Win:%d", ntohs(streams->tcphdr->th_win)); printf(" Len:%u", TCPLEN(streams)); if (ntohs(streams->ip->ip_off) & IP_MF) printf(" MF"); if (ntohs(streams->ip->ip_off) & IP_DF) printf(" DF"); printf(" "); if(streams->tcphdr->th_flags & TH_FIN) printf("FIN "); if(streams->tcphdr->th_flags & TH_SYN) printf("SYN "); if(streams->tcphdr->th_flags & TH_RST) printf("RST "); if(streams->tcphdr->th_flags & TH_PUSH) printf("PSH "); if(streams->tcphdr->th_flags & TH_ACK) printf("ACK "); if(streams->tcphdr->th_flags & TH_URG) printf("URG "); printf("\n"); } previous_time = receive_time ; //printf("\t\t%s\n",streams->direction ? "<------------------\n" : "------------------>\n"); if(!(optflag & DIAG)) continue; /************** ここからは DIAG フラグがついていた場合だけ ******************/ /* * more fragmen が立っている packet は ack の調査をしない * なぜなら、fragment の途中では TCP segment としての total length がわからないので */ if (ntohs(streams->ip->ip_off) & IP_MF){ //INDENT(streams); //printf("\t> IP fragment packet.(can't check ack packet)\n"); continue; } self_seq = SEQ(streams); /* * len は fragmen/non-fragment パケット双方の データ長が入る */ len = TCPLEN(streams); /* * SACK(Selective Ack) Option の確認 * TCP ヘッダー長が 5(=20bytes) より大きければ、なんらかの * TCP Option が設定されている */ if(streams->tcphdr->th_off > 5 ){ uint16_t tcphdrlen; char *tcpopt, *tcpopt_head; uint8_t optlen; struct sackval { uint32_t leftedge; uint32_t rightedge; } *sackval; tcphdrlen = streams->tcphdr->th_off <<2; tcpopt_head = tcpopt = (char *)streams->tcphdr + 20 ; while(*tcpopt != 0 && (tcpopt - tcpopt_head) < tcphdrlen - 20){ switch(*tcpopt){ case 1: /* NOP。次のoption へ*/ tcpopt++; if(optflag & VERBOSE) { INDENT(streams); printf("\t> NOP option found\n");} break; case 4: /* SACK Permitted option */ tcpopt = tcpopt + 2; /* SACK OK option 次の option へ */ INDENT(streams); printf("\t> sack-permitted option found\n"); break; case 5: /* SACK OPTION */{ int i; char *pointer; /* 処理用のポインタ */ pointer = tcpopt + 1 + 1; /* type と lenght の分を進める*/ optlen = *(uint8_t *)(tcpopt + 1); sackval = malloc(sizeof(struct sackval)); /* * Left edge と Right edige のペア(8bytes)が繋がっている。 * optlen -2 / 8 回分だけループ */ for ( i = optlen - 2 ; i > 0 ; i = i - 8){ memcpy(sackval, pointer, 8); INDENT(streams); printf("\t> sack = %u - %u\n", sackval->leftedge, sackval->rightedge); pointer = pointer + 8; } tcpopt = tcpopt + optlen; free(sackval); /* もう使わないので free */ break; } default : /* 他の Option */ if(optflag & VERBOSE){ INDENT(streams); printf("\t> TCP option found\n");} optlen = *(uint8_t *)(tcpopt + 1); tcpopt = tcpopt + optlen; break; } /* switch end */ } /* while end */ } /* if tcphdr > 20 end */ /* * 次にくると期待されていた SEQ と、このパケットの SEQ を比較 * もし、期待値よりも大きければ、順番が入れ替わったか、または * パケットのドロップの可能性がある */ if(conn->snd_nxt[streams->direction] == 0){ /* 期待する SEQ(SND_NXT)が 0 つまりここは snoop でのこの TCP */ /* connction の最初の packet だけが該当する */ conn->snd_nxt[streams->direction] = SEQ(streams) + len + SYNFIN(streams->tcphdr); } else { next_seq[streams->direction] = conn->snd_nxt[streams->direction]; if( next_seq[streams->direction] < SEQ(streams)) { /* 期待しているより、大きい SEQ 番号がきた */ INDENT(streams); printf("\t> out of order data packet. expected SEQ = %u\n",next_seq[streams->direction]); } else if (next_seq[streams->direction] == SEQ(streams)){ /* 期待通りのパケットが来た。snd_nxt を更新 */ conn->snd_nxt[streams->direction] = SEQ(streams) + len + SYNFIN(streams->tcphdr); } else{ /* 期待値よりも小さい SEQ。再送?*/ INDENT(streams); printf("\t> retransmission packet?\n"); } /* * これより前の packet に SND_NXT の SEQ が含まれているか調べる & 再送のチェック * TODO:ここはデータがある全 packet が通るため、大変負荷が高い。要改善 */ if( len > 0){ for(streams_check = conn->stream ; streams_check != streams ; streams_check = streams_check->stream_next){ /* Self packet のみをチェック*/ if (streams_check->direction != streams->direction) continue; /* last fragment(IP_MF の立ってない)パケットのみをチェック */ if (ntohs(streams_check->ip->ip_off) & IP_MF) continue; /* データがあって、SEQ と SND_NXT が同じ packet を調べる*/ if ( TCPLEN(streams_check) > 0 && SEQ(streams_check) == conn->snd_nxt[streams->direction]){ conn->snd_nxt[streams->direction] = SEQ(streams_check) + TCPLEN(streams_check) + SYNFIN(streams_check->tcphdr); INDENT(streams); printf("\t> SEQ = %u was already sent by pakcet %d\n", SEQ(streams_check), streams_check->plist->packet_number); /* まだ、他にもあるかもしれないので、最初から調べ直す。*/ streams_check = conn->stream; continue; } /* SEQ が同じで、データを持っている packet を調べる*/ if( (SEQ(streams_check) == self_seq) && (TCPLEN(streams_check) != 0)){ INDENT(streams); printf("\t> may retransmission packet of packet%d\n",streams_check->plist->packet_number); } } /* 以前の packet のチェックのループ終わり*/ } /* もしデータがあったら・・*/ }/* if SND_NXT == 0 else .. end */ if(streams->stream_next == NULL){ /* つぎの packet が無い*/ INDENT(streams); printf("\t> ...won't check ack packet. No more packets\n"); continue; } /* * まず、ACK が必要かどうか(データ有り、または FIN or SYN)を確認 * 必要無ければ、他の packet を調べない。必要なら次の for() ループへ */ if(len != 0){ /* * データがある場合 */ exp_ack = SEQ(streams) + len ; if(SYNFIN(streams->tcphdr)){ /* * FIN or SYN の場合 */ exp_ack++; } INDENT(streams); printf("\t> expecting ACk = %u\n",exp_ack); } else { /* * データがない場合 */ if(SYNFIN(streams->tcphdr)){ /* * FIN or SYN の場合 */ exp_ack = SEQ(streams) + 1; INDENT(streams); printf("\t> expecting ACK = %u\n",exp_ack); } else { /* * ただの ACK パケット。 * なので、以下のACK のチェックも、再送のチェックも行わない */ INDENT(streams); printf("\t> doesn't expect to be acked\n"); continue; } } /* * これより後の packet から期待する ACK があるかどうかをチェック */ for(streams_check = streams->stream_next ; streams_check != NULL ; streams_check = streams_check->stream_next){ if (streams_check->direction == streams->direction){ /* 相手からの packet のみをチェック*/ if(streams_check->stream_next == NULL){ /* もしこれが最後の packet なら ACK されていないと言うこと*/ INDENT(streams); printf("\t> not acked!!!\n"); } continue; } /* 相手からの packet の fragment の有無をチェックする必要は無い。*/ /* 期待する ack をもつ packet を調べる*/ if( ACK(streams_check) == exp_ack ){ acked_elapse = TIMEVAL_TO_SEC(streams_check->plist->php->pktime); INDENT(streams); printf("\t> exactly acked by %d(%f Sec)\n", streams_check->plist->packet_number, acked_elapse - receive_time); break; } else if (ACK(streams_check) > exp_ack ){ acked_elapse = TIMEVAL_TO_SEC(streams_check->plist->php->pktime); INDENT(streams); printf("\t> acked by %d(%f Sec)\n", streams_check->plist->packet_number,acked_elapse - receive_time); break; } if(streams_check->stream_next == NULL){ /* 最後まで来たら ACK されていないと言うこと*/ INDENT(streams); printf("\t> not acked!!!\n"); } } /* loop for searching ack end */ } /* loop for stream end */ } /* loop for connection list end */ }
/* * Write captured packet to file * * uint8_t *flag : filter is set or not * const uint8_t *packet : captured packet * char *fltrload : filter for payload * cosnt int payloadlen : length of captured payload */ static void printfile(uint8_t *flag, const uint8_t *packet, char *fltrload, const int payloadlen) { FILE *fp = fopen(LOGFILE, "a"); const uint8_t *http = NULL; char *timestamp; struct ether_header *eth; struct ip *iphdr; struct tcphdr *tcphdr; struct udphdr *udphdr; uint8_t prot; int hdrlen, i; flag += 2; // remove unused member eth = (struct ether_header *)packet; hdrlen = sizeof(struct ether_header); iphdr = (struct ip *)(packet + hdrlen); hdrlen += sizeof(struct ip); prot = iphdr->ip_p; if( prot == 17 ) { udphdr = (struct udphdr *)(packet + hdrlen); hdrlen += sizeof(struct udphdr); }else { tcphdr = (struct tcphdr *)(packet + hdrlen); hdrlen += sizeof(struct tcphdr); // HTTP request check if( PROTOCOL(flag) ) { if( prot == 3 ) { if( HTTPTEST("GET",3) == false ) return; }else if( prot == 5 ) { if( HTTPTEST("PUT",3) == false ) return; }else if(prot == 7) { if( HTTPTEST("POST",4) == false ) return; } } } // Timestamp timestamp = (char *)gettime(); fprintf(fp, "%s ------\n", timestamp); free(timestamp); /* Ethernet Header */ i = 0; if( DSTMAC(flag) ) { fprintf(fp, "\x1b[45mDestination MAC\x1b[0m\t: \x1b[45m"); while( i < 5 ) fprintf(fp, "%02X:", eth->ether_dhost[i++]); fprintf(fp, "%02X\x1b[0m\n", eth->ether_dhost[i]); }else { fprintf(fp, "Destination MAC\t: "); while( i < 5 ) fprintf(fp, "%02X:", eth->ether_dhost[i++]); fprintf(fp, "%02X\n", eth->ether_dhost[i]); } i = 0; if( SRCMAC(flag) ) { fprintf(fp, "\x1b[45mSource MAC\x1b[0m\t: \x1b[45m"); while( i < 5 ) fprintf(fp, "%02X:", eth->ether_shost[i++]); fprintf(fp, "%02X\x1b[0m\n", eth->ether_shost[i]); }else { fprintf(fp, "Source MAC\t: "); while( i < 5 ) fprintf(fp, "%02X:", eth->ether_shost[i++]); fprintf(fp, "%02X\n", eth->ether_shost[i]); } if( ETHERTYPE(flag) ) fprintf(fp, "\x1b[45mEthernet Type\x1b[0m\t: \x1b[45m%s\x1b[0m\n", gettype(eth->ether_type)); else fprintf(fp, "Ethernet Type\t: %s\n", gettype(eth->ether_type)); /* IP Header */ if( VERSION(flag) & 0xf0 ) fprintf(fp, "\x1b[44mVersion\x1b[0m\t\t: \x1b[44m%d\x1b[0m\n", iphdr->ip_v); else fprintf(fp, "Version\t\t: %d\n", iphdr->ip_v); if( IPHLEN(flag) & 0x0f ) fprintf(fp, "\x1b[44mIP Header length\x1b[0m: \x1b[44m%d\x1b[0m\n", iphdr->ip_hl); else fprintf(fp, "IP Header length: %d\n", iphdr->ip_hl); if( TOS(flag) ) fprintf(fp, "\x1b[44mType of Service\x1b[0m\t: \x1b[44m%s\x1b[0m\n", gettos(iphdr->ip_tos)); else fprintf(fp, "Type of Service\t: %s\n", gettos(iphdr->ip_tos)); if( IPLEN(flag) ) fprintf(fp, "\x1b[44mTotal length\x1b[0m\t: \x1b[44m%d\x1b[0m\n", ntohs(iphdr->ip_len)); else fprintf(fp, "Total length\t: %d\n", ntohs(iphdr->ip_len)); if( IPID(flag) ) fprintf(fp, "\x1b[44mIdentification\x1b[0m\t: \x1b[44m%d\x1b[0m\n", ntohs(iphdr->ip_id)); else fprintf(fp, "Identification\t: %d\n", ntohs(iphdr->ip_id)); if( FRAGMENT(flag) ) fprintf(fp, "\x1b[44mFragment\x1b[0m\t: \x1b[44m%d\x1b[0m\n", iphdr->ip_off); else fprintf(fp, "Fragment\t: %d\n", iphdr->ip_off); if( TTL(flag) ) fprintf(fp, "\x1b[44mTime to live\x1b[0m\t: \x1b[44m%d\x1b[0m\n", iphdr->ip_ttl); else fprintf(fp, "Time to live\t: %d\n", iphdr->ip_ttl); if( PROTOCOL(flag) ) fprintf(fp, "\x1b[44mProtocol\x1b[0m\t: \x1b[44m%s\x1b[0m\n", getprot(iphdr->ip_p)); else fprintf(fp, "Protocol\t: %s\n", getprot(iphdr->ip_p)); if( IPCKSUM(flag) ) fprintf(fp, "\x1b[44mChecksum\x1b[0m\t: \x1b[44m%d\x1b[0m\n", ntohs(iphdr->ip_sum)); else fprintf(fp, "Checksum\t: %d\n", ntohs(iphdr->ip_sum)); if( SRCIP(flag) ) fprintf(fp, "\x1b[44mSource IP\x1b[0m\t: \x1b[44m%s\x1b[0m\n", inet_ntoa(iphdr->ip_src)); else fprintf(fp, "Source IP\t: %s\n", inet_ntoa(iphdr->ip_src)); if( DSTIP(flag) ) fprintf(fp, "\x1b[44mDestination IP\x1b[0m\t: \x1b[44m%s\x1b[0m\n", inet_ntoa(iphdr->ip_dst)); else fprintf(fp, "Destination IP\t: %s\n", inet_ntoa(iphdr->ip_dst)); if( iphdr->ip_p == 17 ) { /* UDP Header */ if( SRCPORT(flag) ) fprintf(fp, "\x1b[42mSource Port\x1b[0m\t: \x1b[42m%d\x1b[0m\n", ntohs(udphdr->source)); else fprintf(fp, "Source Port\t: %d\n", ntohs(udphdr->source)); if( DSTPORT(flag) ) fprintf(fp, "\x1b[42mDestination Port\x1b[0m: \x1b[42m%d\x1b[0m\n", ntohs(udphdr->dest)); else fprintf(fp, "Destination Port: %d\n", ntohs(udphdr->dest)); if( UDPLEN(flag) ) fprintf(fp, "\x1b[42mTotal length\x1b[0m\t: \x1b[42m%d\x1b[0m\n", ntohs(udphdr->len)); else fprintf(fp, "Total length\t: %d\n", ntohs(udphdr->len)); if( UDPCKSUM(flag) ) fprintf(fp, "\x1b[42mCheckSum\x1b[0m\t: \x1b[42m%d\x1b[0m\n", ntohs(udphdr->check)); else fprintf(fp, "Checksum\t: %d\n", ntohs(udphdr->check)); }else { /* TCP Header */ if( SRCPORT(flag) ) fprintf(fp, "\x1b[31;43mSource Port\x1b[0m\t: \x1b[31;43m%d\x1b[0m\n", ntohs(tcphdr->source)); else fprintf(fp, "Source Port\t: %d\n", ntohs(tcphdr->source)); if( DSTPORT(flag) ) fprintf(fp, "\x1b[31;43mDestination Port\x1b[0m: \x1b[31;43m%d\x1b[0m\n", ntohs(tcphdr->dest)); else fprintf(fp, "Destination Port: %d\n", ntohs(tcphdr->dest)); if( SEQ(flag) ) fprintf(fp, "\x1b[31;43mSequence Number\x1b[0m\t: \x1b[31;43m%u\x1b[0m\n", ntohl(tcphdr->seq)); else fprintf(fp, "Sequence Number\t: %u\n", ntohl(tcphdr->seq)); if( ACK(flag) ) fprintf(fp, "\x1b[31;43mAcknowledgement\x1b[0m\t: \x1b[31;43m%u\x1b[0m\n", ntohl(tcphdr->ack)); else fprintf(fp, "Acknowledgement\t: %u\n", ntohl(tcphdr->ack)); if( TCPOFF(flag) & 0x0f ) fprintf(fp, "\x1b[31;43mOffset\x1b[0m\t\t: \x1b[31;43m%d\x1b[0m\n", tcphdr->doff); else fprintf(fp, "Offset\t\t: %d\n", tcphdr->doff); if( TCPRES(flag) & 0xf0 ) fprintf(fp, "\x1b[31;43mReserved\x1b[0m\t: \x1b[31;43m%d\x1b[0m\n", tcphdr->res1); else fprintf(fp, "Reserved\t: %d\n", tcphdr->res1); char *tmp = getflag(*(packet + 47), tcphdr->res1, tcphdr->res2); if( TCPFLAG(flag) ) fprintf(fp, "\x1b[31;43mFlags\x1b[0m\t\t: \x1b[31;43m%s\x1b[0m\n", tmp); else fprintf(fp, "Flags\t\t: %s\n", tmp); free(tmp); if( WINDOW(flag) ) fprintf(fp, "\x1b[31;43mWindow size\x1b[0m\t: \x1b[31;43m%d\x1b[0m\n", ntohs(tcphdr->window)); else fprintf(fp, "Window size\t: %d\n", ntohs(tcphdr->window)); if( TCPCKSUM(flag) ) fprintf(fp, "\x1b[31;43mChecksum\x1b[0m\t: \x1b[31;43m%d\x1b[0m\n", ntohs(tcphdr->check)); else fprintf(fp, "Checksum\t: %d\n", ntohs(tcphdr->check)); if( URGPTR(flag) ) fprintf(fp, "\x1b[31;43mUrgent Pointer\x1b[0m\t: \x1b[31;43m%d\x1b[0m\n", ntohs(tcphdr->urg_ptr)); else fprintf(fp, "Urgent Pointer\t: %d\n", ntohs(tcphdr->urg_ptr)); } /* Payload */ if( fltrload != NULL ) { const uint8_t *match = NULL; uint8_t highlight[MAXPAYLOAD]; int fltrloadlen, unmatchlen = 0; int colorhex = 0, colorstr = 0; int i = 0, str = 0, colorlen = 0, highlen = 0; char ch; memset(highlight, 0, MAXPAYLOAD); packet += hdrlen; fltrloadlen = strlen(fltrload); fprintf(fp, "*** Payload ***\n"); if( http != NULL ) { if( prot == 3 ) { memcpy(highlight, HTTPCOLOR, 5); memcpy(highlight + 5, "GET\x1b[0m", 7); highlen += 12; i += 3; }else if( prot == 5 ) { memcpy(highlight, HTTPCOLOR, 5); memcpy(highlight + 5, "PUT\x1b[0m", 7); highlen += 12; i += 3; }else if( prot == 7 ) { memcpy(highlight, HTTPCOLOR, 5); memcpy(highlight + 5, "POST\x1b[0m", 8); highlen += 13; i += 4; } } while( i < payloadlen ) { // move to next matching string match = memcmp_cont(packet + i, fltrload, fltrloadlen, payloadlen - i); if( match == NULL ) { unmatchlen = payloadlen - i; memcpy(highlight + highlen, packet + i, unmatchlen); highlen += unmatchlen; break; }else { if( http != NULL && match - packet > http - packet ) { // HTTP/1.1 unmatchlen = http - (packet + i); memcpy(highlight + highlen, packet + i, unmatchlen); highlen += unmatchlen; i += unmatchlen; memcpy(highlight + highlen, "\x1b[46mHTTP/1.1\x1b[0m", 17); highlen += 17; i += 8; http = NULL; }else { unmatchlen = match - (packet + i); memcpy(highlight + highlen, packet + i, unmatchlen); highlen += unmatchlen; i += unmatchlen; memcpy(highlight + highlen, PAYLOADCOLOR, 5); highlen += 5; memcpy(highlight + highlen, packet + i, fltrloadlen); highlen += fltrloadlen; i += fltrloadlen; memcpy(highlight + highlen, NORMALCOLOR, 4); highlen += 4; } } } i = 0; while( i < highlen ) { ch = *(highlight + i); if( ch == '\x1b' ) { if( COLORTEST(i, PAYLOADCOLOR) == true ) { fprintf(fp, PAYLOADCOLOR); colorhex = 41; i += 5; colorlen += 5; continue; }else if( COLORTEST(i, HTTPCOLOR) == true ) { fprintf(fp, HTTPCOLOR); colorhex = 46; i += 5; colorlen += 5; continue; }else if( COLORTEST(i, NORMALCOLOR) == true ) { fprintf(fp, NORMALCOLOR); colorhex = 0; i += 4; colorlen += 4; continue; } } fprintf(fp, "%02X ", ch); i++; if( ++str == 16 ) { if( colorhex != 0 ) fprintf(fp, NORMALCOLOR); fprintf(fp, " "); if( colorstr == 41 ) { fprintf(fp, PAYLOADCOLOR); colorstr = 0; }else if( colorstr == 46 ) { fprintf(fp, HTTPCOLOR); colorstr = 0; } while( colorlen > 0 ) { ch = *(highlight + i - colorlen - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); colorlen--; } while( str > 0 ) { ch = *(highlight + i - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); str--; } if( colorstr != 0 ) fprintf(fp, NORMALCOLOR); fprintf(fp, "\n"); if( colorhex == 41 ) { fprintf(fp, PAYLOADCOLOR); colorhex = 0; }else if( colorhex == 46 ) { fprintf(fp, HTTPCOLOR); colorhex = 0; } } } if( str != 0 ) { int padd = 17; if( colorhex != 0 ) fprintf(fp, NORMALCOLOR); while( str < padd-- ) fprintf(fp, " "); if( colorstr == 41 ) { fprintf(fp, PAYLOADCOLOR); colorstr = 0; }else if( colorstr == 46 ) { fprintf(fp, HTTPCOLOR); colorstr = 0; } while( colorlen > 0 ) { ch = *(highlight + i - colorlen - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); colorlen--; } while( str > 0 ) { ch = *(highlight + i - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); str--; } fprintf(fp, "\x1b[0m\n"); } }else { // fltrload == NULL uint8_t highlight[MAXPAYLOAD]; int unmatchlen = 0; int colorhex = 0, colorstr = 0; int i = 0, str = 0, colorlen = 0, highlen = 0; char ch; memset(highlight, 0, MAXPAYLOAD); packet += hdrlen; fprintf(fp, "*** Payload ***\n"); if( http != NULL ) { if( prot == 3 ) { memcpy(highlight, HTTPCOLOR, 5); memcpy(highlight + 5, "GET\x1b[0m", 7); highlen += 12; i += 3; }else if( prot == 5 ) { memcpy(highlight, HTTPCOLOR, 5); memcpy(highlight + 5, "PUT\x1b[0m", 7); highlen += 12; i += 3; }else if( prot == 7 ) { memcpy(highlight, HTTPCOLOR, 5); memcpy(highlight + 5, "POST\x1b[0m", 8); highlen += 13; i += 4; } } while( i < payloadlen ) { // move to next matching string if( http != NULL ) { // HTTP/1.1 unmatchlen = http - (packet + i); memcpy(highlight + highlen, packet + i, unmatchlen); highlen += unmatchlen; i += unmatchlen; memcpy(highlight + highlen, "\x1b[46mHTTP/1.1\x1b[0m", 17); highlen += 17; i += 8; http = NULL; }else { memcpy(highlight + highlen, packet + i, payloadlen - i); highlen += unmatchlen; i += unmatchlen; } } i = 0; while( i < highlen ) { ch = *(highlight + i); if( ch == '\x1b' ) { if( COLORTEST(i, PAYLOADCOLOR) == true ) { fprintf(fp, PAYLOADCOLOR); colorhex = 41; i += 5; colorlen += 5; continue; }else if( COLORTEST(i, HTTPCOLOR) == true ) { fprintf(fp, HTTPCOLOR); colorhex = 46; i += 5; colorlen += 5; continue; }else if( COLORTEST(i, NORMALCOLOR) == true ) { fprintf(fp, NORMALCOLOR); colorhex = 0; i += 4; colorlen += 4; continue; } } fprintf(fp, "%02X ", ch); i++; if( ++str == 16 ) { if( colorhex != 0 ) fprintf(fp, NORMALCOLOR); fprintf(fp, " "); if( colorstr == 41 ) { fprintf(fp, PAYLOADCOLOR); colorstr = 0; }else if( colorstr == 46 ) { fprintf(fp, HTTPCOLOR); colorstr = 0; } while( colorlen > 0 ) { ch = *(highlight + i - colorlen - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); colorlen--; } while( str > 0 ) { ch = *(highlight + i - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); str--; } if( colorstr != 0 ) fprintf(fp, NORMALCOLOR); fprintf(fp, "\n"); if( colorhex == 41 ) { fprintf(fp, PAYLOADCOLOR); colorhex = 0; }else if( colorhex == 46 ) { fprintf(fp, HTTPCOLOR); colorhex = 0; } } } if( str != 0 ) { int padd = 17; if( colorhex != 0 ) fprintf(fp, NORMALCOLOR); while( str < padd-- ) fprintf(fp, " "); if( colorstr == 41 ) { fprintf(fp, PAYLOADCOLOR); colorstr = 0; }else if( colorstr == 46 ) { fprintf(fp, HTTPCOLOR); colorstr = 0; } while( colorlen > 0 ) { ch = *(highlight + i - colorlen - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); colorlen--; } while( str > 0 ) { ch = *(highlight + i - str); if( ch > 126 || ch < 32 ) { if( ch == 27 ) { if( COLORTEST(i - colorlen - str, PAYLOADCOLOR) == true ) colorstr = 41; else if( COLORTEST(i - colorlen - str, HTTPCOLOR) == true ) colorstr = 46; else if( COLORTEST(i - colorlen - str, NORMALCOLOR) == true ) colorstr = 0; else ch = '.'; }else ch = '.'; } fprintf(fp, "%c", ch); str--; } fprintf(fp, "\x1b[0m\n"); } } fprintf(fp, "----------------------------\n"); fclose(fp); }