LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   example for netwrok packet code for creating a module and access the packet data (https://www.linuxquestions.org/questions/linux-newbie-8/example-for-netwrok-packet-code-for-creating-a-module-and-access-the-packet-data-922152/)

oracle89divi22 01-05-2012 02:04 AM

example for netwrok packet code for creating a module and access the packet data
 
i'm doing my main project and have to write a network module that could access the TCP/IP packets recieved and show the data on the user space... i have read through few books but couldnt manage to get a fullfledge example to start with... can some one help.. i need an example that could access the network packet and its data...
some data that could help me to work with... something related to netlink

theNbomr 01-05-2012 03:22 PM

In userspace, one uses socket()s to send and receive TCP/IP data. You can also send & receive raw ethernet datagrams using sockets and the Raw Sockets protocol. For a good primer on network programming in Linux, with working example C source, see Beej's Guide.

--- rod.

chrism01 01-05-2012 05:50 PM

See also the src code for the tcpdump cmd.
Classic texts @ http://www.kohala.com/start/; Try 'TCP/IP Illustrated, Volume 2: The Implementation'

oracle89divi22 01-06-2012 12:24 AM

i've tried writing with raw socket and could collect the packet but i'm not sure if its accessing all packets.... my teachers said through that i'm only getting the packets that are broadcasted...

i coulndt understand much what he meant.he asked me to search more and check if i can use netlink
my code

#include<stdio.h> //For standard things
#include<stdlib.h> //malloc
#include<string.h> //memset
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
#include<netinet/ip.h> //Provides declarations for ip header
#include<sys/socket.h>
#include<arpa/inet.h>

void ProcessPacket(unsigned char* , int);
void print_ip_header(unsigned char* , int);
void print_tcp_packet(unsigned char* , int);
void print_udp_packet(unsigned char * , int);
void print_icmp_packet(unsigned char* , int);
void PrintData (unsigned char* , int);

int sock_raw;
FILE *logfile;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
struct sockaddr_in source,dest;

int main()
{
int saddr_size , data_size;
struct sockaddr saddr;
struct in_addr in;

unsigned char *buffer = (unsigned char *)malloc(65536); //Its Big!

logfile=fopen("log.txt","w");
if(logfile==NULL) printf("Unable to create file.");
printf("Starting...\n");
//Create a raw socket that shall sniff
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
if(sock_raw < 0)
{
printf("Socket Error\n");
return 1;
}
while(1)
{
saddr_size = sizeof saddr;
//Receive a packet
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , &saddr_size);
if(data_size <0 )
{
printf("Recvfrom error , failed to get packets\n");
return 1;
}
//Now process the packet
ProcessPacket(buffer , data_size);
}
close(sock_raw);
printf("Finished");
return 0;
}

void ProcessPacket(unsigned char* buffer, int size)
{
//Get the IP Header part of this packet
struct iphdr *iph = (struct iphdr*)buffer;
++total;
switch (iph->protocol) //Check the Protocol and do accordingly...
{
case 1: //ICMP Protocol
++icmp;
//PrintIcmpPacket(Buffer,Size);
break;

case 2: //IGMP Protocol
++igmp;
break;

case 6: //TCP Protocol
++tcp;
print_tcp_packet(buffer , size);
break;

case 17: //UDP Protocol
++udp;
print_udp_packet(buffer , size);
break;

default: //Some Other Protocol like ARP etc.
++others;
break;
}
printf("TCP : %d UDP : %d ICMP : %d IGMP : %d Others : %d Total : %d\r",tcp,udp,icmp,igmp,others,total);
}

void print_ip_header(unsigned char* Buffer, int Size)
{
unsigned short iphdrlen;

struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen =iph->ihl*4;

memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iph->saddr;

memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;

fprintf(logfile,"\n");
fprintf(logfile,"IP Header\n");
fprintf(logfile," |-IP Version : %d\n",(unsigned int)iph->version);
fprintf(logfile," |-IP Header Length : %d DWORDS or %d Bytes\n",(unsigned int)iph->ihl,((unsigned int)(iph->ihl))*4);
fprintf(logfile," |-Type Of Service : %d\n",(unsigned int)iph->tos);
fprintf(logfile," |-IP Total Length : %d Bytes(Size of Packet)\n",ntohs(iph->tot_len));
fprintf(logfile," |-Identification : %d\n",ntohs(iph->id));
//fprintf(logfile," |-Reserved ZERO Field : %d\n",(unsigned int)iphdr->ip_reserved_zero);
//fprintf(logfile," |-Dont Fragment Field : %d\n",(unsigned int)iphdr->ip_dont_fragment);
//fprintf(logfile," |-More Fragment Field : %d\n",(unsigned int)iphdr->ip_more_fragment);
fprintf(logfile," |-TTL : %d\n",(unsigned int)iph->ttl);
fprintf(logfile," |-Protocol : %d\n",(unsigned int)iph->protocol);
fprintf(logfile," |-Checksum : %d\n",ntohs(iph->check));
fprintf(logfile," |-Source IP : %s\n",inet_ntoa(source.sin_addr));
fprintf(logfile," |-Destination IP : %s\n",inet_ntoa(dest.sin_addr));
}

