How do I develop a Network Packet Sniffer?

Hello everyone, I’m a newbie on this forum.
Before posting this message, I’ve had some days to research how to develop a Network Packet Sniffer. But at this time, I cannot have any solutions to do it. Please help me for a while.
My questions are:

  1. How do I develop a Packet Sniffer? What steps do I follow to do it?

  2. As I know, there are a “netsniff” utility on QNX RTOS, but I cant see it anywhere? (I’m using QNX 6.3 with SP2).

Thank you very much for your consideration on this message.

Hello everyone,
Is there anybody, help me please. Thanks a lot.

You probably need network DDK
openqnx.com/PNphpBB2-viewtopic-t6661-.html
openqnx.com/PNphpBB2-viewtopic-t7170-.html

Thank you for your help, but I still do not understand how to begin. Can you help me a bit more.
I think there are 2 solutions for my Packet Sniffer application:

  1. Packet Sniffer application (PS application) will commmunicate with TCP/TP stack npm-tcpip.so by Socket API to get all packets which are stored in TCP/IP stack queue.

PS pplication <-----Socket API-----> npm-tcpip.so <----> en

If this solution is feasible, my question is :

  • how to use Socket API to commmunicate with npm-tcpip.so because in QNX there’s no option PF_PACKET as Linux to intercept all raw packets.
  1. I must write a new stack likes TCP/IP stack npm-tcpip.so, named my-stack.so. This stack will get all raw packets from network card device and send it to PS application.

PS pplication <----> my-stack.so <----> en

If this solution is feasible, my question is :

  • which protocol should I use to establish the communication between SS application and my-stack.so
  • how to know my-stack.so works properly after it is loaded by mount -Tio-net because I cannot print out any text to console although my-stack.so is loaded with no errors and I already use “printf” many times in the my-stack.so source code.

That’s all of my ideas, but I still do not assert which solution is feasible. Please give me some advices. Thank you for your consideration to this message

Option 2 is the way to do it. The only “protocol” you will use between “en” and your code is ethernet packet framing, and since (presumably) a “sniffer” is unidirectional (read) only, you simply need to be aware that there will be an ethernet header at the front of the data.

Rennie

Hi Rennie,
Thank you very much for your help. And, if you have any free time, please help me take a look at this message.

I wrote a simple sniffer named “nfm-filter.so”. The source codes as below:

[color=red]#include <stdio.h>
#include <errno.h>
#include <sys/io-net.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

static int filter_init(void *dll_hdl, dispatch_t *dpp, io_net_self_t *n, char *options);
static int filter_destroy(void *dll_hdl);
static int filter_rx_up(npkt_t *npkt, void *func_hdl, int off, int len_sub, uint16_t cell, uint16_t endpoint, uint16_t iface);
static int filter_rx_down(npkt_t *npkt, void *rx_down_hdl);
static int filter_tx_done(npkt_t *npkt, void *done_hdl, void *func_hdl);
static int filter_shutdown1(int registrant_hdl, void *func_hdl);
static int filter_shutdown2(int registrant_hdl, void *func_hdl);

int counter_UP = 0;
int counter_DOWN = 0;

io_net_dll_entry_t io_net_dll_entry = {
2,
filter_init,
filter_destroy
};

static io_net_registrant_funcs_t filter_funcs = {
_IO_NET_REG_NFUNCS,
filter_rx_up,
filter_rx_down,
filter_tx_done,
filter_shutdown1,
filter_shutdown2,
NULL,
NULL,
NULL,
NULL,
NULL
};

static io_net_registrant_t filter_reg = {
_REG_FILTER_ABOVE,
“nfm-filter.so”,
“en”,
“en”,
NULL,
&filter_funcs,
0
};

void * filter_dll_hdl;
dispatch_t * filter_dpp;
io_net_self_t * filter_ion;
int filter_reg_hdl;

///

