netlink机制使用实例
2014-06-18 16:02
120 查看
(一)客户端:
1./*创建NETLINK_ID客户端套接字
netlink _id = open_socket_for_netlink();
int open_socket_for_netlink()
{
int sock = -1;
int bindsock = -1;
struct sockaddr_nl nlskaddr;
sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_ID);
if (sock > 0)
{
memset ( &nlskaddr, 0 , sizeof( nlskaddr ) );
nlskaddr.nl_family = (sa_family_t)AF_NETLINK;
nlskaddr.nl_pid = 0; //getpid();
nlskaddr.nl_groups = TRAPTYPE_GROUP;
}
else
return -1;
bindsock = bind (sock,(struct sockaddr *)&nlskaddr,sizeof(nlskaddr));
if (bindsock != 0)
{
perror("bind failure!\n");
return -1;
}
{
int on = nlskaddr.nl_groups;
//setsockopt(sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
setsockopt(sock, 270, 1,&on, sizeof(on));
}
return sock;
}
2.通过套接子集操作来调用消息接受处理
if(FD_ISSET(netlink_id, &readfds))
{
receive_netlink_do();
FD_CLR(netlink_id, &readfds);
}
void receive_netlink_do()
{
struct nlmsghdr hdr; //从结构体中可以得到netlink消息的总长度
int read_len = -1;
memset(&hdr, 0, sizeof(hdr));
read_len = recvfrom(netlink_id,
&hdr, sizeof(hdr),
MSG_PEEK, NULL, NULL);
if (read_len <=0 || read_len != sizeof(hdr))
return;
struct nlmsg_netlink message;
memset(&message, 0, sizeof(message));
read_len = recvfrom(netlink_cgi_id, &message, sizeof(message),MSG_DONTWAIT, NULL, NULL);
if (read_len <=0 || read_len != hdr.nlmsg_len)
return;
……..
}
3. 主动发送消息给服务端:
send_nlhdr = ( struct nlmsghdr * ) malloc ( NLMSG_SPACE ( MAX_MSGSIZE ) );
void send_msg_to_server_kernel ( int msg_type, char *message, unsigned short int msg_len )
{
user_mgs *pmsg;
struct sockaddr_nl daddr;
struct nlmsghdr *nlhdr = NULL;
struct msghdr msg;
struct iovec iov;
int ret;
int *mess;
send_nlhdr->nlmsg_len = NLMSG_SPACE ( MAX_MSGSIZE );
send_nlhdr->nlmsg_pid = getpid(); /* self pid */
send_nlhdr->nlmsg_flags = 0;
/* 填写用户消息*/
pmsg = ( USER_MSG * ) NLMSG_DATA ( send_nlhdr );
pmsg->msg_id = msg_type;
pmsg->datalen = msg_len*4;
memcpy ( pmsg->data, message, 4*msg_len );
mess= ( int * ) message;
memset ( &daddr, 0, sizeof ( daddr ) );
daddr.nl_family = AF_NETLINK;
daddr.nl_pid = 0; /* For Linux Kernel */
daddr.nl_groups = 0; /* unicast */
memset ( &msg, 0 ,sizeof ( struct msghdr ) );
iov.iov_base = ( void * ) send_nlhdr;
iov.iov_len = send_nlhdr->nlmsg_len;
msg.msg_name = ( void * ) &daddr;
msg.msg_namelen = sizeof ( daddr );
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg
( netlink_sk, &msg, 0 );
if ( ret == -1 )
{
perror ( "sendmsg error" );
}
}
(二)服务端:
1.服务器注册NETLINK_ID 的netlink_sk
netlink_sk=netlink_kernel_create(&init_net,NETLINK_ID, 0,
recv_msg_from_user, NULL,THIS_MODULE);
2.netlink发送函数处理
int server_netlink_send_msg_portal ( struct sock *netlink_sk, u_int8_t *msg, int len )
{
int ret = -1;
int size;
unsigned char *old_tail;
struct sk_buff *skb;
struct nlmsghdr *nlh;
char *pos = NULL;
size = NLMSG_SPACE ( len );
skb = dev_alloc_skb ( size );
if ( skb == NULL )
{
goto out;
}
old_tail = skb->tail;
/*填写数据报相关信息*/
nlh = NLMSG_PUT ( skb, 0, 0, AUTH_GROUP, size - sizeof ( struct nlmsghdr ) );
pos = NLMSG_DATA ( nlh );
memset ( pos, 0, len );
memcpy ( pos, msg, len );/*传输到用户空间的数据*/
nlh->nlmsg_len = skb->tail - old_tail;/*计算经过字节对其后的数据实际长度*/
NETLINK_CB ( skb ).dst_group =
TRAPTYPE_GROUP;
if ( netlink_sk )
netlink_broadcast ( netlink_sk, skb, 0,TRAPTYPE_GROUP, GFP_ATOMIC );
else
goto out;
ret = 0;
out:
return ret;
nlmsg_failure: /*NLMSG_PUT 失败,则撤销套接字缓存*/
kfree_skb ( skb );
goto out;
}
3. 处理用户空间传递的消息:
void recv_msg_from_user (struct sk_buff *skb)
{
struct nlmsghdr *nlh = NULL;
u8 *payload = NULL;
skb = skb_clone(skb, GFP_KERNEL);
//while ( (skb = skb_dequeue( &sk->sk_receive_queue)) != NULL )
if (skb)
{
/* process netlink message pointed by skb->data */
nlh = (struct nlmsghdr *)skb->data;
/* process netlink message with header pointed by
* nlh and payload pointed by payload
*/
payload = NLMSG_DATA(nlh);
deal_msg_from_user( payload );
//if(skb) kfree_skb(skb);
}
}
1./*创建NETLINK_ID客户端套接字
netlink _id = open_socket_for_netlink();
int open_socket_for_netlink()
{
int sock = -1;
int bindsock = -1;
struct sockaddr_nl nlskaddr;
sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_ID);
if (sock > 0)
{
memset ( &nlskaddr, 0 , sizeof( nlskaddr ) );
nlskaddr.nl_family = (sa_family_t)AF_NETLINK;
nlskaddr.nl_pid = 0; //getpid();
nlskaddr.nl_groups = TRAPTYPE_GROUP;
}
else
return -1;
bindsock = bind (sock,(struct sockaddr *)&nlskaddr,sizeof(nlskaddr));
if (bindsock != 0)
{
perror("bind failure!\n");
return -1;
}
{
int on = nlskaddr.nl_groups;
//setsockopt(sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
setsockopt(sock, 270, 1,&on, sizeof(on));
}
return sock;
}
2.通过套接子集操作来调用消息接受处理
if(FD_ISSET(netlink_id, &readfds))
{
receive_netlink_do();
FD_CLR(netlink_id, &readfds);
}
void receive_netlink_do()
{
struct nlmsghdr hdr; //从结构体中可以得到netlink消息的总长度
int read_len = -1;
memset(&hdr, 0, sizeof(hdr));
read_len = recvfrom(netlink_id,
&hdr, sizeof(hdr),
MSG_PEEK, NULL, NULL);
if (read_len <=0 || read_len != sizeof(hdr))
return;
struct nlmsg_netlink message;
memset(&message, 0, sizeof(message));
read_len = recvfrom(netlink_cgi_id, &message, sizeof(message),MSG_DONTWAIT, NULL, NULL);
if (read_len <=0 || read_len != hdr.nlmsg_len)
return;
……..
}
3. 主动发送消息给服务端:
send_nlhdr = ( struct nlmsghdr * ) malloc ( NLMSG_SPACE ( MAX_MSGSIZE ) );
void send_msg_to_server_kernel ( int msg_type, char *message, unsigned short int msg_len )
{
user_mgs *pmsg;
struct sockaddr_nl daddr;
struct nlmsghdr *nlhdr = NULL;
struct msghdr msg;
struct iovec iov;
int ret;
int *mess;
send_nlhdr->nlmsg_len = NLMSG_SPACE ( MAX_MSGSIZE );
send_nlhdr->nlmsg_pid = getpid(); /* self pid */
send_nlhdr->nlmsg_flags = 0;
/* 填写用户消息*/
pmsg = ( USER_MSG * ) NLMSG_DATA ( send_nlhdr );
pmsg->msg_id = msg_type;
pmsg->datalen = msg_len*4;
memcpy ( pmsg->data, message, 4*msg_len );
mess= ( int * ) message;
memset ( &daddr, 0, sizeof ( daddr ) );
daddr.nl_family = AF_NETLINK;
daddr.nl_pid = 0; /* For Linux Kernel */
daddr.nl_groups = 0; /* unicast */
memset ( &msg, 0 ,sizeof ( struct msghdr ) );
iov.iov_base = ( void * ) send_nlhdr;
iov.iov_len = send_nlhdr->nlmsg_len;
msg.msg_name = ( void * ) &daddr;
msg.msg_namelen = sizeof ( daddr );
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ret = sendmsg
( netlink_sk, &msg, 0 );
if ( ret == -1 )
{
perror ( "sendmsg error" );
}
}
(二)服务端:
1.服务器注册NETLINK_ID 的netlink_sk
netlink_sk=netlink_kernel_create(&init_net,NETLINK_ID, 0,
recv_msg_from_user, NULL,THIS_MODULE);
2.netlink发送函数处理
int server_netlink_send_msg_portal ( struct sock *netlink_sk, u_int8_t *msg, int len )
{
int ret = -1;
int size;
unsigned char *old_tail;
struct sk_buff *skb;
struct nlmsghdr *nlh;
char *pos = NULL;
size = NLMSG_SPACE ( len );
skb = dev_alloc_skb ( size );
if ( skb == NULL )
{
goto out;
}
old_tail = skb->tail;
/*填写数据报相关信息*/
nlh = NLMSG_PUT ( skb, 0, 0, AUTH_GROUP, size - sizeof ( struct nlmsghdr ) );
pos = NLMSG_DATA ( nlh );
memset ( pos, 0, len );
memcpy ( pos, msg, len );/*传输到用户空间的数据*/
nlh->nlmsg_len = skb->tail - old_tail;/*计算经过字节对其后的数据实际长度*/
NETLINK_CB ( skb ).dst_group =
TRAPTYPE_GROUP;
if ( netlink_sk )
netlink_broadcast ( netlink_sk, skb, 0,TRAPTYPE_GROUP, GFP_ATOMIC );
else
goto out;
ret = 0;
out:
return ret;
nlmsg_failure: /*NLMSG_PUT 失败,则撤销套接字缓存*/
kfree_skb ( skb );
goto out;
}
3. 处理用户空间传递的消息:
void recv_msg_from_user (struct sk_buff *skb)
{
struct nlmsghdr *nlh = NULL;
u8 *payload = NULL;
skb = skb_clone(skb, GFP_KERNEL);
//while ( (skb = skb_dequeue( &sk->sk_receive_queue)) != NULL )
if (skb)
{
/* process netlink message pointed by skb->data */
nlh = (struct nlmsghdr *)skb->data;
/* process netlink message with header pointed by
* nlh and payload pointed by payload
*/
payload = NLMSG_DATA(nlh);
deal_msg_from_user( payload );
//if(skb) kfree_skb(skb);
}
}
相关文章推荐
- 使用反射机制将一个类实例的值赋给DataTable某一行
- 使用反射机制用一个类实例的值为DataTable添加一行
- 委托机制在线程中的使用的简单实例
- Linux中与内核通信的Netlink机制(实例)
- LoadingCache简单实例,使用google缓存机制
- 使用netlink机制在内核与应用程序之间通信
- Linux中与内核通信的Netlink机制(实例)
- linux netlink机制介绍与实例
- inux netlink机制介绍与实例
- Linux中与内核通信的Netlink机制(实例)
- C#中使用反射机制得到类型实例应用Demo
- 使用netlink机制实现内核空间和用户空间的双向消息通讯
- 使用netlink机制在内核进程和用户空间进程通信
- Linux中与内核通信的Netlink机制(实例)
- netlink机制和udev实例
- 使用反射机制将一个类实例的值赋给DataTable某一行
- NetLink机制使用
- NetLink机制使用
- 使用反射机制创建对象实例
- Linux中与内核通信的Netlink机制(实例)