io-net component (need help)

Hi
We need to handle the network traffic (incomming and outgoing) between
Ethernet driver and TCP/IP stack.
We have a stack (tcp/ip sim) that need to intercept UDP + ARP packets
and process/or pass the packet to our application if it belong to us
, otherwise pass to QNX TCP/IP stack.
Our application should be able to transmit packet though tcp/ip sim
stack. (this stack can take care of ethernet header for Desired setup
1 before send down)
Is it possible to write something similar to a filter that can sit
between an en and a converter.?

The traditional setup:

client application
||
TCP/IP
||
en<->ip converter
||
en


Desired setup 1:

|| TCP/IP || en<->ip converter || tcp/ip sim ===================== || en \ \ or Desired setup 2: \ \ || TCP/IP ||

tcp/ip sim ================
||
en<->ip converter
||
en



Can we do that ?.
Please give us some hint.

Thanks,
VanChi

Setup number 1 is more generic and certainly possible. You
would write a module of type _REG_FILTER_ABOVE handling
packets of type “en”. Packets you don’t want to go to
the stack you would simply call (io_net_self_t *)->tx_done()
on, possibly passing them out to your external app beforehand.

Regards,

-seanb

vanchi <n_vanchi@hotmail-dot-com.no-spam.invalid> wrote:

Hi
We need to handle the network traffic (incomming and outgoing) between
Ethernet driver and TCP/IP stack.
We have a stack (tcp/ip sim) that need to intercept UDP + ARP packets
and process/or pass the packet to our application if it belong to us
, otherwise pass to QNX TCP/IP stack.
Our application should be able to transmit packet though tcp/ip sim
stack. (this stack can take care of ethernet header for Desired setup
1 before send down)
Is it possible to write something similar to a filter that can sit
between an en and a converter.?

The traditional setup:

client application
||
TCP/IP
||
en<->ip converter
||
en



Desired setup 1:

client application
||
TCP/IP
||
en<->ip converter
||
tcp/ip sim ===================== <our application
||
en



or Desired setup 2:



client application
||
TCP/IP
||

tcp/ip sim ================ <our application
||
en<->ip converter
||
en



Can we do that ?.
Please give us some hint.

Thanks,
VanChi

Hello Sean.
Thanks for your help.

  1. Does the filter module require function rx_down()
    (io_net_registrant_funcs_t) defined. Can we simply set rx_down to
    NULL (let io-net take care of outgoing traffic between qnx tcp/ip
    stack and en) and handle the outgoing traffic between our stack and
    en, .
  2. Can io-net handle multiple filters ? (later, if we wish to use
    other filter such as IP filter, will it cause some conflic ?). I
    believe lsm-ipfilter is also an a module of type _REG_FILTER_ABOVE.

Thanks,
VanChi.

vanchi <n_vanchi@hotmail-dot-com.no-spam.invalid> wrote:

Hello Sean.
Thanks for your help.

  1. Does the filter module require function rx_down()
    (io_net_registrant_funcs_t) defined. Can we simply set rx_down to
    NULL (let io-net take care of outgoing traffic between qnx tcp/ip
    stack and en) and handle the outgoing traffic between our stack and
    en, .

Yes. Packets on the way down will need to pass through your
filter.

  1. Can io-net handle multiple filters ? (later, if we wish to use
    other filter such as IP filter, will it cause some conflic ?). I
    believe lsm-ipfilter is also an a module of type _REG_FILTER_ABOVE.

Filters can be stacked.

Thanks,
VanChi.

Hi
I try to create a simple filter (nfm-ftsim.so) using
build command:
qcc -I /usr/include -shared filtersim.c -o nfm-ftsim.so

I always got error when using command mount to load this filter.

mount -vvvv -Tio-net nfm-ftsim.so

Parsed: mount from [nfm-ftsim.so] mount on [NULL] type
exec: mount_io-net -o implied -o nostat nfm-ftsim.so /
Using internal mount (mount_io-net not found)
Type [io-net] Flags 0x80080000
Device [nfm-ftsim.so] Directory [/]
Options []
mount: Can’t mount / (type io-net)
mount: Possible reason: No such device or address

Could you tell me more about error ? Please. How to fix it.?
Thanks
VanChi.

Try specifying the full path to your filter:

mount -T io-net /full/path/to/nfm-ftsim.so

-seanb

vanchi <n_vanchi@hotmail-dot-com.no-spam.invalid> wrote:

Hi
I try to create a simple filter (nfm-ftsim.so) using
build command:
qcc -I /usr/include -shared filtersim.c -o nfm-ftsim.so

I always got error when using command mount to load this filter.

mount -vvvv -Tio-net nfm-ftsim.so

Parsed: mount from [nfm-ftsim.so] mount on [NULL] type
exec: mount_io-net -o implied -o nostat nfm-ftsim.so /
Using internal mount (mount_io-net not found)
Type [io-net] Flags 0x80080000
Device [nfm-ftsim.so] Directory [/]
Options []
mount: Can’t mount / (type io-net)
mount: Possible reason: No such device or address