void print_tcp_packet(unsigned char* Buffer, int Size)
{
unsigned short iphdrlen;

struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen = iph->ihl*4;

struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen);

fprintf(logfile,"\n\n***********************TCP Packet*************************\n");

print_ip_header(Buffer,Size);

fprintf(logfile,"\n");
fprintf(logfile,"TCP Header\n");
fprintf(logfile," |-Source Port : %u\n",ntohs(tcph->source));
fprintf(logfile," |-Destination Port : %u\n",ntohs(tcph->dest));
fprintf(logfile," |-Sequence Number : %u\n",ntohl(tcph->seq));
fprintf(logfile," |-Acknowledge Number : %u\n",ntohl(tcph->ack_seq));
fprintf(logfile," |-Header Length : %d DWORDS or %d BYTES\n" ,(unsigned int)tcph->doff,(unsigned int)tcph->doff*4);
//fprintf(logfile," |-CWR Flag : %d\n",(unsigned int)tcph->cwr);
//fprintf(logfile," |-ECN Flag : %d\n",(unsigned int)tcph->ece);
fprintf(logfile," |-Urgent Flag : %d\n",(unsigned int)tcph->urg);
fprintf(logfile," |-Acknowledgement Flag : %d\n",(unsigned int)tcph->ack);
fprintf(logfile," |-Push Flag : %d\n",(unsigned int)tcph->psh);
fprintf(logfile," |-Reset Flag : %d\n",(unsigned int)tcph->rst);
fprintf(logfile," |-Synchronise Flag : %d\n",(unsigned int)tcph->syn);
fprintf(logfile," |-Finish Flag : %d\n",(unsigned int)tcph->fin);
fprintf(logfile," |-Window : %d\n",ntohs(tcph->window));
fprintf(logfile," |-Checksum : %d\n",ntohs(tcph->check));
fprintf(logfile," |-Urgent Pointer : %d\n",tcph->urg_ptr);
fprintf(logfile,"\n");
fprintf(logfile," DATA Dump ");
fprintf(logfile,"\n");

fprintf(logfile,"IP Header\n");
PrintData(Buffer,iphdrlen);

fprintf(logfile,"TCP Header\n");
PrintData(Buffer+iphdrlen,tcph->doff*4);

fprintf(logfile,"Data Payload\n");
PrintData(Buffer + iphdrlen + tcph->doff*4 , (Size - tcph->doff*4-iph->ihl*4) );

fprintf(logfile,"\n###########################################################");
}

void print_udp_packet(unsigned char *Buffer , int Size)
{

unsigned short iphdrlen;

struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen = iph->ihl*4;

struct udphdr *udph = (struct udphdr*)(Buffer + iphdrlen);

fprintf(logfile,"\n\n***********************UDP Packet*************************\n");

print_ip_header(Buffer,Size);

fprintf(logfile,"\nUDP Header\n");
fprintf(logfile," |-Source Port : %d\n" , ntohs(udph->source));
fprintf(logfile," |-Destination Port : %d\n" , ntohs(udph->dest));
fprintf(logfile," |-UDP Length : %d\n" , ntohs(udph->len));
fprintf(logfile," |-UDP Checksum : %d\n" , ntohs(udph->check));

fprintf(logfile,"\n");
fprintf(logfile,"IP Header\n");
PrintData(Buffer , iphdrlen);

fprintf(logfile,"UDP Header\n");
PrintData(Buffer+iphdrlen , sizeof udph);

fprintf(logfile,"Data Payload\n");
PrintData(Buffer + iphdrlen + sizeof udph ,( Size - sizeof udph - iph->ihl * 4 ));

fprintf(logfile,"\n###########################################################");
}

