본문 바로가기
TCP/IP

Linux: SOCK_PARCKET

by 상레알 2009. 12. 3.

리눅스 환경에서 데이터링크계층으로부터 패킷을 받을려면  SOCK_PACKET이라는 종류의 소켓을 만들어야 한다. 이를 위해서 우선 관리자의 권한을 가져야 하고, socket의 세번째 인수가 이더넷 프레임 종류를 나타내는 0이 아닌 값이어야 한다. 예를 들면 데이터링크로부터 패킷을 받기 위해서 다음과 같이 써야 한다.

fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));

이는 데이터링크가 받는 모든 프로토콜의 프레임을 반환할 것이다. 만일 IPv4 프레임만을 원한다면, 호출은 다음과 같다.

fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP));

마지막 인수로서의 다른 상수는 ETH_P_ARP나 ETH_P_IPV6 등이 있다. ETH_P_ALL의 프로토콜을 지시한 것은 데이터링크에게 어떤 종류의 프레임을 데이터링크가 받은 프레임을 위한 소켓이 전달할지를 말해주는 것이다. 만일 데이터 링크가 난잡상태를 지원한다면 (예, 이더넷) 기기도 난잡 상태에 들어가야한다. 이것은 표시자를 덧붙일 SIOCGIFFLAGS의 ioctl과 IFF_PROMISC 표시자를 정하고 표시자를 SIOCSIFFLAGS에 저장하는 것으로 된다.
 이 리눅스 형태를 BPF나 DLPI와 비교하면 몇 가지 차이가 있다.

1. 리눅스 형태는 커널 버퍼링이나 커널 필터링을 제공하지 않는다. 일반 소켓 수신 버퍼는 됐지만 여러 개의 프레임이 동시에 버퍼링되지 못하고 응요에 한번의 읽기가 된다. 이는 커널로 부터 응용까지의 잠재적으로 막대한 양의 데이터를 복사하는 데서 생기는 비용을 증가시킨다.

2. 리눅스 형태는 기기에 의한 필터링을 제공하지 않는다. 만일 ETH_P_IP가 socket을 호출할때 지정되었다면 모든 기기(이더넷, PPP 링크, SLIP 링크, 그리고 루프백 기기)로 부터의 모든 IPv4 패킷들은 소켓으로부터 전달된다. 일반적인 소켓 주소 구조체는 recvfrom과sa_data 구성된 장치 이름 (e.g., eth0)을 반환한다. 그러면 응용은 자신이 관심이 없은?! 장치에 관한 데이터를 버린다.  이것은 문제가 된다 너무 만은 데이터들이 응용으로 반환 될때는 이러한 문제는 고속 네트워크를 모니터링할때 볼수 있다.

번역 이..ㅠ_ㅠ 제대로인거 맞음?!
- Unix Networking Programming :Networking API sockets and XTI

'TCP/IP' 카테고리의 다른 글

Nagle 알고리즘  (0) 2011.05.02
getsockopt() , setopt () 함수  (0) 2011.05.02
ioctl : 장치 제어 함수  (0) 2011.04.29
소켓 함수 및 헤더들  (0) 2011.02.07
sendto()  (0) 2010.03.28
SOCKADDR_IN 구조체  (0) 2010.03.28
SOCKET() 함수  (0) 2010.03.25
ICMP 프로토콜  (0) 2009.11.16
인터넷 소켓 활용  (0) 2009.08.31
TCP/IP 열혈 강의  (0) 2009.08.12