What is User Space and Kernel Space:
Different ways of Communication b/w User Space and Kernel Space:
Standard API's for Kernel Space:
e.g:
> To avoid this kind of error :assertion (!atomic_read(&sk->sk_rmem_alloc)) failed, ensure that the skb is freed after being dequeued and processed. ( SKB Should be freed in De-queue Function) e.g: static void msgFromNetLinkSock(struct sock *sk, int len) {
e.g: While sending data from kernel, /* Copy the Payload */
For Further reading: http://people.ee.ethz.ch/~arkeller/linux/kernel_user_space_howto.html
Operating system segregates virtual memory into kernel space and user space.
Kernel space is strictly reserved for running the kernel, kernel extensions, and most device drivers.
In contrast, user space is the memory area where all user mode applications work and this memory can be swapped out when necessary.
Different ways of Communication b/w User Space and Kernel Space:
There are many ways to Communicate between the User space and Kernel Space, they are:
File system based communication:
- Procfs
- Sysfs
- Configfs
- Debugfs
- Sysctl
- Character Devices
Socket Based Communication:
There are two types of sockets used for communication.
UDP Sockets
Netlink Socket.
In this post, i will be giving more importance for the Netlink socket based communication since this mechanism is extensively used in Linux networking applications.
What is NETLINK Socket:
Netlink socket is a special IPC used for transferring information between kernel and user-space processes.
It provides a full-duplex communication link between the two by way of standard socket APIs for user-space processes and a special kernel API for kernel modules.
- vNetlink socket uses the address family AF_NETLINK, as compared to AF_INET used by TCP/IP socket.
- vEach netlink socket feature defines its own protocol type in the kernel header file include/linux/netlink.h
Why do the above features use netlink instead of system calls, ioctls or proc filesystems for communication between user and kernel worlds?
- vIt is a nontrivial task to add system calls, ioctls or proc files for new features; we risk polluting the kernel and damaging the stability of the system.
- vNetlink socket is simple, though: only a constant, the protocol type, needs to be added to netlink.h.
- vThen, the kernel module and application can talk using socket-style APIs immediately
- vNetlink is asynchronous because, as with any other socket API, it provides a socket queue to smooth the burst of messages.
- vThe system call for sending a netlink message queues the message to the receiver's netlink queue and then invokes the receiver's reception handler.
- vThe receiver, within the reception handler's context, can decide whether to process the message immediately or leave the message in the queue and process it later in a different context.
- vUnlike netlink, system calls require synchronous processing. Therefore, if we use a system call to pass a message from user space to the kernel, the kernel scheduling granularity may be affected if the time to process that message is long.
v NetLink sockets can be used for Multicast.
Standard API's
vThe standard socket APIs—socket(), sendmsg() or sendto(), recvmsg() or recvFrom() and close()—can be used by user-space applications to access netlink socket.
int socket(int domain, int type, int protocol)
The socket domain (address family) is AF_NETLINK, and the type of socket is either SOCK_RAW or SOCK_DGRAM, because netlink is a datagram-oriented service.
The protocol (protocol type) selects for which netlink feature the socket is used. The following are some predefined netlink protocol types: NETLINK_ROUTE, NETLINK_FIREWALL, NETLINK_ARPD, NETLINK_ROUTE6 and NETLINK_IP6_FW. You also can add your own netlink protocol type easily.
Standard API's for Kernel Space:
How to Create Netlink socket in kernel?
struct sock*
netlink_kernel_create(struct net *net,int unit,unsigned int groups,
void (*input)(struct sk_buff *skb),
struct mutex *cb_mutex,
struct module *module)
e.g: No need to pass the net parameter.
/* Create NetLink Socket */
nlSock = netlink_kernel_create
( NETLINK_MUNISOCK, // Unit can be Protocol Type
0, // Groups can be Zero
msgFromNetLinkSock, // Call Back Function
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
NULL, // Mutex can be zero
#endif
THIS_MODULE);
Important Hint: The value of NETLINK_MUNISOCK should be same in User space and Kernel Space ( NETLINK_MUNISOCK, // Unit can be Protocol Type
0, // Groups can be Zero
msgFromNetLinkSock, // Call Back Function
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
NULL, // Mutex can be zero
#endif
THIS_MODULE);
This is nothing about protocol Type and it should be same in User space and Kernel Space.
cat /proc/net/netlink -> To check the netlink Sock ID's in kernel
cat /proc/net/netlink -> To check the netlink Sock ID's in kernel
How to send a unicast message to user Space?
int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock);
e.g:
int Error;
Error = netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
if(Error == -1) { printk(KERN_INFO "Unable to send Info Back to User Space\n"); }
How to de-queue netlink message from Call back function in Kernel Space?
skb = skb_dequeue(&sk->receive_queue))
E.g:
static void msgFromNetLinkSock(struct sock *sk, int nLength)
{
struct sk_buff *skb; struct nlmsghdr *nlh = NULL; unsigned char *payload = NULL; while ((skb = skb_dequeue(&sk->receive_queue)) != NULL)
{
/* process netlink message pointed by skb->data */
nlh = (struct nlmsghdr *)skb->data;
payload = NLMSG_DATA(nlh);
/* process netlink message with header pointed by
* nlh and payload pointed by payload
*/
}
}
Working Code For NETLINK Socket:
Kernel Space Code:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/version.h>
#include <linux/netlink.h>
#include<linux/udp.h>
/* Optional Headers not Required, If you don't want Remove*/
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/socket.h>
#include <linux/icmp.h>
/* These Headers are also Optional (Not Required),
But these are Required for NETFILTER functionality */
#include <net/checksum.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/interrupt.h>
/* NetLink Definitions */
#define NETLINK_HEADER_SIZE 16
#define NETLINK_MUNISOCK 25
#define NL_MSG_TYPE 20
#define MAX_BUFFER_SIZE 1024
/* Driver Definitions */
#define DRIVER_AUTHOR "AMSEKHAR"
#define DRIVER_DESC "SAMPLE_NETLINK_SOCKET"
#define MAX_DATA_SIZE 50
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/version.h>
#include <linux/netlink.h>
#include<linux/udp.h>
/* Optional Headers not Required, If you don't want Remove*/
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/socket.h>
#include <linux/icmp.h>
/* These Headers are also Optional (Not Required),
But these are Required for NETFILTER functionality */
#include <net/checksum.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/interrupt.h>
/* NetLink Definitions */
#define NETLINK_HEADER_SIZE 16
#define NETLINK_MUNISOCK 25
#define NL_MSG_TYPE 20
#define MAX_BUFFER_SIZE 1024
/* Driver Definitions */
#define DRIVER_AUTHOR "AMSEKHAR"
#define DRIVER_DESC "SAMPLE_NETLINK_SOCKET"
#define MAX_DATA_SIZE 50
/* Dump Function */
static void dumpRecvData(unsigned char *data, unsigned int dataLen);
/* Declare Buffer */
unsigned char *ucBuffer = NULL;
/* Netlink Sock ID*/
static struct sock *nl_sock_id = NULL;
/* Process Id */
static pid_t pid = 0;
static void dumpRecvData(unsigned char *data, unsigned int dataLen);
/* Declare Buffer */
unsigned char *ucBuffer = NULL;
/* Netlink Sock ID*/
static struct sock *nl_sock_id = NULL;
/* Process Id */
static pid_t pid = 0;
/*
* Function Name : dumpRecvData()
*/
void dumpRecvData(unsigned char *data, unsigned int len)
{
unsigned int uIndx=0;
printk("The Data:\n");
if(data)
{
for(uIndx=0; uIndx<len; ++uIndx)
{
if(uIndx%32 == 0)
{
printk("\n%4d:", uIndx);
}
if(uIndx%4 == 0)
{
printk(" ");
}
printk("%02x", data[uIndx]);
}
}
printk(" Length of Bytes: %d\n", len);
printk("\n");
}
* Function Name : dumpRecvData()
*/
void dumpRecvData(unsigned char *data, unsigned int len)
{
unsigned int uIndx=0;
printk("The Data:\n");
if(data)
{
for(uIndx=0; uIndx<len; ++uIndx)
{
if(uIndx%32 == 0)
{
printk("\n%4d:", uIndx);
}
if(uIndx%4 == 0)
{
printk(" ");
}
printk("%02x", data[uIndx]);
}
}
printk(" Length of Bytes: %d\n", len);
printk("\n");
}
/*
* Function Name : sendDataToUserSpace()
*/
void sendDataToUserSpace(unsigned char *ucBuffer, int unDataLen)
{
/* Intialise the Sk buffer */
struct sk_buff *skb = NULL;
/* Intialise the Netlink message Hdr */
struct nlmsghdr *nlhdr = NULL;
int nRet= 0;
/* Allocate the Memory Using SKB for sending To Appl Space */
skb = alloc_skb((unDataLen + sizeof (struct nlmsghdr)), GFP_ATOMIC);
/* Move the Tail Pointer at end of the Buffer */
skb_put(skb, (unDataLen + sizeof (struct nlmsghdr)));
/* Validate the Skb */
if(NULL != skb)
{
nlhdr = (struct nlmsghdr *)skb->data;
nlhdr->nlmsg_len = NLMSG_SPACE(MAX_BUFFER_SIZE);
/*pid=0 corresponds to kernel */
nlhdr->nlmsg_pid = 0;
nlhdr->nlmsg_flags = 0;
nlhdr->nlmsg_seq = 1;
nlhdr->nlmsg_type = NL_MSG_TYPE;
/* Copy the Payload */
memmove(NLMSG_DATA(nlhdr), ucBuffer, unDataLen);
NETLINK_CB(skb).pid = 0;
/*BSGATM.exe Process ID */
NETLINK_CB(skb).dst_pid = pid ;
NETLINK_CB(skb).dst_group = 0; /* unicast */
/* send the NetLink Message to Application space */
nRet = netlink_unicast(nl_sock_id, skb, pid, MSG_DONTWAIT);
if(nRet == -1)
{
printk("Not Send Successfully\n");
kfree_skb(skb);
}
else
{
printk(" Successfully sent to Application space\n");
}
}
}
* Function Name : sendDataToUserSpace()
*/
void sendDataToUserSpace(unsigned char *ucBuffer, int unDataLen)
{
/* Intialise the Sk buffer */
struct sk_buff *skb = NULL;
/* Intialise the Netlink message Hdr */
struct nlmsghdr *nlhdr = NULL;
int nRet= 0;
/* Allocate the Memory Using SKB for sending To Appl Space */
skb = alloc_skb((unDataLen + sizeof (struct nlmsghdr)), GFP_ATOMIC);
/* Move the Tail Pointer at end of the Buffer */
skb_put(skb, (unDataLen + sizeof (struct nlmsghdr)));
/* Validate the Skb */
if(NULL != skb)
{
nlhdr = (struct nlmsghdr *)skb->data;
nlhdr->nlmsg_len = NLMSG_SPACE(MAX_BUFFER_SIZE);
/*pid=0 corresponds to kernel */
nlhdr->nlmsg_pid = 0;
nlhdr->nlmsg_flags = 0;
nlhdr->nlmsg_seq = 1;
nlhdr->nlmsg_type = NL_MSG_TYPE;
/* Copy the Payload */
memmove(NLMSG_DATA(nlhdr), ucBuffer, unDataLen);
NETLINK_CB(skb).pid = 0;
/*BSGATM.exe Process ID */
NETLINK_CB(skb).dst_pid = pid ;
NETLINK_CB(skb).dst_group = 0; /* unicast */
/* send the NetLink Message to Application space */
nRet = netlink_unicast(nl_sock_id, skb, pid, MSG_DONTWAIT);
if(nRet == -1)
{
printk("Not Send Successfully\n");
kfree_skb(skb);
}
else
{
printk(" Successfully sent to Application space\n");
}
}
}
/*
* Function Name : MsgFromNetLinkSock
*/
static void msgFromNetLinkSock(struct sock *sk, int len)
{
struct sk_buff *skb = NULL;
struct nlmsghdr *nlhdr = NULL;
int type, unDataLen;
/* skb_dequeue takes the buffer from a queue.
* Nothing(No Buffer) is there then it return NULL pointer.*/
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL)
{
/* Extract the NetLink Header fields for Processing */
nlhdr = (struct nlmsghdr *)skb->data;
if(nlhdr->nlmsg_pid != 0)
{
pid = nlhdr->nlmsg_pid; /*pid of sending process */
}
/* Copy the Type of message */
type = nlhdr->nlmsg_type;
if (type != NL_MSG_TYPE)
{
printk(KERN_INFO "Recieved Message Type :%d", type);
kfree_skb(skb);
continue;
}
/* Point the data to Buffer */
ucBuffer = NLMSG_DATA(nlhdr);
* Function Name : MsgFromNetLinkSock
*/
static void msgFromNetLinkSock(struct sock *sk, int len)
{
struct sk_buff *skb = NULL;
struct nlmsghdr *nlhdr = NULL;
int type, unDataLen;
/* skb_dequeue takes the buffer from a queue.
* Nothing(No Buffer) is there then it return NULL pointer.*/
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL)
{
/* Extract the NetLink Header fields for Processing */
nlhdr = (struct nlmsghdr *)skb->data;
if(nlhdr->nlmsg_pid != 0)
{
pid = nlhdr->nlmsg_pid; /*pid of sending process */
}
/* Copy the Type of message */
type = nlhdr->nlmsg_type;
if (type != NL_MSG_TYPE)
{
printk(KERN_INFO "Recieved Message Type :%d", type);
kfree_skb(skb);
continue;
}
/* Point the data to Buffer */
ucBuffer = NLMSG_DATA(nlhdr);
/* Compute Actual Length */
/* skb->len and nlhdr->nlmsg_len are same.*/
//or unDataLen = nlhdr->nlmsg_len - NETLINK_HDR_SIZE;
unDataLen = skb->len - NETLINK_HEADER_SIZE;
/* dump Recieved Data*/
dumpRecvData(ucBuffer, unDataLen);
/* Send the Data to User SPace from Kernel */
sendDataToUserSpace(ucBuffer, unDataLen);
/* If this is not there, then it will throw an atomic error */
kfree_skb(skb);
}
}
/* skb->len and nlhdr->nlmsg_len are same.*/
//or unDataLen = nlhdr->nlmsg_len - NETLINK_HDR_SIZE;
unDataLen = skb->len - NETLINK_HEADER_SIZE;
/* dump Recieved Data*/
dumpRecvData(ucBuffer, unDataLen);
/* Send the Data to User SPace from Kernel */
sendDataToUserSpace(ucBuffer, unDataLen);
/* If this is not there, then it will throw an atomic error */
kfree_skb(skb);
}
}
/*
* Function Name : netlinkProcess_init()
*/
static int __init init_netlinkAppl(void)
{
printk(KERN_INFO "NFNL Loading netlinkProcess Module\n");
// Create NetLink Socket
nl_sock_id = netlink_kernel_create(NETLINK_MUNISOCK,
0,
msgFromNetLinkSock,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
NULL,
#endif
THIS_MODULE);
if(!nl_sock_id)
{
printk(KERN_ERR "NFNL %s: receive handler registration failed\n", __func__);
return -ENOMEM;
}
return 0;
}
* Function Name : netlinkProcess_init()
*/
static int __init init_netlinkAppl(void)
{
printk(KERN_INFO "NFNL Loading netlinkProcess Module\n");
// Create NetLink Socket
nl_sock_id = netlink_kernel_create(NETLINK_MUNISOCK,
0,
msgFromNetLinkSock,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
NULL,
#endif
THIS_MODULE);
if(!nl_sock_id)
{
printk(KERN_ERR "NFNL %s: receive handler registration failed\n", __func__);
return -ENOMEM;
}
return 0;
}
/*
* Function Name : cleanup Module()
*/
static void __exit exit_netlinkAppl(void)
{
printk(KERN_INFO "NFNL UnLoading netlinkProcess Module\n");
if(nl_sock_id)
{
//netlink_kernel_release(nl_sock_id);
sock_release(nl_sock_id->sk_socket);
}
}
/* Module Init and exit */
module_init(init_netlinkAppl);
module_exit(exit_netlinkAppl);
/* Module properties */
MODULE_LICENSE("Proprietary");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION("2.6.18.194");
obj-m += netlinksock.o
netlinksock-objs := netlinkProcess.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
* Function Name : cleanup Module()
*/
static void __exit exit_netlinkAppl(void)
{
printk(KERN_INFO "NFNL UnLoading netlinkProcess Module\n");
if(nl_sock_id)
{
//netlink_kernel_release(nl_sock_id);
sock_release(nl_sock_id->sk_socket);
}
}
/* Module Init and exit */
module_init(init_netlinkAppl);
module_exit(exit_netlinkAppl);
/* Module properties */
MODULE_LICENSE("Proprietary");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION("2.6.18.194");
How to compile the Kernel Space Code
1. Create Makefile
2. Copy the below contents in to Makefile.
obj-m += netlinksock.o
netlinksock-objs := netlinkProcess.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
User Space Code:
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/netlink.h>
/* Netlink Defines */
#define NL_MSG_TYPE 20
#define NETLINK_MUNISOCK 25
#define NETLINK_HEADER_SIZE 16
#define MAX_DATA_SIZE 30
/* Socket FD */
int netlinkSockFD;
struct sockaddr_nl SrcAddr;
struct sockaddr_nl DestAddr;
/* Sequence No */
int SeqNo;
/* process Id */
pid_t PID;
/* Configure The Structure */
unsigned char ucBuffer[MAX_DATA_SIZE];
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/netlink.h>
/* Netlink Defines */
#define NL_MSG_TYPE 20
#define NETLINK_MUNISOCK 25
#define NETLINK_HEADER_SIZE 16
#define MAX_DATA_SIZE 30
/* Socket FD */
int netlinkSockFD;
struct sockaddr_nl SrcAddr;
struct sockaddr_nl DestAddr;
/* Sequence No */
int SeqNo;
/* process Id */
pid_t PID;
/* Configure The Structure */
unsigned char ucBuffer[MAX_DATA_SIZE];
/*
* Name : SendMessage()
*/
bool sendDataToKernel(int len)
{
unsigned char buf[1024]={0};
bool ret = false;
int errno;
unsigned int uIndx;
/* Intialise the buffer */
for(uIndx=0; uIndx<len; uIndx++)
{
ucBuffer[uIndx] = 0x31;
}
struct nlmsghdr *nlh = (struct nlmsghdr*)buf;
nlh->nlmsg_len = (len + NETLINK_HEADER_SIZE );
nlh->nlmsg_pid = PID; /* self pid */
nlh->nlmsg_seq = SeqNo++;
nlh->nlmsg_flags = 0;
nlh->nlmsg_type = NL_MSG_TYPE;
/* Copy the Buffer */
memcpy(NLMSG_DATA(nlh), &ucBuffer, len);
/* Send the Data */
int res = sendto(netlinkSockFD, nlh, nlh->nlmsg_len, 0,
(const struct sockaddr*) &DestAddr, sizeof(struct sockaddr_nl));
* Name : SendMessage()
*/
bool sendDataToKernel(int len)
{
unsigned char buf[1024]={0};
bool ret = false;
int errno;
unsigned int uIndx;
/* Intialise the buffer */
for(uIndx=0; uIndx<len; uIndx++)
{
ucBuffer[uIndx] = 0x31;
}
struct nlmsghdr *nlh = (struct nlmsghdr*)buf;
nlh->nlmsg_len = (len + NETLINK_HEADER_SIZE );
nlh->nlmsg_pid = PID; /* self pid */
nlh->nlmsg_seq = SeqNo++;
nlh->nlmsg_flags = 0;
nlh->nlmsg_type = NL_MSG_TYPE;
/* Copy the Buffer */
memcpy(NLMSG_DATA(nlh), &ucBuffer, len);
/* Send the Data */
int res = sendto(netlinkSockFD, nlh, nlh->nlmsg_len, 0,
(const struct sockaddr*) &DestAddr, sizeof(struct sockaddr_nl));
if(-1 == res)
{
cout<<"Unable to Transmit Netlink Message: "<<strerror(errno);
return ret;
}
return (ret=true);
}
/*
* Function Name : dumpData()
*/
void dumpData(unsigned char *data, unsigned int len)
{
unsigned int uIndx;
if(data)
{
for(uIndx=0; uIndx<len; ++uIndx)
{
if(uIndx%32 == 0)
{
printf("\n%4d:", uIndx);
}
if(uIndx%4 == 0)
{
printf(" ");
}
//printf("%02x", data[uIndx]);
printf("%02x", *(data + uIndx));
}
}
printf("\n Length of Bytes: %d\n", len);
printf("\n");
}
/*
* Func: recvMsgFromKernel()
*/
void *recvMsgFromKernel(void *args)
{
unsigned char ucBuffer[1024];
struct sockaddr_nl client_addr;
socklen_t size = sizeof(struct sockaddr_nl);
int length =0;
while(true)
{
memset(ucBuffer, 0,1024);
// Recieve Data from Kernel
length = recvfrom(netlinkSockFD, ucBuffer, 1024 , MSG_NOSIGNAL, (struct sockaddr*)&client_addr, &size);
if (length > 0 )
{
struct nlmsghdr *nlh = (struct nlmsghdr*) ucBuffer;
if(0 != nlh->nlmsg_pid)
{
printf("\nReceived Message from Unknown Source\n");
continue;
}
else
{
unsigned char ucBuf[1024];
unsigned int unActualLen = length - sizeof (struct nlmsghdr);
memmove(&ucBuf, NLMSG_DATA(nlh), length - sizeof(struct nlmsghdr));
/* dump Recieved Data */
dumpData(ucBuf, unActualLen);
}
}
}
}
/*
* Name : main()
*/
int main()
{
bool ret;
int ch, len, errno;
/* Intialise Socket Paramters */
netlinkSockFD = -1;
PID = getpid();
SeqNo = 0;
memset(&DestAddr, 0, sizeof(struct sockaddr_nl));
memset(&SrcAddr, 0, sizeof(struct sockaddr_nl));
//create receive thread
pthread_t threadId;
if(pthread_create(&threadId, NULL, recvMsgFromKernel, NULL))
{
perror("Error in creating receiver thread");
return -1;
}
/* Create NetLink Socket */
netlinkSockFD = socket(PF_NETLINK, SOCK_RAW, NETLINK_MUNISOCK);
if(netlinkSockFD == -1)
{
cout<< "Unable to open socket - " << strerror(errno);
return 0;
}
else
{
cout<< "Netlink Socket created Successfully\n";
}
memset(&DestAddr, 0, sizeof(struct sockaddr_nl));
DestAddr.nl_family = AF_NETLINK;
DestAddr.nl_pid = 0; /* For Linux Kernel */
DestAddr.nl_groups = 0; /* unicast */
do
{
cout<<endl;
cout<<" Enter your choice:\t"<<endl;
cout<<" 1. Send Data to Kernel" <<endl;
cout<<" 2. exit" <<endl;
cin>>ch;
cout<<endl;
switch(ch)
{
case 1:
{
cout<<"Enter the Length of the Payload "<<endl;
cin>>len;
ret = sendDataToKernel(len);
if(ret)
{
cout<<"\n Netlink Socket Sent successfully \n";
}
else
{
cout<<"\n Netlink Socket Failed in Sending Message \n";
}
break;
}
default:
cout<<"Invalid Choice\n";
break;
}
}while(ch!=2);
}
{
cout<<"Unable to Transmit Netlink Message: "<<strerror(errno);
return ret;
}
return (ret=true);
}
/*
* Function Name : dumpData()
*/
void dumpData(unsigned char *data, unsigned int len)
{
unsigned int uIndx;
if(data)
{
for(uIndx=0; uIndx<len; ++uIndx)
{
if(uIndx%32 == 0)
{
printf("\n%4d:", uIndx);
}
if(uIndx%4 == 0)
{
printf(" ");
}
//printf("%02x", data[uIndx]);
printf("%02x", *(data + uIndx));
}
}
printf("\n Length of Bytes: %d\n", len);
printf("\n");
}
/*
* Func: recvMsgFromKernel()
*/
void *recvMsgFromKernel(void *args)
{
unsigned char ucBuffer[1024];
struct sockaddr_nl client_addr;
socklen_t size = sizeof(struct sockaddr_nl);
int length =0;
while(true)
{
memset(ucBuffer, 0,1024);
// Recieve Data from Kernel
length = recvfrom(netlinkSockFD, ucBuffer, 1024 , MSG_NOSIGNAL, (struct sockaddr*)&client_addr, &size);
if (length > 0 )
{
struct nlmsghdr *nlh = (struct nlmsghdr*) ucBuffer;
if(0 != nlh->nlmsg_pid)
{
printf("\nReceived Message from Unknown Source\n");
continue;
}
else
{
unsigned char ucBuf[1024];
unsigned int unActualLen = length - sizeof (struct nlmsghdr);
memmove(&ucBuf, NLMSG_DATA(nlh), length - sizeof(struct nlmsghdr));
/* dump Recieved Data */
dumpData(ucBuf, unActualLen);
}
}
}
}
/*
* Name : main()
*/
int main()
{
bool ret;
int ch, len, errno;
/* Intialise Socket Paramters */
netlinkSockFD = -1;
PID = getpid();
SeqNo = 0;
memset(&DestAddr, 0, sizeof(struct sockaddr_nl));
memset(&SrcAddr, 0, sizeof(struct sockaddr_nl));
//create receive thread
pthread_t threadId;
if(pthread_create(&threadId, NULL, recvMsgFromKernel, NULL))
{
perror("Error in creating receiver thread");
return -1;
}
/* Create NetLink Socket */
netlinkSockFD = socket(PF_NETLINK, SOCK_RAW, NETLINK_MUNISOCK);
if(netlinkSockFD == -1)
{
cout<< "Unable to open socket - " << strerror(errno);
return 0;
}
else
{
cout<< "Netlink Socket created Successfully\n";
}
memset(&DestAddr, 0, sizeof(struct sockaddr_nl));
DestAddr.nl_family = AF_NETLINK;
DestAddr.nl_pid = 0; /* For Linux Kernel */
DestAddr.nl_groups = 0; /* unicast */
do
{
cout<<endl;
cout<<" Enter your choice:\t"<<endl;
cout<<" 1. Send Data to Kernel" <<endl;
cout<<" 2. exit" <<endl;
cin>>ch;
cout<<endl;
switch(ch)
{
case 1:
{
cout<<"Enter the Length of the Payload "<<endl;
cin>>len;
ret = sendDataToKernel(len);
if(ret)
{
cout<<"\n Netlink Socket Sent successfully \n";
}
else
{
cout<<"\n Netlink Socket Failed in Sending Message \n";
}
break;
}
default:
cout<<"Invalid Choice\n";
break;
}
}while(ch!=2);
}
How to compile the user space code:
> First save this file as userNetLinkSock.cpp then compile using below command
> c++ userNetLinkSock.cpp -lpthread -o user
Find a local DJ, DJ wanted London
ReplyDeleteDj Required has been setup by a mixed group of London’s finest Dj’s, a top photographer and cameraman. Together we take on Dj’s, Photographers and Cameramen with skills and the ability required to entertain and provide the best quality service and end product. We supply Bars, Clubs and Pubs with Dj’s, Photographers, and Cameramen. We also supply for private hire and other Occasions. Our Dj’s, Photographers and Cameramen of your choice, we have handpicked the people we work with
Best content.Thank you so much for sharing,i have learnt something new.I hope you will share more information like this,keep updating.
ReplyDeleteBest Data Science Certification Course in Bangalore
ReplyDeleteL'accent est mis sur la qualité du contenu, ce que les clients recherchent et auquel ils sont attirés lorsqu'ils consultent Internet.
Sans la création & , Le WebMarketing n'est qu'un hamas de statistiques et de données argumentées. Notre Agence Webmarketing tourisme vous apporte une Visibilité ciblée sans engagement & Abordable !
Kütahya
ReplyDeleteistanbul
Çankırı
Malatya
Maraş
RAG
Bolu Lojistik
ReplyDeleteMardin Lojistik
Kocaeli Lojistik
Diyarbakır Lojistik
İstanbul Lojistik
ABOUW
D0D7F
ReplyDeleteGiresun Evden Eve Nakliyat
Kayseri Evden Eve Nakliyat
Bartın Lojistik
Muğla Evden Eve Nakliyat
Bingöl Lojistik
FE7DD
ReplyDeletehttps://referanskodunedir.com.tr/
312F5
ReplyDeletebinance
866E1
ReplyDeletevan ücretsiz sohbet uygulaması
mardin sesli sohbet
maraş tamamen ücretsiz sohbet siteleri
en iyi ücretsiz sohbet siteleri
yozgat yabancı görüntülü sohbet
canlı sohbet odaları
yalova canlı sohbet odası
rize bedava görüntülü sohbet sitesi
kütahya kızlarla rastgele sohbet
712E6
ReplyDeleteBitcoin Kazanma Siteleri
Tiktok İzlenme Hilesi
Snapchat Takipçi Hilesi
Threads İzlenme Hilesi
Bitcoin Giriş Nasıl Yapılır
Lunc Coin Hangi Borsada
Twitter Trend Topic Hilesi
Pepecoin Coin Hangi Borsada
Kripto Para Nasıl Oynanır
FD803
ReplyDeleteBinance Nasıl Oynanır
Youtube Abone Hilesi
Telegram Görüntüleme Satın Al
Parasız Görüntülü Sohbet
Soundcloud Dinlenme Hilesi
Binance Referans Kodu
Gate io Borsası Güvenilir mi
Binance Referans Kodu
Bitcoin Nasıl Kazanılır
RTHYTHJUYTJ
ReplyDeleteشركة كشف تسربات المياه بالجبيل
dfgdgbfhbfhgfjhn
ReplyDeleteشركة مكافحة حشرات بالاحساء
شركة عزل اسطح بالمدينة المنورة P8Re1XYdfW
ReplyDeleteشركة تنظيف افران بعنيزة sRXwWknmxZ
ReplyDeleteرقم المجاري بالاحساء PmTOWqZjtn
ReplyDeleteنفخ المجاري بالاحساء T5GxrphsG8
ReplyDeleteشركة عزل مواسير المياه بصفوى nD6bSfY0gR
ReplyDeleteشركة مكافحة النمل الابيض بخميس مشيط GYA5XsIOnH
ReplyDeleteشركة صيانة افران بعنيزة
ReplyDelete4LyXNwAvZ0iHM
ZUTDnJ