Привет! Вот такая ситуация: сделал класс для отправки сообщений в kernel-space при помощи netlink-сокета, когда создаю консольное приложение - все нормально отправляется в модуль ядра, когда же использую тот же самый код из GUI-приложения - срабатывает крайне редко... В чем может быть проблема? (приложения в user-space создаю на Qt)
вот часть кода из user-space:
NetLinkManager::NetLinkManager() {
int res;
/* Создаем Netlink сокет, указываем собственное семейство (NETLINK_USERSOCK) */ if ((netlink_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK)) < 0) { qDebug() << «Ошибка создания NetLink-сокета»; return; }
/* Указываем в адресе наш идентификатор процесса и связываем адрес с сокетом */ memset(&nl_src_addr, 0, sizeof(nl_src_addr)); nl_src_addr.nl_family = AF_NETLINK; nl_src_addr.nl_pid = getpid(); nl_src_addr.nl_groups = 0;
res = bind(netlink_sock, (struct sockaddr*)&nl_src_addr, sizeof(nl_src_addr)); if(res < 0) { qDebug() << «Ошибка bind-инга NetLink-сокета»; return; }
/* Заполняем адрес для отправки сообщений модулю ядра */ nl_dest_addr.nl_family = AF_NETLINK; nl_dest_addr.nl_pid = 0; nl_dest_addr.nl_groups = 0;
/* Выделяем память для заголовка netlink сообщения и передаваемых данных */ nlmsg_send = (struct nlmsghdr *)malloc(NLMSG_SPACE(MSG_SIZE_SEND)); if(nlmsg_send == NULL) { qDebug() << «Ошибка выделения памяти1»; return; }
/* Указываем размер сообщения, и кто его отправляет */ nlmsg_send->nlmsg_len = NLMSG_SPACE(MSG_SIZE_SEND); nlmsg_send->nlmsg_pid = getpid(); nlmsg_send->nlmsg_flags = 0;
/* Заполняем iovec для структуры msghdr */ iov_send.iov_base = (void *)nlmsg_send; iov_send.iov_len = nlmsg_send->nlmsg_len;
/* Формируем сообщение: указываем, кому отправить и что отправить */ MSG_Send.msg_name = (void *)&nl_dest_addr; MSG_Send.msg_namelen = sizeof(nl_dest_addr); MSG_Send.msg_iov = &iov_send; MSG_Send.msg_iovlen = 1;
/* Выделяем память для принятия netlink сообщений */ nlmsg_read = (struct nlmsghdr *)malloc(NLMSG_SPACE(MSG_SIZE_READ)); if(nlmsg_read == NULL) { qDebug() << «Ошибка выделения памяти2»; return; }
/* Формируем сообщение для приема: указываем размер, и куда сохранять данные */ nlmsg_read->nlmsg_len = NLMSG_SPACE(MSG_SIZE_READ); iov_read.iov_base = (void *)nlmsg_read; iov_read.iov_len = nlmsg_read->nlmsg_len; MSG_Read.msg_iov = &iov_read; MSG_Read.msg_iovlen = 1;
/* Определяем указатели для удобной работы с принятыми и отправляемыми данными */ SEND_MSG = (struct Command*)NLMSG_DATA(nlmsg_send); RECV_FLAG = (bool*)NLMSG_DATA(nlmsg_read); }
bool NetLinkManager::sendCommand(struct Command com) { memcpy(SEND_MSG, &com, sizeof(com)); /* Отправляем сообщение модулю */ sendmsg(netlink_sock, &MSG_Send, 0); qDebug() << «Sended»;
recvmsg(netlink_sock, &MSG_Read, 0); qDebug() << «Receivied»;
...... }
Часть кода модуля ядра:
int init_module() { printk(KERN_INFO «Firewall: INIT kernel module\n»);
netlink_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0, netlink_Read_Msg, NULL, THIS_MODULE); if(netlink_sock == NULL) printk(KERN_ERR «Firewall: Error creating netlink socket.\n»);
return 0; }
void netlink_Read_Msg(struct sk_buff *skb_in) { printk(KERN_ERR «Firewall: read_begin!\n»); .....