對於一個項目,我試圖從Linux內核空間發送UDP數據包。我目前正在將我的代碼「硬編碼」到內核中(我不理解它是最好的/最新的方式),但我試圖讓一個簡單的測試工作(發送「TEST」)。應該指出,我是內核黑客的新手 - 我不是那種在許多原理和技術上找到的東西!在Linux內核中發送UDP數據包
每當我的代碼運行系統掛起,我必須重新啓動 - 沒有鼠標/鍵盤響應和滾動和大寫鎖定鍵燈閃爍在一起 - 我不知道這是什麼意思,但我假設它是內核恐慌?
repeat_send代碼對於此測試代碼是不必要的,但是當它工作時,我想發送可能需要多個'send'的大消息 - 我不確定如果可能是我的問題的原因?
N.B.這段代碼被插入到linux-source/net/core/origin的neighbour.c中,因此使用了NEIGH_PRINTK1,它只是一個宏包裝printk。
我真的把我的頭撞在這裏的磚牆上,我找不到任何明顯的東西,任何人都可以指向正確的方向(或者發現那個盲目的明顯錯誤!)?
這是我到目前爲止有:
void mymethod()
{
struct socket sock;
struct sockaddr_in addr_in;
int ret_val;
unsigned short port = htons(2048);
unsigned int host = in_aton("192.168.1.254");
unsigned int length = 5;
char *buf = "TEST\0";
struct msghdr msg;
struct iovec iov;
int len = 0, written = 0, left = length;
mm_segment_t oldmm;
NEIGH_PRINTK1("forwarding sk_buff at: %p.\n", skb);
if ((ret_val = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
NEIGH_PRINTK1("Error during creation of socket; terminating. code: %d\n", ret_val);
return;
}
memset(&addr_in, 0, sizeof(struct sockaddr_in));
addr_in.sin_family=AF_INET;
addr_in.sin_port = port;
addr_in.sin_addr.s_addr = host;
if((ret_val = sock.ops->bind(&sock, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in))) < 0) {
NEIGH_PRINTK1("Error trying to bind socket. code: %d\n", ret_val);
goto close;
}
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_flags = 0;
msg.msg_name = &addr_in;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
repeat_send:
msg.msg_iov->iov_len = left;
msg.msg_iov->iov_base = (char *)buf + written;
oldmm = get_fs();
set_fs(KERNEL_DS);
len = sock_sendmsg(&sock, &msg, left);
set_fs(oldmm);
if (len == -ERESTARTSYS)
goto repeat_send;
if (len > 0) {
written += len;
left -= len;
if (left)
goto repeat_send;
}
close:
sock_release(&sock);
}
任何幫助將非常感激,謝謝!
在LKM中使用類似的代碼進行試驗後,我能夠確定問題是由於試圖將我的套接字綁定到遠程ip造成的!我應該一直使用連接。 – owst 2009-11-30 01:58:10