U E D R , A S I H C RSS

Computer Network Class/Report2006/Packet Analyzer


= 추가 요구사항 =
  • 홈페지 나온 내용.
패킷분석기는 다음 사항을 최소한 구현하여야 함.

1. 선택적 capture
- 수신자 주소 등에 따라 원하는 패킷만 분석
2. IP 헤더의 graphical한 표시
- 리스트에서 하나의 패킷을 선택하면 IP 헤더를 분석해서 보여주는 기능
3. ethereal의 기능 중 1개 또는 새로운 기능을 한가지 구현
- 예, TCP connection 설정과정 분석

상의 기능 동작하는 것을 반드시 보여야 함.
- 런, -_-; 할게 늘어버렸넹
네트워크 숙제를 하란 건지 GUI코딩을 하란 건지...
- ㅋㅋ 그러게 잘짜야지... ㅋㅋㅋ - eternalbleu

1. WSAIoctl

WSAIoctl 은 소켓나 트랜스포트 계층 프로토콜, 통신 시스템의 구성과 관련된 사항을 설정하거나 설정값을 가져오기위해서 만들어졌다.
WSA prefix 를 가진 함수의 경우 대부분 Winsock 2에서 제공 되기 시작한 것며, WSAIoctl 역시도 윈속 2에서 지원된다.
네트워크의 3번째 프로젝트를 하기위해서는 SIO_RCVALL 라는 옵션을 설정하여 사용할 줄 알아야한다. 유사한 옵션으로는
SIO_RCVALL_IGMPMCAST, SIO_RCVALL_MCAST 가있다.
자세한 사항은 MSDN 혹은 Network Programming For Microsoft Windows 를 참조하기 바란다.

※ 윈도우 소켓 프로그래밍을 위해서는 윈속 라브러리를 같 linking 해야하며, WSActrl 을 사용하기 위해서는 winsock2 라브러리인 ws2_32.lib 를 포함해야한다.
~cpp
#include <mstcpip.h>
※ 'SIO_RCVALL' : undeclared identifier 에러가 뜰 경우에 아래 코드를 추가 한다.
~cpp
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

2. Sample Code

~cpp
int _cdecl main(int argc, char **argv)
{
    SOCKET        s;
    WSADATA       wsd;
    SOCKADDR_IN   if0;
    int           ret,
                  count;
    unsigned int  optval;
    DWORD         dwBytesRet,
                  dwFlags,
                  nproc;
    char          rcvbuf[MAX_IP_SIZE];
    WSABUF        wbuf;

    // Load Winsock
    //
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("WSAStartup() failed: %d\n", GetLastError());
        return -1;
    }
    // Parse the command line
    //
    ValidateArgs(argc, argv);
    if (bFilter)
    {
        printf("Source Port: %d\n", usSourcePort);
        printf("Dest   Port: %d\n", usDestPort);
    }
    // Create a raw socket for receiving IP datagrams
    //
    s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (s == INVALID_SOCKET)
    {
        printf("WSASocket() failed: %d\n", WSAGetLastError());
        return -1;
    }
    // Get an interface to read IP packets on
    //
    if (GetInterface(s, &if0, dwInterface) != 0)
    {
        printf("Unable to obtain an interface\n");
        return -1;
    }
    printf("Binding to IF: %s\n", inet_ntoa(if0.sin_addr));
    //
    // This socket MUST be bound before calling the ioctl
    //
    if0.sin_family = AF_INET;
    if0.sin_port = htons(0);

    if (bind(s, (SOCKADDR *)&if0, sizeof(if0)) == SOCKET_ERROR)
    {
        printf("bind() failed: %d\n", WSAGetLastError());
        return -1;
    }
    //
    // Set the SIO_RCVALLxxx ioctl
    //
    optval = 1;
    if (WSAIoctl(s, SIO_RCVALL, &optval, sizeof(optval),
            NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR)
    {
        printf("WSAIotcl(%d) failed; %d\n", dwIoControlCode,
            WSAGetLastError());
        return -1;
    }
    // Start receiving IP datagrams until interrupted
    // 
    count = 0;
    while (1)
    {
        wbuf.len = MAX_IP_SIZE;
        wbuf.buf = rcvbuf;
        dwFlags  = 0;

        ret = WSARecv(s, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
        if (ret == SOCKET_ERROR)
        {
            printf("WSARecv() failed: %d\n", WSAGetLastError());
            return -1;
        }
        // Decode the IP header
        //
    }
    // Cleanup
    //
    closesocket(s);
    WSACleanup();
    return 0;
}
상기와 같 기존의 서버 프로그램과 다른 점은 별로 없다. (Listen과 accept가 없네요. WSAIoctrl에서 다 처리하는건지...) 단지 소켓을 ioctrl 로 조정해서 ip 수준에서 올라오는 패킷을 기존과 다르게 처리할 뿐다.
SIO_RCVALL 을 통해서 NIC를 통해 올라오는 모든 패킷의 캡쳐가 가능하다. NIC를 통해 나가는 패킷을 캡쳐하지 못하는 듯 하다.

아마도 listen, accept 가 패킷 필터링을 하는 것으로 보는데 dst 상관없 무조겁 application 까지 올라오니깐 필요없는 것 아닐까? 그런 생각하고 있음. -_- - eternalbleu

3. 참고

  • MFC 각 데터 타입 크기
Type Size
bool 1 byte
char, unsigned char, signed char 1 byte
short, unsigned short 2 bytes
int, unsigned int 4 bytes
__intn 1, 2, 4, or 8 bytes depending on the value of n. __intn is Microsoft-specific.
long, unsigned long 4 bytes
float 4 bytes
double 8 bytes
long double1 8 bytes
long long Equivalent to __int64.

4. 터 변환

const char* szIpAddr to DWORD ipvalue
inet_addr() :

Unsigned short interger 변환 (2바트 체계)
htons() : host-to-network 바트 변환
ntohs() : network-to-host 바트 변환

Unsigned long interger 변환 (4바트 체계)
htonl() : host-to-network 바트 변환
ntohl() : network-to-host 바트 변환

5. 추천 개발 과정

(1) 콘솔로 캡쳐기, 필터, 컨테너 클래스를 구성한다.
필터기는 가능하면 propery 를 설정해서 동작하도록 구성한다.
(2) MFC, VB 등을 용해서 GUI 부분을 짠다. (핵심은 리포트 모듈 작성)
컨테너와 리스트 컨트롤을 옵저버 패턴으로 연결할 것을 염두에 둔다.
캡쳐기의 동작으로 인한 UI 딜레 현상을 막기위해서 쓰레드를 용.
(3) 만들어진 front-end, back-end 를 통합한다.
리포트 모듈을 리스트 컨트롤과 옵저버 패턴 혹은 벤트 드리븐으로 연동

6. postscript

일단 캡쳐기만 완성하니 그야말로 일사천리로 풀리는데 -_-; 귀차니즘 발동하는구만.. 쿨럭 - eternalbleu
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:00
Processing time 0.0206 sec