void print_icmp_packet(unsigned char* Buffer , int Size)
{
unsigned short iphdrlen;

struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen = iph->ihl*4;

struct icmphdr *icmph = (struct icmphdr *)(Buffer + iphdrlen);

fprintf(logfile,"\n\n***********************ICMP Packet*************************\n");

print_ip_header(Buffer , Size);

fprintf(logfile,"\n");

fprintf(logfile,"ICMP Header\n");
fprintf(logfile," |-Type : %d",(unsigned int)(icmph->type));

if((unsigned int)(icmph->type) == 11)
fprintf(logfile," (TTL Expired)\n");
else if((unsigned int)(icmph->type) == ICMP_ECHOREPLY)
fprintf(logfile," (ICMP Echo Reply)\n");
fprintf(logfile," |-Code : %d\n",(unsigned int)(icmph->code));
fprintf(logfile," |-Checksum : %d\n",ntohs(icmph->checksum));
//fprintf(logfile," |-ID : %d\n",ntohs(icmph->id));
//fprintf(logfile," |-Sequence : %d\n",ntohs(icmph->sequence));
fprintf(logfile,"\n");

fprintf(logfile,"IP Header\n");
PrintData(Buffer,iphdrlen);

fprintf(logfile,"UDP Header\n");
PrintData(Buffer + iphdrlen , sizeof icmph);

fprintf(logfile,"Data Payload\n");
PrintData(Buffer + iphdrlen + sizeof icmph , (Size - sizeof icmph - iph->ihl * 4));

fprintf(logfile,"\n###########################################################");
}

void PrintData (unsigned char* data , int Size)
{

for(i=0 ; i < Size ; i++)
{
if( i!=0 && i%16==0) //if one line of hex printing is complete...
{
fprintf(logfile," ");
for(j=i-16 ; j<i ; j++)
{
if(data[j]>=32 && data[j]<=128)
fprintf(logfile,"%c",(unsigned char)data[j]); //if its a number or alphabet

else fprintf(logfile,"."); //otherwise print a dot
}
fprintf(logfile,"\n");
}

if(i%16==0) fprintf(logfile," ");
fprintf(logfile," %02X",(unsigned int)data[i]);

if( i==Size-1) //print the last spaces
{
for(j=0;j<15-i%16;j++) fprintf(logfile," "); //extra spaces

fprintf(logfile," ");

for(j=i-i%16 ; j<=i ; j++)
{
if(data[j]>=32 && data[j]<=128) fprintf(logfile,"%c",(unsigned char)data[j]);
else fprintf(logfile,".");
}
fprintf(logfile,"\n");
}
}
}






to execute

step 1
gcc sniffer.c -o sniffer

step 2
sudo ./sniffer


this will generate a log file


thanks for the help

theNbomr 01-06-2012 09:10 AM

Yes, using raw sockets will only receive broadcast and unicast packets. Are you trying to create a sniffer? For that you should probably use libpcap. A sniffer needs to operate the ethernet interface in promiscuous mode, meaning that it will capture all packets, irrespective of the destination MAC in the ethernet header.

--- rod.

oracle89divi22 01-09-2012 10:21 AM

i have a code thats reads and writes packets from netlink sockets.... i'm planning to modify this code to collect packets and display it on the user space but i have errors in the user program...
my code

kernel module


#include <linux/module.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>

#define NETLINK_USER 31

struct sock *nl_sk = NULL;

static void hello_nl_recv_msg(struct sk_buff *skb) {

struct nlmsghdr *nlh;
int pid;
struct sk_buff *skb_out;
int msg_size;
char *msg="Hello from kernel";
int res;

printk(KERN_INFO "Entering: %s\n", __FUNCTION__);

msg_size=strlen(msg);

nlh=(struct nlmsghdr*)skb->data;
printk(KERN_INFO "Netlink received msg payload: %s\n",(char*)nlmsg_data(nlh));
pid = nlh->nlmsg_pid; /*pid of sending process */

skb_out = nlmsg_new(msg_size,0);

if(!skb_out)
{

printk(KERN_ERR "Failed to allocate new skb\n");
return;

}
nlh=nlmsg_put(skb_out,0,0,NLMSG_DONE,msg_size,0);
NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */
strncpy(nlmsg_data(nlh),msg,msg_size);

res=nlmsg_unicast(nl_sk,skb_out,pid);

if(res<0)
printk(KERN_INFO "Error while sending bak to user\n");

}

static int __init hello_init(void)
{
printk("Entering: %s\n",__FUNCTION__);
nl_sk=netlink_kernel_create(&init_net, NETLINK_USER, 0, hello_nl_recv_msg,NULL, THIS_MODULE);
if(!nl_sk)
{

printk(KERN_ALERT "Error creating socket.\n");
return -10;

}

return 0;

}

