Thinking Different




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
 
void error(char *str)
{
    puts(str);
    exit(1);
}
// checksum 검사 함수
USHORT checksum(USHORT *buffer, int size) 
{
    unsigned long cksum=0;
 
    while (size > 1) 
    {
        cksum += *buffer++;
        size -= sizeof(USHORT);
    }
    if (size) 
    {
        cksum += *(UCHAR*)buffer;
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
    return (USHORT)(~cksum);
}
 
// icmp 헤더 구조체 선언
typedef struct icmp_hdr
{
    unsigned char icmp_type;
    unsigned char icmp_code;
    unsigned short icmp_checksum;
    unsigned short icmp_id;
    unsigned short icmp_sequence;
    unsigned short icmp_timestamp;
}ICMP_HDR, *PICMP_HDR, FAR *LPICMP_HDR;
 
int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsaData;
    SOCKET s;
    SOCKADDR_STORAGE dest;
    ICMP_HDR *icmp = NULL;
    char buf[sizeof(ICMP_HDR) + 32];
 
    icmp = (ICMP_HDR*)buf;
    icmp->icmp_type = 8;
    icmp->icmp_code = 0;
    icmp->icmp_id = (unsigned short)GetCurrentProcessId();
    icmp->icmp_checksum = 0;
    icmp->icmp_sequence = 0;
    icmp->icmp_timestamp = (unsigned short)GetTickCount();
    memset(&buf[sizeof(ICMP_HDR)], '@', 32);
    icmp->icmp_checksum = checksum((USHORT*)buf, sizeof(ICMP_HDR)+32);
    
    if(WSAStartup(WINSOCK_VERSION, &wsaData) != 0)
        error("WSAStartup Error!");
 
    s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if(s == INVALID_SOCKET)
        error("socket() Error!");
 
    ((SOCKADDR_IN*)&dest)->sin_family = AF_INET;
    ((SOCKADDR_IN*)&dest)->sin_port = htons(0);     // ICMP에서 포트는 무시한다
    ((SOCKADDR_IN*)&dest)->sin_addr.S_un.S_addr = inet_addr("Target IP 주소");
 
    for(int i = 0; i<10; i++)       // ping 10번 전송, 이때 wireshark를 확인하면 icmp 패킷이 날아가는것을 확인 할 수 있다.
    {
        sendto(s, buf, sizeof(ICMP_HDR)+32, 0, (SOCKADDR*)&dest, sizeof(dest));
        Sleep(1000);
    }
    
    closesocket(s);
    WSACleanup();
 
    return 0;
}


아래는 와이어샤크로 위 소스코드를 실행하여 icmp를 날렸을때 패킷을 캡쳐한 내용이다... 10개의 패킷을 날렸으며 각 세부부분은 아래와 같다...