Packet_Analyze |
|
|
#include<stdio.h>
#include<pcap/pcap.h> #include<netinet/ether.h> #include<netinet/ip.h> void HexaView(unsigned char *ucP, unsigned int isize); int L2_IP(void *); unsigned short smart_cksum(void *us_data, unsigned int ui_Len); int main() { char errbuf[PCAP_ERRBUF_SIZE]; char *cpNIC_Name; pcap_t *st_Des; unsigned char uc_data[1500]; //u_char *const struct pcap_pkthdr st_info; // 패킷을 가져왔을때의 정보를 저장 : 패킷 헤더. struct ether_header *stEth; // 헤더 구조체 포인터. // 네트워크 카드를 찾는 함수. pcap 함수. // 장치를 찾다가 에러가 생기면 버퍼에 에러메세지를 저장을 해준다. cpNIC_Name = pcap_lookupdev(errbuf); if( 0 == cpNIC_Name ) { printf("Error : %s\n", errbuf); return 0; } printf("==========================================================================\n"); printf("==============================Packet Analyze==============================\n"); printf("==========================================================================\n"); printf("== NIC Name : [%s]\n",cpNIC_Name); // pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) // int snaplen > 1500 MTU(Max Transmission Unit:최대로 전송할수 있는 유닛 단위), // Ethernet의 최대단위 1500 byte // int promisc '난잡한' , 1일때 어떠한 패킷이든 다 건져옴. // 0일때 promisc를 OFF 시키고 내컴퓨터에서 건져옴. // pcap_open_live 함수는 블로킹함수로 그 대기시간을 적는다. 단위는 ms (ex:1분 = 60000) // errbuf 에러버퍼 st_Des = pcap_open_live(cpNIC_Name, 1500, 1, 0, errbuf); if( 0 == st_Des ) { printf("Error : %s\n", errbuf); return 0; } // 메모리 카피 : 1500byte만큼의 크기를 pcap으로 건져 온 데이터를 uc_data 에 넣어주겠다. memcpy(uc_data, pcap_next(st_Des, &st_info), sizeof(uc_data)); stEth =(struct ether_header *)uc_data; // 구조체를 가르킴. printf("== Source -> Destination\n"); /* source ether addr */ printf("== MAC Address : [%02X:%02X:%02X:%02X:%02X:%02X]->", stEth->ether_shost[0], stEth->ether_shost[1], stEth->ether_shost[2], stEth->ether_shost[3], stEth->ether_shost[4], stEth->ether_shost[5]); /* destination eth addr */ printf("[%02X:%02X:%02X:%02X:%02X:%02X]\n", stEth->ether_dhost[0], stEth->ether_dhost[1], stEth->ether_dhost[2], stEth->ether_dhost[3], stEth->ether_dhost[4], stEth->ether_dhost[5]); //printf("----- %s\n",ether_ntoa( (struct ether_addr *)stEth->ether_shost) ); //구조체를 직접 찝어줘서 ether_host (LAN 장치번호)를 알수있다. /* packet type ID field */ printf("== Packet type : "); switch(ntohs(stEth->ether_type)) { case ETHERTYPE_PUP: printf("Xerox PUP\n"); break; case ETHERTYPE_IP: printf("IP\n"); L2_IP(uc_data+14); // IP Header 의 위치. break; case ETHERTYPE_ARP: printf("Address resolution\n"); break; case ETHERTYPE_REVARP: printf("Revers ARP\n"); break; default : printf("Unknown %04X\n",ntohs(stEth->ether_type)); break; }
HexaView(uc_data, 64); pcap_close(st_Des); return 0; } // CRC check sum이라는 이론을 함수로 만들어놓음._ 데이타의 손상이 있는지를 찾아주는 함수. unsigned short smart_cksum(void *vp_data, unsigned int ui_Len) { unsigned long ul_sum; for(ul_sum =0; ui_Len > 0; ui_Len=ui_Len-2) { ul_sum = ul_sum + *((unsigned short *)vp_data); vp_data = (unsigned short *)vp_data + 1; } ul_sum = (ul_sum>>16) + (ul_sum&0xffff); ul_sum = ul_sum + (ul_sum>>16); return ~ul_sum; } // Layer 2 의 IP 안에 구조파악. int L2_IP(void *vp) { struct ip *st_IP = vp; // IP 헤더. unsigned short us_checksum; printf("== IP Version : IPv%d\n", (st_IP->ip_v)); printf("== IP Header size : %d bytes\n", (st_IP->ip_hl)*4); // Type of Service를 출력. printf("== Type of Service : LOWDELAY [%s]\n", ( 0 == ((st_IP->ip_tos) & IPTOS_LOWDELAY) ? "NO" : "YES" ) ); printf("== : Throughput [%s]\n", ( 0 == ((st_IP->ip_tos) & IPTOS_THROUGHPUT) ? "NO" : "YES" ) ); printf("== : Reliability [%s]\n", ( 0 == ((st_IP->ip_tos) & IPTOS_RELIABILITY) ? "NO" : "YES" ) ); printf("== : Low Cost [%s]\n", ( 0 == ((st_IP->ip_tos) & IPTOS_LOWCOST) ? "NO" : "YES" ) ); printf("== : Min Cost [%s]\n", ( 0 == ((st_IP->ip_tos) & IPTOS_MINCOST) ? "NO" : "YES" ) ); // Total Length printf("== Total Length : %d bytes\n", ntohs(st_IP->ip_len)); printf("== Identification : %d\n", ntohs(st_IP->ip_id)); // Flag and Fragment printf("== Flag : More Fragment [%s]\n", ( 0 == ((st_IP->ip_off) & IP_MF) ? "NO" : "YES" ) ); printf("== : Don't Fragment [%s]\n", ( 0 == ((st_IP->ip_off) & IP_DF) ? "NO" : "YES" ) ); printf("== Fragmentation OFFSET : %d\n", ntohs(st_IP->ip_off) & IP_OFFMASK ); // Time to live printf("== Time to live : %d sec\n", st_IP->ip_ttl); printf("== IP Protocol : "); switch(st_IP->ip_p) { case IPPROTO_IP : printf("Dummy protocol for TCP\n"); break; case IPPROTO_ICMP : printf("Internet Control Message Protocol\n"); break; case IPPROTO_IGMP : printf("Internet Group Management Protocol\n"); break; case IPPROTO_IPIP : printf("IPIP tunnels (older KA9Q tunnels use 94)\n"); break; case IPPROTO_TCP : printf("Transmission Control Protocol\n"); break; case IPPROTO_EGP : printf("Exterior Gateway Protocol\n"); break; case IPPROTO_PUP : printf("PUP protocol\n"); break; case IPPROTO_UDP : printf("User Datagram Protocol\n"); break; case IPPROTO_IDP : printf("XNS IDP protocol\n"); break; case IPPROTO_TP : printf("SO Transport Protocol Class\n"); break; case IPPROTO_IPV6 : printf("IPv6 header\n"); break; case IPPROTO_ROUTING : printf("IPv6 routing header\n"); break; case IPPROTO_FRAGMENT : printf("IPv6 fragmentation header\n"); break; default : break; } //printf("== IP Header : %04X\n", st_IP->ip_sum); // 실제 들어가는 checksum. //st_IP->ip_sum = 0X0000; // 2byte의 데이터 비우고 받기위해서 0x0000을 넣어줌. //printf("== Smart cksum : %04X\n", smart_cksum(st_IP,20)); // 함수로 맞춰본. us_checksum = st_IP->ip_sum; st_IP->ip_sum = 0x0000; printf("== CheckSum Check : %s\n", ( us_checksum == smart_cksum(st_IP,(st_IP->ip_hl)*4) ) ? "OK" : "Failed" ); // IP Address ( Source IP Address -> Destination IP Address ) // inet_ntoa 함수는 4byte의 정수를 네트워크에 문자열로 바꿔 // Static 변수로 버퍼에 저장해주므로, 따로 불러서 덮어써야만 값이 바껴서 제대로 나옴. printf("== IP Address : [%s]->",inet_ntoa(st_IP->ip_src)); printf("[%s]\n",inet_ntoa(st_IP->ip_dst)); //printf("== IP Address : [%s]->[%s]\n",inet_ntoa(st_IP->ip_src),inet_ntoa(st_IP->ip_dst));
return 0; } void HexaView(unsigned char *ucP, unsigned int isize) { int iCnt; int iloop; printf("----------------------------------------" "----------------------------------\n"); printf("Address \t\t\tHexa\t\t\t ASCII\n"); printf("\t "); for(iCnt=0 ; iCnt <= 15 ; iCnt++) { printf("%02X ", iCnt); } putchar('\n'); printf("----------------------------------------" "----------------------------------\n"); if( 0 == isize%16 ) { isize = isize / 16; } else { isize = (isize/16) + 1; } for(iloop=0; iloop < isize; iloop++) { printf("%08X ", ucP); for( iCnt=0 ; iCnt <= 15 ; iCnt++) { printf("%02X ", *(ucP+iCnt)); } for( iCnt=0 ; iCnt <= 15 ; iCnt++ ) { if(0 == *(ucP+iCnt)) { printf("."); } else if( 32 > *(ucP+iCnt)) { printf("."); } else if( 127 < *(ucP+iCnt)) { printf("."); } else { printf("%c", *(ucP+iCnt)); } } putchar('\n'); ucP = ucP + 16; } } |
------ P_CAP ( 패킷 아날라이즈 ) 소스 -----
------------------------------------------
'TCPIP' 카테고리의 다른 글
2013.07.02_sigaction() 함수. (0) | 2013.07.02 |
---|---|
2013.07.01_TCP(Transfer Control Protocol)_by종영이형 (0) | 2013.07.01 |
2013.06.26_IP헤더구조_ (0) | 2013.06.26 |
2013.06.24_TCP/IP이론_ (0) | 2013.06.24 |
2013.06.19_select()활용_Client소켓늘려보기_ (0) | 2013.06.20 |