static void __exit hello_exit(void) {

printk(KERN_INFO "exiting hello module\n");
netlink_kernel_release(nl_sk);

}

module_init(hello_init); module_exit(hello_exit);

MODULE_LICENSE("GPL");




user program



#include <sys/socket.h>
#include <linux/netlink.h>

#define NETLINK_USER 31

#define MAX_PAYLOAD 1024 /* maximum payload size*/
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
struct msghdr msg;

int main()
{
sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
if(sock_fd<0)
return -1;

memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid(); /* self pid */

bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));

memset(&dest_addr, 0, sizeof(dest_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; /* For Linux Kernel */
dest_addr.nl_groups = 0; /* unicast */

nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = getpid();
nlh->nlmsg_flags = 0;

strcpy(NLMSG_DATA(nlh), "Hello");

iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;

printf("Sending message to kernel\n");
sendmsg(sock_fd,&msg,0);
printf("Waiting for message from kernel\n");

/* Read message from kernel */
recvmsg(sock_fd, &msg, 0);
printf("Received message payload: %s\n", NLMSG_DATA(nlh));
close(sock_fd);
return 0;
}



errors
gcc user.c -o user
user.c: In function ‘main’:
user.c:21: warning: incompatible implicit declaration of built-in function ‘memset’
user.c:33: warning: incompatible implicit declaration of built-in function ‘malloc’
user.c:39: warning: incompatible implicit declaration of built-in function ‘strcpy’
user.c:48: warning: incompatible implicit declaration of built-in function ‘printf’
user.c:54: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘void *’


can someone help me resolve these

chrism01 01-09-2012 07:07 PM

You haven't #include'd the .h files that define those fns :)

oracle89divi22 01-10-2012 01:45 AM

thanks chrism01 i did that and it has resolved most of the errors i had.... i executed it successfully along with a warning but now the state is that the socket is not being created am i doing anything wrong please check

sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);

if(sock_fd<0)
return -1;

the control goes into the if loop immediately after executing the socket statement...plz help urget..

the error i found is some casting problem in

printf("Received message payload: %s\n", NLMSG_DATA(nlh));


error is
socket invaliddivya@divya:~$ gcc user.c -o user
user.c: In function ‘main’:
user.c:56: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘void *’

theNbomr 01-10-2012 09:33 AM

Since you are using raw socket protocol, you must have root privileges. Not having that would explain the failure to create a socket. You should be able to get rid of the compiler warning by casting the void pointer argument to a char *.

--- rod.

oracle89divi22 01-10-2012 12:11 PM

nombr i've corrected the code and made it execute fine... this now sends data from kernel to the userspace...:-) nw all i need to do is catch hold of packets from the TCP/ip stack and send those from kernel to userspace can you explain what can i do for that to happen..

thanks in advance..

i got this output in the var/log/messages file

Entering: hello_init
Entering: hello_nl_recv_msg
Netlink received msg payload: Hello

theNbomr 01-10-2012 01:32 PM

Sorry, I didn't notice you were working in kernel space. I think you have to short-circuit the TCP/IP stack, since that layer will only capture IP packets. I have no idea ho to accomplish any of what you're doing, but I do question why you need/want to do any of it in kernel space. Sniffers work just fine in userspace, as long as they get sufficient privileges.

--- rod.

oracle89divi22 01-10-2012 08:57 PM

basically my main project is to develop a kernel rootkit and hence capture packets from kernel as i've to capture all packets passing through and send these to user space

i met sir today he asked me to use netfilter hooks can someone help me where i can find a fast learning tutorial or a code as i've to complete this part of my project by tomorrow morning 9am....

really urgent....:-(

TB0ne 01-13-2012 09:17 AM

Quote:

Originally Posted by oracle89divi22 (Post 4571467)
basically my main project is to develop a kernel rootkit and hence capture packets from kernel as i've to capture all packets passing through and send these to user space

i met sir today he asked me to use netfilter hooks can someone help me where i can find a fast learning tutorial or a code as i've to complete this part of my project by tomorrow morning 9am....

really urgent....:-(

You want to develop a rootkit, and are asking for HELP? And, you've posted the same question in about five different threads, some of which are 9 years old.

Tinkster 01-13-2012 04:27 PM

Thread re-opened as it was clarified that this is in fact
not about a root-kit.


All times are GMT -5. The time now is 04:59 AM.