Could you tell me more about error ? Please. How to fix it.?
Thanks
VanChi.

Hi Seanb.
I did try it, same problem. same error.

Here’s the source, quite simple.

#include <sys/io-net.h>
#include “filtersim.h”


io_net_dll_entry_t io_net_dll_entry = {
2,
ftsim_init,
ftsim_destroy };

static io_net_registrant_funcs_t ftsim_funcs = {
_IO_NET_REG_NFUNCS,
ftsim_rx_up,
ftsim_rx_down,
ftsim_tx_done,
ftsim_shutdown1,
ftsim_shutdown2,
NULL,
NULL,
NULL,
NULL,
NULL };

static io_net_registrant_t ftsim_reg = {
_REG_FILTER_ABOVE,
“nfm-ftsim.so”,
“en”,
“en”,
NULL,
&ftsim_funcs,
0
};

ftsim_Ext_t fts_cp;

// entry from io-net
static int ftsim_init( void *dll_hdl, dispatch_t *dpp, io_net_self_t
*ion, char *options)
{
ftsim_Ext_t *pfts_cp = &fts_cp;

memset(pfts_cp, 0, sizeof(*pfts_cp));
pfts_cp->dll_hdl = dll_hdl;
pfts_cp->dpp = dpp;
pfts_cp->ion = ion;


printf(“ftsim_init \n”);
if(ion->reg(dll_hdl, &ftsim_reg, &pfts_cp->reg_hdl,
&pfts_cp->cell, &pfts_cp->endpoint) == -1) {
return(-1);
}

return EOK;
}

I found the problem. have to copy the nfm-ftsim to /lib/dll/ . No need
to specify the full path.
Thanks Seanb.
VanChi.

Vanchi or Seanb,

I’m having the same problem that you had (mount telling me “No such
device or address.” However, in my case the file is copied in
/lib/dll.

I think this may be related to the io_net_registrant_t stucture not
being set properly. I’m not sure about the values I should set for
top_type and bot_type. Here is how I set i:

static io_net_registrant_t EtherRaw_reg =
{
_REG_FILTER_ABOVE,
“nfm-en.so”,
“en”,
NULL,
NULL,
&EtherRaw_funcs,
0
};

Thank you,
Martin Fillion

A _REG_FILTER_ABOVE must have top_type == bot_type. If you
want to filter ethernet packets, they should both be “en”.
It must also have both rx_up and rx_down functions defined.

-seanb

mfillion <mfillion@mechtronix-dot-ca.no-spam.invalid> wrote:

Vanchi or Seanb,

I’m having the same problem that you had (mount telling me “No such
device or address.” However, in my case the file is copied in
/lib/dll.

I think this may be related to the io_net_registrant_t stucture not
being set properly. I’m not sure about the values I should set for
top_type and bot_type. Here is how I set i:

static io_net_registrant_t EtherRaw_reg =
{
_REG_FILTER_ABOVE,
“nfm-en.so”,
“en”,
NULL,
NULL,
&EtherRaw_funcs,
0
};

Thank you,
Martin Fillion

Hello everyone in this topic,
I’m developing a packet sniffer application and I’ve researched on the
QNX forum for a week but I still do not understand how to begin.
I think there are 2 solutions for my application, but I cannot be sure
which is wrong and which is feasible.

  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.

Hi Qadie!

On Mon, 06 Mar 2006 05:49:29 +0000, Quadie wrote:

Hello everyone in this topic,
I’m developing a packet sniffer application and I’ve researched on the
QNX forum for a week but I still do not understand how to begin.
I think there are 2 solutions for my application, but I cannot be sure
which is wrong and which is feasible.

There’s quite a good documentation under

http://www.qnx.com/developers/docs/momentics621_docs/ddk_en/
network/writing.html#SampleRegistration

This was, at least for us, very helpful to write our own network
protocol DLL.

HTH,

Karsten.

Hi Karsten,
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:

#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=blue:43f1b090f4]mount -T io-net
nfm-filter.so[/color:43f1b090f4]

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

[color=blue:43f1b090f4]pidin -P io-net mem[/color:43f1b090f4]

and the output is:

[color=blue:43f1b090f4]# 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
[/color:43f1b090f4]
It means the nfm-filter was loaded successfully.
[color=blue:43f1b090f4]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?
[/color:43f1b090f4]
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.

Hi Quadie.
By default, io-net will not output message.
try the following step before doing a mount.
#DL_DEBUG=1
#mount -Tio-net nfm-filter.so

If not working then you may need to kill io-net (you find out how
network driver and protocol are loaded by io-net at startup).
#slay io-net
#io-net -d your_network_driver.so -p your_protocol.so
#netmanager
#mount -Tio-net nfm-filter.so