▶ IP헤더구조. |
(1) Version: 인터넷 프로토콜 버전으로 IPv4 일 경우 4, IPv6 일 경우 6 (ex: IPLv4 -> Lv4이기때문에 이진수로 0100 )
(2) Header Length: IP 프로토콜 헤더의 길이 ( 4bit ) ( 20byte(4byte 짜리 5개 이므로) 5개를 이진수로 0101 )
그래서 보통 4 5 로 나옴.
(3) Type Of Service : 교환하는 데이터의 종류에 따라 지연 통신효율, 신뢰성의 우선순위를 지정할 수 있음
데이터그램에기대되는 QoS(Quality of Service)를 지시하는 8비트 코드
우선권(Precedence)필드(3비트), TOS(Type-Of-Service) 필드(4 비트), 예약 필드(1 비트)
우선권 필드는 패킷의우선순위 정의
TOS 필드는 최소 지연, 최대 처리량, 최대 신뢰성, 최소 비용을 나타내는 필드, 4비트 중 한비트만1
(4) Total Length : IP의 프로토콜 헤더에 계속되는 데이터도 포함한 IP 패킷의전체길이 (이더넷MTU 1500 byte)
옥텟으로나타낸 헤더와 데이터 필드를 포함한 전체 데이터그램의길이
(5) Identification : 상위 계층으로부터 각 IP데이터그램을분별하기 위한 식별번호 (패킷이단편화 됐을때사용하는 부분)
(6) Flags : IP데이터그램이분할(Fragment)에 관한 정보를 나타냄
- 첫번째비트 : 사용안함, 두 번째 비트 : Do not fragment, 세 번째 비트 : More fragment
(7) Fragment Offset : 각 프래그먼트의원 데이터에 있어서의 위치를 바이트 단위로 나타냄
(8) TTL : Time To Live의 약자로 통과가능한 라우터의남은 수를 나타냄, 라우터를경유할 때마다 이 값이 하나씩 줄어든다.
데이터그램이폐기되기 전 인터넷에 얼마동안존속할 수 있는지를 지시하는 값.
각 라우터에의해 감소된다. (값이 0이 되면 데이터그램은 폐기)
(9) Protocol Type : 데이터에 포함되는 상위 프로토콜 (TCP:6, UDP:17)의 종류를 나타냄
데이터그램과관련된 상위 계층 프로토콜을 식별
- 1 = ICMP 메시지를 운반
- 6 = TCP 세그먼트를 운반
- 17 = UDP 사용자 데이터그램을운반
(10) Header Checksum : IP 프로토콜 헤더 자체의 내용이 바르게 교환되고 있는가를 점검
전송 도중 헤더가 손상되지 않았음을 보장하기 위하여 수신된 패킷내IP 헤더 자체를 검사하는데 사용.
(11) Source IP Address : 발신지의 IP Address
(12) Destination IP Address : 수신지의 IP Address
(13) Option: 경로배정 및 보안 등과 같은 제어 기능에 사용되는 40 bytes 까지의 부가 정보
▶ P_CAP : Packet 을 건져서 정보를 알수 있는 함수. |
#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 *); 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; } // Layer 2 의 IP 안에 구조파악. int L2_IP(void *vp) { struct ip *st_IP = vp; // IP 헤더.
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 : %04X\n", ntohs(st_IP->ip_id)); printf("== Flag : More Fragment [%s]\n", ( 0 == ((st_IP->ip_off) & IP_MF) ? "NO" : "YES" ) ); printf("== Flag : Don't Fragment [%s]\n", ( 0 == ((st_IP->ip_off) & IP_DF) ? "NO" : "YES" ) ); 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; } } |
: 출력 화면 : vi ~/.bashrc : IP 구조체
: ip_v = IP Version -> 4bit + : ip_hl = Header Length -> 4bit + : ip_tos = Type of Service -> 8bit + : ip_len = Total Length -> 16bit = 32bit = 4byte 를 가짐. : ip_id = Identification -> 16bit : ip_off = Flag -> 3bit |
'TCPIP' 카테고리의 다른 글
2013.07.01_TCP(Transfer Control Protocol)_by종영이형 (0) | 2013.07.01 |
---|---|
2013.06.27_Packet_Analyze_ (0) | 2013.06.27 |
2013.06.24_TCP/IP이론_ (0) | 2013.06.24 |
2013.06.19_select()활용_Client소켓늘려보기_ (0) | 2013.06.20 |
2013.06.18_select()활용 (0) | 2013.06.18 |