- 论坛徽章:
- 0
|
加载后,向内核发送据之后,就死机了,请高手指点
内核版本:2.6.32-21-generic
内核源码
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <linux/proc_fs.h>
#define BUF_SIZE 16384
static struct sock *netlink_exam_sock;
static unsigned char buffer[BUF_SIZE];
static unsigned int buffer_tail = 0;
static void recv_handler(struct sk_buff *__skb)
{
struct nlmsghdr * nlhdr = NULL;
int len;
struct sk_buff *skb;
skb = __skb;
/* êÕμ½êy¾Yoó£¬ò»·YÔY′æ»o3壬ò»·Y¶à2¥3öè¥ */
if (!skb)
{
return;
}
nlhdr = (struct nlmsghdr *)skb->data;
if (!nlhdr)
{
return;
}
len = nlhdr->nlmsg_len - NLMSG_LENGTH(0);
if (len < 0)
{
printk(KERN_ERR "netlink recv error.\n");
return;
}
else
{
printk(KERN_ERR "netlink recv %d.\n", len);
}
/* »o3åÇøoľ¡£¬·Ç»·DÎμÄ£¬Ö»êÇÔúÄú′æÔY′æó|óÃ2ãêy¾Y */
if (len + buffer_tail > BUF_SIZE) {
printk(KERN_ERR "netlink buffer is full.\n");
}
else {
memcpy(buffer + buffer_tail, NLMSG_DATA(nlhdr), len);
buffer_tail += len;
}
/* Ôú¶à2¥×é1ÖD1ã2¥±¾′νóêÕêy¾Y */
nlhdr->nlmsg_pid = 0;
nlhdr->nlmsg_flags = 0;
NETLINK_CB(skb).pid = 0;
/* ½óêÕ½ø3ì¼óèë×é2¥×é1ÖD ËùòÔÕaàïéèÖÃÎa1 */
NETLINK_CB(skb).dst_group = 1;
netlink_broadcast(netlink_exam_sock, skb, 0, 1, GFP_KERNEL);
}
/* cat ¶¼êÇòÔò3Îaμ¥λ½øDD¶áμÄ D′μľí2»è·¶¨áË */
static int netlink_exam_readproc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
if (off >= buffer_tail) {
* eof = 1;
return 0;
}
else {
len = count;
if (count > PAGE_SIZE) {
len = PAGE_SIZE;
}
if (len > buffer_tail - off) {
len = buffer_tail - off;
}
memcpy(page, buffer + off, len);
*start = page;
return len;
}
}
static int __init netlink_exam_init(void)
{
/* ½ó¿úÔú>=kernel 2.6.24±ä»ˉoó£¬Ã»·¨óöàÏß3ì′|àíáË£¬¿éòÔ¶Ô±èÑ1Ëõ°üÖD′úÂë */
netlink_exam_sock = netlink_kernel_create(&init_net, NETLINK_HELUN, 1, recv_handler, NULL,THIS_MODULE);
/* ·μ»Ø3ö′í′ó¶àêyòòÎaD-òéoű»Õ¼óã¬ÄúoËí·Îļt£¬¿aí·Îļt¶¼òaDT¸Ä(ó|óÃ3ìDòê1óà NETLINK_HELUN) */
if (!netlink_exam_sock) {
printk("Fail to create netlink socket.\n");
return 1;
}
/* ′′½¨ÎļtÏμí3½áμ㣬¶á2ù×÷ */
create_proc_read_entry("netlink_exam_buffer", 0444, NULL, netlink_exam_readproc, 0);
return 0;
}
static void __exit netlink_exam_exit(void)
{
if (netlink_exam_sock)
{
wake_up(netlink_exam_sock->sk_sleep);
sock_release(netlink_exam_sock->sk_socket);
}
}
module_init(netlink_exam_init);
module_exit(netlink_exam_exit);
MODULE_LICENSE("GPL");
send进程源码
#define MAX_MSGSIZE 1024
int main(int argc, char * argv[])
{
FILE * fp;
struct sockaddr_nl saddr, daddr;
struct nlmsghdr *nlhdr = NULL;
struct msghdr msg;
struct iovec iov;
int sd;
unsigned int count = 0;
char text_line[MAX_MSGSIZE];
int ret = -1;
if (argc < 2) {
printf("Usage: %s atextfilename\n", argv[0]);
exit(1);
}
if ((fp = fopen(argv[1], "r")) == NULL) {
printf("File %s dosen't exist.\n");
exit(1);
}
sd = socket(AF_NETLINK, SOCK_RAW,NETLINK_HELUN);
memset(&saddr, 0, sizeof(saddr));
memset(&daddr, 0, sizeof(daddr));
saddr.nl_family = AF_NETLINK;
saddr.nl_pid = getpid();
saddr.nl_groups = 0;
bind(sd, (struct sockaddr*)&saddr, sizeof(saddr));
daddr.nl_family = AF_NETLINK;
daddr.nl_pid = 0;
daddr.nl_groups = 0;
nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_MSGSIZE));
while (fgets(text_line, MAX_MSGSIZE, fp)) {
memcpy(NLMSG_DATA(nlhdr), text_line, strlen(text_line));
printf("%d:%s\n", count++, text_line);
memset(&msg, 0 ,sizeof(struct msghdr));
nlhdr->nlmsg_len = NLMSG_LENGTH(strlen(text_line));
nlhdr->nlmsg_pid = getpid(); /* self pid */
nlhdr->nlmsg_flags = 0;
iov.iov_base = (void *)nlhdr;
iov.iov_len = nlhdr->nlmsg_len;
msg.msg_name = (void *)&daddr;
msg.msg_namelen = sizeof(daddr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg(sd, &msg, 0);
if (ret == -1) {
perror("sendmsg error:");
} else
{
printf("send %d \n", ret);
}
}
close(sd);
}
|
|