성엽이
KKIMSSI
성엽이
전체 방문자
오늘
어제
  • 분류 전체보기 (454)
    • :) (2)
    • C프로그래밍이론 (9)
    • C++프로그래밍 (64)
      • STL (1)
    • C# (2)
    • Visual studio 10.0 (9)
    • AT91SAM7S256 (21)
    • 논리회로 (14)
    • AVR2560 (11)
    • TCPIP (16)
    • NetWork (4)
      • Ubuntu Linux (2)
    • Assembly (21)
    • UNIX 프로그래밍 (6)
    • RFID 분석 (1)
    • Win32 API (7)
    • Cortex-M3 (4)
    • Unity (91)
    • Flutter (9)
    • OwnProject (11)
      • It's mine (5)
      • 마인드스톰 실습 (1)
      • 보고서 자료 (2)
      • RPi B+ (2)
    • ETC (25)
      • 상식 (3)
    • MFC (40)
    • PostgeSQL (18)
    • 영상제어 (6)
      • VFW_영상처리 (1)
    • Python (0)
    • Java (30)
      • SpringBoot (2)
      • Javascript (1)
      • JSP (13)
      • Spring (8)
    • Oracle (4)
      • SQL (3)
    • HTML (6)
      • Thymeleaf (1)
      • CSS (1)
      • Bootstrap (3)
    • IDE (1)
      • VS Code (1)
    • Android (2)
    • Privacy Policy (0)
    • MYSQL (2)
      • MariaDB (2)
    • AWS (5)
    • 개인공부 (0)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록
  • 관리자
  • 글쓰기

공지사항

인기 글

태그

  • WINAPI
  • 문자열 나누기
  • Boot Code 분석
  • ARM Reverse Engineering
  • MFC

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
성엽이

KKIMSSI

2013.06.27_Packet_Analyze_
TCPIP

2013.06.27_Packet_Analyze_

2013. 6. 27. 13:53


 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 ( 패킷 아날라이즈 ) 소스 -----


P_CAP.c


------------------------------------------


저작자표시 (새창열림)

'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
    'TCPIP' 카테고리의 다른 글
    • 2013.07.02_sigaction() 함수.
    • 2013.07.01_TCP(Transfer Control Protocol)_by종영이형
    • 2013.06.26_IP헤더구조_
    • 2013.06.24_TCP/IP이론_
    성엽이
    성엽이

    티스토리툴바