static int filter_init(void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char *options)
{
filter_dll_hdl = dll_hdl;
filter_ion = ion;
filter_dpp = dpp;

if(filter_ion->reg(filter_dll_hdl, &filter_reg, &filter_reg_hdl, NULL, NULL) == -1)
{
	fprintf(stderr, "\nreg-ERROR ");	
	return (-1);
}

fprintf(stderr, "\ninit-OK reg_hdl=%d ",filter_reg_hdl);
return EOK;

}

///

static int filter_destroy(void *dll_hdl)
{
fprintf(stderr, "\ndestroy ");
return EOK;
}

///

static int filter_rx_up(npkt_t *npkt, void *func_hdl, int off, int len_sub, uint16_t cell, uint16_t endpoint, uint16_t iface)
{
counter_UP += 1;
fprintf(stderr, "\npkt_UP reg_hdl=%d (%d), framelen = %d ",filter_reg_hdl,counter_UP, npkt->framelen);

if( filter_ion->tx_up(filter_reg_hdl, npkt, off, len_sub, cell, endpoint, iface) <= 0 )
filter_ion->tx_done(filter_reg_hdl, npkt);

return 0;

}

///

static int filter_rx_down(npkt_t *npkt, void *rx_down_hdl)
{
counter_DOWN += 1;
fprintf(stderr, "\npkt_DOWN reg_hdl=%d (%d) ",filter_reg_hdl,counter_DOWN);

return filter_ion->tx_down(filter_reg_hdl, npkt);

}

///

static int filter_tx_done(npkt_t *npkt, void *done_hdl, void *func_hdl)
{
fprintf(stderr, “\nfilter_tx_done”);
return 0;
}

///

static int filter_shutdown1(int registrant_hdl, void *func_hdl)
{
fprintf(stderr, “\nfilter_shutdown1”);
return EOK;
}

///

static int filter_shutdown2(int registrant_hdl, void *func_hdl)
{
fprintf(stderr, “\nfilter_shutdown2”);
return 0;
}

After building “nfm-filter.so” successfully, I copy it into “/lib/dll” and use “mount” command to load it:

[color=red]mount -T io-net nfm-filter.so

Everything is done with no errors.
Then, I use “pidin” command to check whether it has been loaded

[color=red]pidin -P io-net mem

and the output is:

[color=red]# pidin -P io-net mem
pid tid name prio STATE code data stack
86032 1 sbin/io-net 10o SIGWAITINFO 64K 508K 8192(516K)*
86032 2 sbin/io-net 10o RECEIVE 64K 508K 4096(68K)
86032 3 sbin/io-net 10o RECEIVE 64K 508K 4096(68K)
86032 4 sbin/io-net 10o RECEIVE 64K 508K 4096(68K)
86032 5 sbin/io-net 20o RECEIVE 64K 508K 4096(132K)
86032 6 sbin/io-net 21o RECEIVE 64K 508K 4096(132K)
86032 7 sbin/io-net 10o RECEIVE 64K 508K 4096(68K)
ldqnx.so.2 @b0300000 348K 20K
npm-tcpip.so @b8200000 276K 28K
devn-speedo.so @b824c000 40K 4096
nfm-filter.so @b8257000 4096 4096

It means the nfm-filter was loaded successfully. [color=red]BUT, I don’t understand what happens: I never see any output text, although I already use “printf” in each function. How can I know the “nfm-filter.so” registered successfully? And, how can I know when the function “filter_rx_up” called?

Please forgive me if my questions are stupid, I have just read the Network DDK for some days.
Thank you very much for your consideration.
Quadie.

Hello Quadie,

io-net, when startet from the device enumerator, doesn’t display anything that you printed to stdout or stderr.

You have to manually start io-net on the command line to see all the outputs. Open a terminal and do:

slay io-net
io-net -dspeedo -ptcpip
netmanager # This will configure your network subsystem according to /etc/net.cfg
mount -Tio-net nfm-filter.so

Hope that helps,

Albrecht

Hello Albrecht,
You’re an expert in QNX. I can see the output now.
Thank you very much for your help.
Quadie.