= 추가 요구사항 =
- 홈페이지 나온 내용.
- 수신자 주소 등에 따라 원하는 패킷만 분석
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 를 포함해야한다.
WSA prefix 를 가진 함수의 경우 대부분 Winsock 2에서 제공 되기 시작한 것이며, 이 WSAIoctl 역시도 윈속 2에서 지원된다.
네트워크의 3번째 프로젝트를 하기위해서는 SIO_RCVALL 라는 옵션을 설정하여 사용할 줄 알아야한다. 유사한 옵션으로는
SIO_RCVALL_IGMPMCAST, SIO_RCVALL_MCAST 가있다.
자세한 사항은 MSDN 혹은 Network Programming For Microsoft Windows 를 참조하기 바란다.
~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
SIO_RCVALL 을 통해서 NIC를 통해 올라오는 모든 패킷의 캡쳐가 가능하다. NIC를 통해 나가는 패킷을 캡쳐하지 못하는 듯 하다.
3. 참고 ¶
- MFC 각 데이터 타입 크기
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 바이트 변환
inet_addr() :
htons() : host-to-network 바이트 변환
ntohs() : network-to-host 바이트 변환
htonl() : host-to-network 바이트 변환
ntohl() : network-to-host 바이트 변환