[질문] ptype_all 구조체에서 socket packet 의 pkt_type 바꾸
datalink 계층의 모든 패킷을 ip layer(ip_rcv()) 로 끌어 올리고
싶습니다. 그래서 ip_input.c 파일의
if(skb->pkt_type == PACKET_OTHERHOST)
drop;
이 부분을 피하고자 아래와 같은 모듈을 ptype_all 리스트에
새로운 packet_type{} 데이타 구조를 등록 시켜서 skb->pkt_type 을
바꾸고자 합니다.
그런데 해당 모듈에서는 일시적으로 바뀐 것 처럼 보이나, 실제로 ip_rcv()
function 에서 찍어 보면 바뀌어 있지 않습니다. 그래서 결국 drop 되어 버리구요.
pkt_type 는 sk_buff 구조체에서 unsigned char 형으로 선언 되어 있습니다.
아래는 해당 모듈에서 type 을 바꿔주는 부분입니다.
int change_func(struct sk_buff *skb, struct net_device *dv,
struct packet_type *pt)
{
if(skb->pkt_type == PACKET_OTHERHOST)
skb->pkt_type = PACKET_HOST;
printk("%d\n", skb->pkt_type);
}
혹시나 해서 mac address까지 memcpy function 을 써서 copy 를
해 줘도 실제 ip_rcv() function 에서 받는 패킷의 pkt_type 이 변하질
않습니다.(실제 ip_rcv 에서 printk 문으로찍어 봤습니다.)
혹시 더 필요한 내용이나, 빠트린 내용이 있을까요?
코딩상에 무슨 문제가 있는 것이지....... 조언 부탁드립니다.
접근 방법에 문제가 있지 않을까요?
예를 들어, ethernet 이라는 ethernet 프레임의 protocol 필드를 보고, ip_rcv() 함수를 호출할 텐데요. 어떻게 다른 모듈로 보내게 하시는 건가요?
기본적으로 datalink 는 자신의 MAC address 또는 자신이 해당되는 MAC broadcast 주소 또는 MAC multicast address 만을 인식합니다.
따라서, 일반적인 경우라면,
위 코드에서 drop으로 점프할 일도 없습니다. 위 코드는 단지 인터페이스를 promiscuous mode 로 설정해 놓았을 경우에 인터페이스에서 자신의 MAC address와는 상관 없는 패킷을 받는 경우를 가정한 것입니다.
대략 플로우를 정리해 보자면,
1. 인터페이스를 promiscuous mode 로 설정한다.
2. 해당 인터페이스는 자신과 상관 없는 MAC 주소를 향하는 프레임도 받아들인다.
3. 받아들인 모든 프레임 중에서 protocol 필드가 ETH_P_IP (0x0800) 인 프레임들은 ip_rcv 로 넘겨 진다.
4. IP 계층에서는 자신과 무관한 IP일 경우는 이를 버려야 한다. (설령 link 계층에서 넘겨줬더라도 말이다.)
위 과정의 어느 부분을 고치셔서 새로운 모듈로 넘어 가도록 했다는 것인지 이해가 안 갑니다.
또한, link layer의 모든 패킷을 ip layer 로 끌어 오면 절대 정상적으로 동작할 것이라고 보이지 않습니다만.. 꼭 커널을 고쳐서 그렇게 처리해야 하는 이유가 있나요?
[quote]위 코드에서 drop으로 점프할 일도 없습니다. 위 코드
네 맞습니다. promiscuous mode 로 돌린다는 가정하에서 였습니다. promiscuous mode
가 아니라면, 아예, 다른 외부의 패킷이 올라 오지도 않겠죠!. 근데 점프할일이 일반
사용자에게도 가끔은 있을 것 같습니다. 예를 들어 tcpdump 등으로 datalink의
패킷을 보고 있는 동안은(promis 모드로 바뀌므로) goto drop; 로 점프할 일이 생기겠죠!
제가 하고자 하는 것은 위의 flow 중에서 4번을 피하고자 함입니다. 넘어온 패킷이
정상적인 ip layer 의 수순을 따르도록 할려고 하지는 않습니다. 아마도 ip layer
를 새로 구성해야 겠지요!
안 타깝게도 꼭 그렇게 해야만 합니다. 이유는 말씀 드리기가 곤란한 상황이라서요......
방금 전 원인을 알았습니다. 제가 등록한 packet handler 로 오는 패킷의 헤더는
clone 된 것이었습니다. 당연히 원래의 패킷은 변화가 없으니 drop 되는 것이
였습니다.
커널.. 어렵군요!
답변 감사드립니다. 좋은 하루 되십시오.
댓글 달기