diff --git a/sample/dpsws2016/ICMP-captured.pcap b/sample/dpsws2016/ICMP-captured.pcap new file mode 100644 index 0000000..c4a9270 Binary files /dev/null and b/sample/dpsws2016/ICMP-captured.pcap differ diff --git a/sample/dpsws2016/ICMP-generated.pcap b/sample/dpsws2016/ICMP-generated.pcap new file mode 100644 index 0000000..8617a98 Binary files /dev/null and b/sample/dpsws2016/ICMP-generated.pcap differ diff --git a/sample/dpsws2016/Makefile b/sample/dpsws2016/Makefile new file mode 100644 index 0000000..8233752 --- /dev/null +++ b/sample/dpsws2016/Makefile @@ -0,0 +1,7 @@ +all: + g++ -o dpsws2016-analyze -g -O0 -std=c++11 -I../../include/ dpsws2016-analyze.cc -L../../ -lpgen2 + g++ -o dpsws2016-generate -g -O0 -std=c++11 -I../../include/ dpsws2016-generate.cc -L../../ -lpgen2 + +clean: + rm -rf a.out dpsws2016-analyze dpsws2016-create + diff --git a/sample/dpsws2016/README.md b/sample/dpsws2016/README.md new file mode 100644 index 0000000..f2eca99 --- /dev/null +++ b/sample/dpsws2016/README.md @@ -0,0 +1,44 @@ + +# これは何 + +DPSWS2016田沢湖で発案した +アプリケーションのコードです + +テキストで指定したフォーマットでパケットを解析するdpsws2016-analyzeと、 +テキストで指定したデータメッセージのパケットを作成するdpsws2016-genereteのプロトタイプなプログラムです。 + +## Usage + +``` +$ make clean +$ make +$ sudo ./dpsws2016-analyze ICMP-captured.pcap < dpsws2016-fmt-ICMP.txt +$ sudo ./dpsws2016-generate ICMP-generated.pcap < dpsws2016-msg-ICMP.txt +``` + +### パケット指定用フォーマット + +# フォーマット書式 + +description:dig|hex:bytes[:text] +............. + +# フォーマット書式の解説 + +description = 任意のASCIIテキスト +dig|hex = データの表記方法の選択、dig=10進数表記、hex=16進数表記 +bytes = データのバイト数、0または-1を指定すると無制限を指定 +[text] = パケット生成時に投入するデータ自体、前記のデータ指定方法(dig|hex)に則って、1バイトずつ、スペース区切りで記載する + +# サンプル + +dpsws2016-fmt-ICMP.txt = ICMPパケットを解析するためのフォーマット書式例(データ無し) +dpsws2016-msg-ICMP.txt = ICMPパケットを作成するためのフォーマット書式例(データ有り) + +#### 注意事項 + +現在のプロトタイプなプログラムでは、解析(dpsws2016-analyze)も作成(dpsws2016-generate)も、1パケットしか取り扱えません。 +解析時に複数パケットが含まれるpcapファイルをしていた場合、先頭の1パケットだけを解析します。 + + + diff --git a/sample/dpsws2016/dpsws2016-analyze b/sample/dpsws2016/dpsws2016-analyze new file mode 100644 index 0000000..0f04eac Binary files /dev/null and b/sample/dpsws2016/dpsws2016-analyze differ diff --git a/sample/dpsws2016/dpsws2016-analyze.cc b/sample/dpsws2016/dpsws2016-analyze.cc new file mode 100644 index 0000000..7dc4cba --- /dev/null +++ b/sample/dpsws2016/dpsws2016-analyze.cc @@ -0,0 +1,40 @@ + +#include +#include +#include "dpsws2016.h" + +static const char* getnow() +{ + static char str[32]; + time_t now = time(NULL); + struct tm* p = localtime(&now); + sprintf(str, "%02d:%02d:%02d", p->tm_hour, p->tm_min, p->tm_sec); + return str; +} + +int main(int argc, char** argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s pcapfile \n", argv[0]); + return -1; + } + + pgen::pcap_stream packet_stream(argv[1], pgen::open_mode::pcap_read); + + uint8_t buf[10000]; + size_t recvlen; + try { + recvlen = packet_stream.recv(buf, sizeof buf); + } catch (std::exception& e) { + return 0; + } + + if ( is_dpsws2016_packet(buf, recvlen) ) { + dpsws2016 pack(buf, recvlen); + printf("[%s] 0x%04x: \n", getnow()); + printf("%s\n", (pack.DPSWS2016.print_str()).c_str() ); + } + + return 0; +} + diff --git a/sample/dpsws2016/dpsws2016-fmt-ICMP.txt b/sample/dpsws2016/dpsws2016-fmt-ICMP.txt new file mode 100644 index 0000000..1ba9ec8 --- /dev/null +++ b/sample/dpsws2016/dpsws2016-fmt-ICMP.txt @@ -0,0 +1,10 @@ +Ether no vlan skip :hex:14 +IP skip:hex:9 +IP Proto:dig:1 +IP skip:hex:2 +IP Src Addr:hex:4 +IP Dst Addr:hex:4 +ICMP Type:dig:1 +ICMP Code:dig:1 +ICMP Checksum:hex:2 +ICMP Data:hex:-1 diff --git a/sample/dpsws2016/dpsws2016-generate b/sample/dpsws2016/dpsws2016-generate new file mode 100644 index 0000000..963dd07 Binary files /dev/null and b/sample/dpsws2016/dpsws2016-generate differ diff --git a/sample/dpsws2016/dpsws2016-generate.cc b/sample/dpsws2016/dpsws2016-generate.cc new file mode 100644 index 0000000..e839655 --- /dev/null +++ b/sample/dpsws2016/dpsws2016-generate.cc @@ -0,0 +1,24 @@ + +#include +#include "dpsws2016.h" + +int main(int argc, char** argv) +{ + + if (argc != 2) { + fprintf(stderr, "Usage: %s pcapfile \n", argv[0]); + return -1; + } + + try { + dpsws2016 pack; + pack.compile(); + pgen::pcap_stream pcap(argv[1], pgen::open_mode::pcap_write); + pcap << pack; + } catch (std::exception& e) { + printf("%s \n", e.what()); + } + + return 0; +} + diff --git a/sample/dpsws2016/dpsws2016-msg-ICMP.txt b/sample/dpsws2016/dpsws2016-msg-ICMP.txt new file mode 100644 index 0000000..0b4b62d --- /dev/null +++ b/sample/dpsws2016/dpsws2016-msg-ICMP.txt @@ -0,0 +1,10 @@ +Ether no vlan skip :hex:14:00 00 00 00 00 00 00 00 00 00 00 00 08 00 +IP skip:hex:9:45 00 00 54 13 E3 00 00 40 +IP Proto:dig:1:1 +IP skip:hex:2:68 C4 +IP Src Addr:hex:4:7F 00 00 01 +IP Dst Addr:hex:4:7F 00 00 01 +ICMP Type:dig:1:0 +ICMP Code:dig:1:0 +ICMP Checksum:hex:2:BA A7 +ICMP Data:hex:-1:25 80 00 01 49 2C 24 58 00 00 00 00 EE 7F 05 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 diff --git a/sample/dpsws2016/dpsws2016.h b/sample/dpsws2016/dpsws2016.h new file mode 100644 index 0000000..4a125fa --- /dev/null +++ b/sample/dpsws2016/dpsws2016.h @@ -0,0 +1,347 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct dpsws2016_s { + std::string desc; + uint8_t type; /* 10:digital, 16:hex, 2:bit*/ + uint16_t fmt_length; /* byte */ + uint8_t* msg; /* raw data, without regard type */ + uint16_t msg_length; /* byte */ + std::string text; /* strings regard type */ +}; + +class dpsws2016_header : public pgen::header { + public: + static const size_t min_length = 1; + static const size_t max_length = 10000; + struct dpsws2016_s dpsws2016_s_list[max_length]; + uint8_t* all_msg = NULL; + uint16_t all_msg_length = 0; + + public: + void clear() override + { + for(int i = 0; i < max_length; i++ ){ + dpsws2016_s_list[i].desc = ""; + dpsws2016_s_list[i].type = 0; + dpsws2016_s_list[i].fmt_length = 0; + if( dpsws2016_s_list[i].msg != NULL ){ + free(dpsws2016_s_list[i].msg); + } + dpsws2016_s_list[i].msg = NULL; + dpsws2016_s_list[i].msg_length = 0; + dpsws2016_s_list[i].text = ""; + } + if( all_msg != NULL ){ + free(all_msg); + } + all_msg = NULL; + all_msg_length = 0; + } + + void summary(bool moreinfo=false) const override + { + printf("DPSWS2016\n"); + } + + void write(void* buffer, size_t bufferlen) const override + { + if (bufferlen < min_length) { + throw pgen::exception("pgen::dpsws2016_header::write: buflen is too small"); + } + + uint8_t* buffer_point = reinterpret_cast(buffer); + + for(int i = 0; i < max_length; i++ ){ + if( dpsws2016_s_list[i].type != 0 ){ + memcpy(buffer_point, dpsws2016_s_list[i].msg, dpsws2016_s_list[i].msg_length); + buffer_point += dpsws2016_s_list[i].msg_length; + bufferlen -= dpsws2016_s_list[i].msg_length; + }else{ + break; + } + } + } + + void read(const void* buffer, size_t bufferlen ) override + { + char cbuf[16]; + + if (bufferlen < min_length) { + throw pgen::exception("pgen::dpsws2016_header::read: buflen is too small"); + } + + all_msg_length = bufferlen; + const uint8_t* buffer_point = reinterpret_cast(buffer); + all_msg = (uint8_t*)malloc(sizeof(uint8_t)*all_msg_length); + memcpy(all_msg, buffer_point, all_msg_length); + + for(int i = 0; i < max_length; i++ ){ + if( bufferlen > 0 ){ + if( dpsws2016_s_list[i].fmt_length > 0 ){ + dpsws2016_s_list[i].msg_length = dpsws2016_s_list[i].fmt_length; + }else{ + dpsws2016_s_list[i].msg_length = bufferlen; + } + dpsws2016_s_list[i].msg = (uint8_t*)malloc(sizeof(uint8_t)*dpsws2016_s_list[i].msg_length); + memset(dpsws2016_s_list[i].msg, 0, dpsws2016_s_list[i].msg_length); + memcpy(dpsws2016_s_list[i].msg, buffer_point, dpsws2016_s_list[i].msg_length); + dpsws2016_s_list[i].text = ""; + if( dpsws2016_s_list[i].type == 2 ){ + for( int j = 0; j < dpsws2016_s_list[i].msg_length; j++){ + sprintf(cbuf, "%08b ", dpsws2016_s_list[i].msg[j]); + dpsws2016_s_list[i].text.append(cbuf); + } + }else if( dpsws2016_s_list[i].type == 8 ){ + for( int j = 0; j < dpsws2016_s_list[i].msg_length; j++){ + sprintf(cbuf, "%04o ", dpsws2016_s_list[i].msg[j]); + dpsws2016_s_list[i].text.append(cbuf); + } + }else if(dpsws2016_s_list[i].type == 10 ){ + for( int j = 0; j < dpsws2016_s_list[i].msg_length; j++){ + sprintf(cbuf, "%03d ", dpsws2016_s_list[i].msg[j]); + dpsws2016_s_list[i].text.append(cbuf); + } + }else if(dpsws2016_s_list[i].type == 16 ){ + for( int j = 0; j < dpsws2016_s_list[i].msg_length; j++){ + sprintf(cbuf, "%02x ", dpsws2016_s_list[i].msg[j]); + dpsws2016_s_list[i].text.append(cbuf); + } + }else{ + for( int j = 0; j < dpsws2016_s_list[i].msg_length; j++){ + sprintf(cbuf, "%02x ", dpsws2016_s_list[i].msg[j]); + dpsws2016_s_list[i].text.append(cbuf); + } + } + buffer_point += dpsws2016_s_list[i].msg_length; + bufferlen -= dpsws2016_s_list[i].msg_length; + }else{ + break; + } + } + } + + size_t length() const override + { + return all_msg_length; + } + + std::string print_str() + { + char cbuf[1024]; + std::string ret_str = ""; + + ret_str.append("\n"); + ret_str.append("Print (DPSWS2016)\n\n"); + sprintf(cbuf, "min_length = %d\n", min_length); + ret_str.append(cbuf); + sprintf(cbuf,"max_length = %d\n\n", max_length); + ret_str.append(cbuf); + + ret_str.append("msg part list\n\n"); + for(int i = 0; i < max_length; i++ ){ + if( dpsws2016_s_list[i].type != 0 ){ + sprintf(cbuf,"msg_fmt_id = %d\n", i); + ret_str.append(cbuf); + ret_str.append("desc = "); + ret_str.append(dpsws2016_s_list[i].desc); + ret_str.append("\n"); + if( dpsws2016_s_list[i].type == 2 ){ + sprintf(cbuf,"type = bit\n"); + }else if( dpsws2016_s_list[i].type == 8 ){ + sprintf(cbuf,"type = oct\n"); + }else if( dpsws2016_s_list[i].type == 10 ){ + sprintf(cbuf,"type = dig\n"); + }else if( dpsws2016_s_list[i].type == 16 ){ + sprintf(cbuf,"type = hex\n"); + }else{ + sprintf(cbuf,"type = %d\n", dpsws2016_s_list[i].type); + } + ret_str.append(cbuf); + sprintf(cbuf,"fmt_length = %d\n", dpsws2016_s_list[i].fmt_length); + ret_str.append(cbuf); + if( dpsws2016_s_list[i].msg_length > 0 ){ + sprintf(cbuf,"msg_length = %d\n", dpsws2016_s_list[i].msg_length); + ret_str.append(cbuf); + ret_str.append("msg(hex) = "); + for(int j = 0; j < dpsws2016_s_list[i].msg_length ; j++ ){ + sprintf(cbuf,"%02x ", dpsws2016_s_list[i].msg[j]); + ret_str.append(cbuf); + } + ret_str.append("\n"); +/* ret_str.append("text = "); + ret_str.append(dpsws2016_s_list[i].text); + ret_str.append("\n"); +*/ } + ret_str.append("\n"); + }else{ + break; + } + } + ret_str.append("\n"); + + if( all_msg_length > 0 ){ + sprintf(cbuf,"all_msg_length = %d\n", all_msg_length); + ret_str.append(cbuf); + ret_str.append("all_msg (hex) = "); + for(int j = 0; j < all_msg_length; j++ ){ + sprintf(cbuf,"%02x ", all_msg[j]); + ret_str.append(cbuf); + } + ret_str.append("\n\n"); + } + return(ret_str); + } + +}; + +class dpsws2016 : public pgen::packet { + private: + void init_headers() override + { + headers = {&DPSWS2016}; + } + + public: + + dpsws2016_header DPSWS2016; + + dpsws2016() + { + clear(); + init_headers(); + } + + dpsws2016(const void* buffer, size_t bufferlen) : dpsws2016() + { + analyze(buffer, bufferlen); + } + + dpsws2016(const dpsws2016& rhs) : dpsws2016() + { + DPSWS2016 = rhs.DPSWS2016; + init_headers(); + } + + void clear() override + { + DPSWS2016.all_msg = NULL; + DPSWS2016.all_msg_length = 0; + + uint8_t mbuf[DPSWS2016.max_length]; + std::string sbuf = ""; + std::string tbuf = ""; + char cbuf[16]; + uint16_t nlen = 0; + + for(int i = 0; i < DPSWS2016.max_length; i++ ){ + DPSWS2016.dpsws2016_s_list[i].type = 0; + + sbuf = ""; + std::getline(std::cin, sbuf); + tbuf = ""; + for( const auto c : sbuf ){ + if( c != '\r' && c != '\n' && c != '\0' ){ + tbuf += c; + } + } + sbuf = std::move(tbuf); + + if( sbuf.length() > 0 ){ + std::string ebuf; + std::stringstream strstr(sbuf); + + std::getline(strstr, ebuf, ':'); + DPSWS2016.dpsws2016_s_list[i].desc = std::string(ebuf); + + DPSWS2016.dpsws2016_s_list[i].type = 0; + std::getline(strstr, ebuf, ':'); + if( ebuf == "bit" ){ + DPSWS2016.dpsws2016_s_list[i].type = 2; + }else if( ebuf == "oct" ){ + DPSWS2016.dpsws2016_s_list[i].type = 8; + }else if( ebuf == "dig" ){ + DPSWS2016.dpsws2016_s_list[i].type = 10; + }else if( ebuf == "hex" ){ + DPSWS2016.dpsws2016_s_list[i].type = 16; + }else{ + sscanf(ebuf.c_str(), "%d", &(DPSWS2016.dpsws2016_s_list[i].type)); + } + + std::getline(strstr, ebuf, ':'); + sscanf(ebuf.c_str(), "%d", &(DPSWS2016.dpsws2016_s_list[i].fmt_length)); + if( DPSWS2016.dpsws2016_s_list[i].fmt_length >= 65535 ){ + DPSWS2016.dpsws2016_s_list[i].fmt_length = 0; + } + + ebuf = ""; + std::getline(strstr, ebuf, ':'); + + DPSWS2016.dpsws2016_s_list[i].text = ""; + DPSWS2016.dpsws2016_s_list[i].msg = NULL; + if( ebuf.length() > 0 ){ + DPSWS2016.dpsws2016_s_list[i].text = std::string(ebuf); + + std::stringstream bstr(ebuf); + std::string bbuf = ""; + nlen = 0; + while( std::getline(bstr, bbuf, ' ') ){ + if( bbuf.length() > 0 ){ + if( DPSWS2016.dpsws2016_s_list[i].fmt_length > 0 ){ + if( nlen >= DPSWS2016.dpsws2016_s_list[i].fmt_length ){ + break; + } + } + if( DPSWS2016.dpsws2016_s_list[i].type == 2 ){ + sscanf(bbuf.c_str(), "%b", &(mbuf[nlen])); + }else if( DPSWS2016.dpsws2016_s_list[i].type == 8 ){ + sscanf(bbuf.c_str(), "%o", &(mbuf[nlen])); + }else if( DPSWS2016.dpsws2016_s_list[i].type == 10 ){ + sscanf(bbuf.c_str(), "%d", &(mbuf[nlen])); + }else if( DPSWS2016.dpsws2016_s_list[i].type == 16 ){ + sscanf(bbuf.c_str(), "%x", &(mbuf[nlen])); + }else{ + sscanf(bbuf.c_str(), "%x", &(mbuf[nlen])); + } + nlen++; + } + bbuf = ""; + } + + DPSWS2016.dpsws2016_s_list[i].msg_length = nlen; + DPSWS2016.dpsws2016_s_list[i].msg = (uint8_t*)malloc(sizeof(uint8_t)*nlen); + DPSWS2016.dpsws2016_s_list[i].msg_length = nlen; + memcpy(DPSWS2016.dpsws2016_s_list[i].msg, mbuf, nlen); + DPSWS2016.all_msg_length += nlen; + nlen = 0; + } + }else{ + break; + } + sbuf = ""; + } + DPSWS2016.all_msg = (uint8_t*)malloc(sizeof(uint8_t)*DPSWS2016.all_msg_length); + nlen = 0; + for(int i = 0; i < DPSWS2016.max_length; i++ ){ + if( DPSWS2016.dpsws2016_s_list[i].type != 0 ){ + memcpy(DPSWS2016.all_msg + nlen, DPSWS2016.dpsws2016_s_list[i].msg, DPSWS2016.dpsws2016_s_list[i].msg_length); + nlen += DPSWS2016.dpsws2016_s_list[i].msg_length; + }else{ + break; + } + } + } + +}; + +bool is_dpsws2016_packet(const void* _buf, size_t len ) +{ + return true; +} +