간단히 말해서, 전선 위에 무언가를 얻기 위해 매우 뼈없는 UDP SKB를 만들려고합니다. 그 시나리오는 다음과 같습니다 :출구 장치 용 커널 sk_buff 빌드 리눅스 커널
로드 중의 커널 모듈은 /net/ipv4/udp.c에있는 표준 udp_sendmsg 함수의 메모리 위치를 덮어 씁니다. 여기에서 필자는 단순히 케이블에 연결할 수있는 지점까지 skb를 만들고 싶습니다. 일반적으로 udp_sendmsg는 약간의 UDP 부기를 수행하고 UDP 헤더를 집어 넣은 다음 라우팅, L3/L2 헤더 등을 보내기 위해 IP 계층으로 보냅니다. 기본적으로 sendmsg 기능으로 일부 기능을 가져옵니다. 이 때, 나는 단지 SKB 할당하고 있습니다 :
struct udphdr *uh;
skb->transport_header = skb_push(skb, sizeof(struct udphdr));
uh = udp_hdr(skb);
uh->source = 5555;
uh->dest = dport;
uh->len = 18;
uh->check = 0;
와 ip_hdr (단 기초를 잘 작성 : 다음
skb = alloc_skb(1500, GFP_KERNEL);
//skb has 1500 bytes of tail room only
skb_reserve(skb, 500);
//now has head and tail but no data space
data = skb_put(skb, 500);
//now we have an skb with 500 head, 500 data sec, 500 tail
그리고 (일부 경로 테이블 seteup 후) 나는 udp_hdr를 추가하는 것을 시도하고있다) :
struct iphdr *iph;
skb->network_header = skb_push(skb, sizeof(struct iphdr));
iph = ip_hdr(skb);
iph->version = 4;
iph->ihl = 5;
iph->tos = inet->tos;
iph->tot_len = htons(skb->len);
iph->protocol = IPPROTO_UDP;
iph->saddr = saddr;
iph->daddr = daddr;
skb->dst = dst_clone(&rt->u.dst);
참고 : 나는 this page에서이 물건의 대부분을 가지고 있지만, 네트워크와 전송 헤더가 노동 조합을 어디 그들은 이전의 커널 (사전 2.6.24)을 사용하고 NH 및 시간 각각의 호출 어. 새로운 방법은 skb-> transport_header/skb-> network_header를 사용하고 이러한 도우미 기능을 사용하는 것입니다. 그러나 udp_sendmsg를 호출하려고 할 때 커널이 오작동하기 때문에 분명히 뭔가를하고 있습니다.
참고 : 이것은 oops없이 실행되었습니다.
skb->transport_header = skb_push(skb, sizeof(struct udphdr));
내가 사용 : 대신 때 와이어에 쓰레기를 버려.
skb_reset_transport_header(skb);
(및 network_header 상당하지만 위의 링크를 읽고 리눅스의 리셋 기능에 대한 소스보고 후 /sk_buff.h, 보지 못했습니다. 그것이 내가 원하는 것을하고있는 것처럼.
위 정의 문에서 정의되지 않은 변수는 내가 전체 함수를 포함하지 않았기 때문에 간단합니다.
나는이 질문이 매우 특정한 영역에 들어갈 수도 있다는 것을 알고 있지만, 새로운 skb 구조의 올바른 사용에 대한 지침은 매우 도움이 될 것입니다. 내 친구 google이 꽤 건조 해지고 있습니다.
아차 전화 추적 :
[<ffffffff813dbf98>] oops_end+0xb9/0xc1 [<ffffffff81030e21>] no_context+0x1f6/0x205 [<ffffffff81030fd3>] __bad_area_nosemaphore+0x1a3/0x1c9 [<ffffffff8101184e>] ? apic_timer_interrupt+0xe/0x20 [<ffffffff8103100c>] bad_area_nosemaphore+0x13/0x15 [<ffffffff813dd30a>] do_page_fault+0x125/0x222 [<ffffffff813db485>] page_fault+0x25/0x30 [<ffffffffa010924f>] ? udp_sendmsg_offload+0x1e3/0x250 [testmodule] [<ffffffffa010922e>] ? udp_sendmsg_offload+0x1c2/0x250 [testmodule] [<ffffffff81390a00>] inet_sendmsg+0x54/0x5d [<ffffffff8132f142>] __sock_sendmsg+0x61/0x6c [<ffffffff8132f8b9>] sock_sendmsg+0xcc/0xe5
가 아차 우리에게 보여주십시오. – ninjalj
oops를 반영하는 편집 된 게시물 –