Network Driver doesn't work

Hello,

I am writing experimental network driver. The driver pretends to be for
ethernet compatible hardware with ethernet MAC adresses, but actually
transmits data through the com ports. Driver starts succesfully, advertises
himself as broadcast, multicast, simplex compatible. Then I set up the
corresponding IP addresses
to the connected hosts : 192.168.0.1 and 192.168.0.2. MAC addresses are
hardcoded for both of them - bb:bb:bb:bb:bb:aa, bb:bb:bb:bb:bb:bb. Then I do
telnet from 0.2 to 0.1 and io-net passes to my driver normal broadcast IP
address request arp packet. I receive on the other side of the wire that arp
packet and pass it up to the io-net. Everything seems ok till this point.
But the problem is that io-net doesn’t responds to that packet it simply
does nothing. The connection timeouts.
Can anyone have any idea what’s wrong? I give the advertising and init
functions source for analysis, maybe i’m missing some registration function
??
Thanks in advance,

Arunas

Arp packet dump:
0xff 0xff 0xff 0xff 0xff 0xff 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0x8 0x6 0x0 0x1
0x8 0x0 0x6 0x4 0x0 0x1 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0xc0 0xa8 0x0 0x2 0x0
0x0 0x0 0x0 0x0 0x0 0xc0 0xa8 0x0 0x1

// advertising function
int devicecc_advertise(int reg_hdl, void *func_hdl)
{
npkt_t *npkt;
net_buf_t *nb;
net_iov_t *iov;
Nic_t *nic;
devicecc_ext_t *ext;
io_net_msg_dl_advert_t *ap;


nic = (Nic_t *)(func_hdl);
ext = (devicecc_ext_t *) nic->ext;

printf(“In advertise1\n”);
fflush(stdout);

npkt = ion_alloc_npkt( sizeof(*nb) + sizeof *iov, (void **)&nb );
if( npkt == NULL )
{
return 0;
}

printf(“In advertise2\n”);
fflush(stdout);

ap = ion_alloc(sizeof(*ap), 0);
if( ap == NULL)
{
ion_free(npkt);
return 0;
}
printf(“In advertise3\n”);
fflush(stdout);

TAILQ_INSERT_HEAD(&npkt->buffers, nb, ptrs);

iov = (net_iov_t *)(nb + 1);

nb->niov = 1;
nb->net_iov = iov;
iov->iov_base = ap;
iov->iov_len = sizeof *ap;

printf(“In advertise4\n”);
fflush(stdout);

memset(ap, 0x00, sizeof *ap);
ap->type = _IO_NET_MSG_DL_ADVERT;

ap->iflags = (IFF_SIMPLEX | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST );

ap->mtu_min = PACKET_SIZE;
ap->mtu_max = PACKET_SIZE; //nic->mtu;
ap->mtu_preferred = PACKET_SIZE; //nic->mtu;
strcpy(ap->up_type, “en”);
itoa(nic->lan, ap->up_type + 2, 10);

printf(“In advertise5\n”);
fflush(stdout);

strcpy(ap->dl.sdl_data, ap->up_type);

ap->dl.sdl_len = sizeof(struct sockaddr_dl);
ap->dl.sdl_family = AF_LINK;
ap->dl.sdl_index = nic->lan;
ap->dl.sdl_type = IFT_ETHER;
ap->dl.sdl_nlen = strlen(ap->dl.sdl_data); /* not null terminated */
ap->dl.sdl_alen = 6;
memcpy(ap->dl.sdl_data + ap->dl.sdl_nlen, nic->current_address, 6);

npkt->org_data = ap;
npkt->flags |= _NPKT_MSG;
npkt->iface = 0;
npkt->framelen = sizeof *ap;
printf(“In advertise6\n”);
fflush(stdout);

if( ion_add_done( ext->reg_hdl, npkt, nic ) == -1)
{
ion_free(ap);
ion_free(npkt);
return(0);
}
printf(“In advertise7\n”);
fflush(stdout);

if(ion_rx_packets(ext->reg_hdl, npkt, 0, 0, ext->cell, nic->lan, 0) == 0)
{
ion_tx_complete(ext->reg_hdl, npkt);
}

return(0);
}

// init file source

#include <devicecc.h>

extern io_net_registrant_t deviceccEntry;

static void devicecc_init_stop_threads( Nic_t *nic )
{
devicecc_ext_t *ext;

ext = (devicecc_ext_t *)nic->ext;
if( ext->rx_tid > 0 )
{
pthread_cancel( ext->rx_tid );
}
if( ext->tx_tid > 0 )
{
pthread_cancel( ext->tx_tid );
}
}


static int devicecc_init_start_threads( Nic_t *nic )
{
devicecc_ext_t *ext;
pthread_attr_t rx_attr;
pthread_attr_t tx_attr;
struct sched_param rx_param, tx_param;
int ret;

ext = (devicecc_ext_t *)nic->ext;

pthread_attr_init( &rx_attr );
pthread_attr_setschedpolicy( &rx_attr, SCHED_RR );
rx_param.sched_priority = RECEIVE_THREAD_PRIORITY;
pthread_attr_setschedparam( &rx_attr, &rx_param );
pthread_attr_setinheritsched( &rx_attr, PTHREAD_EXPLICIT_SCHED );

pthread_attr_init( &tx_attr );
pthread_attr_setschedpolicy( &tx_attr, SCHED_RR );
tx_param.sched_priority = TRANSMIT_THREAD_PRIORITY;
pthread_attr_setschedparam( &tx_attr, &tx_param );
pthread_attr_setinheritsched( &tx_attr, PTHREAD_EXPLICIT_SCHED );


ext->chid = ChannelCreate( _NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK );
if( ext->chid == -1 )
{
slogf( _SLOGC_NETWORK, _SLOG_ERROR, “devn-devicecc: Unable to create
channel” );
devicecc_init_stop_threads( nic );
return -1;
}

ext->coid = ConnectAttach( 0, 0, ext->chid, _NTO_SIDE_CHANNEL, 0 );
if( ext->coid == -1 )
{
slogf( _SLOGC_NETWORK, _SLOG_ERROR, “devn-devicecc: Unable to create
connection” );
devicecc_init_stop_threads( nic );
return -1;
}

ret = pthread_create( &ext->rx_tid, &rx_attr, (void
*)devicecc_receive_thread, nic );
if( ret )
{
slogf( _SLOGC_NETWORK, _SLOG_ERROR, “devn-devicecc: Unable to create
interface thread (receive)” );
devicecc_init_stop_threads( nic );
return -1;
}

ret = pthread_create( &ext->tx_tid, &tx_attr, (void
*)devicecc_transmit_thread, nic );
if( ret )
{
slogf( _SLOGC_NETWORK, _SLOG_ERROR, “devn-devicecc: Unable to create
interface thread (transmit)” );
devicecc_init_stop_threads( nic );
return -1;
}

return EOK;
}


static int devicecc_init_register_device( Nic_t *nic )
{
devicecc_ext_t *ext;
uint16_t lan;
int ret;

ext = (devicecc_ext_t *)nic->ext;

if( ext->verbose )
{
nic_display_config( nic );
}

deviceccEntry.func_hdl = (void *) nic;

ret = ion_register( ext->dll_hdl, &deviceccEntry, &ext->reg_hdl,
&ext->cell, &lan );
if( ret != EOK )
{
return ret;
}

nic->lan = lan;

if (!ext->max_pkts)
{
ext->max_pkts = 100;
}

ext->ion->devctl( ext->reg_hdl, DCMD_IO_NET_MAX_QUEUE, &ext->max_pkts,
sizeof(ext->max_pkts), NULL);

/* Successful Registration!!! */
return( 0 );
}


static int devicecc_init_start_driver( void *dll_hdl, io_net_self_t *ion,
devicecc_args_t *args )
{
int ret;
Nic_t *nic;
devicecc_ext_t *ext;
struct Config_Info *cfg;

nic = nic_create_dev( sizeof( devicecc_ext_t ) );
if( nic == NULL )
{
return ENODEV;
}

ext = (devicecc_ext_t*)nic->ext;
cfg = (struct Config_Info *)&nic->cfg;

/* Store these for use later */
ext->ion = ion;
ext->dll_hdl = dll_hdl;

/* Get all the arguments in args.nic copied over */
memcpy( nic, &args->nic, sizeof( Nic_t ) );
nic->ext = ext;

/* Store args we care about into the driver handle */
ext->verbose = args->verbose;
ext->device = args->device;

strcpy( cfg->Description, “DEVICE THROUGH CC” );
nic->media = NIC_MEDIA_CUSTOM;
nic->mac_length = ETH_MAC_LEN;
nic->phy = PHY_NOT_INSTALLED;

nic->mtu = PACKET_SIZE;

nic->permanent_address[0] = 0xBB;
nic->permanent_address[1] = 0xBB;
nic->permanent_address[2] = 0xBB;
nic->permanent_address[3] = 0xBB;
nic->permanent_address[4] = 0xBB;
nic->permanent_address[5] = 0xBB;
nic->permanent_address[6] = 0xBB;
nic->permanent_address[7] = 0xBB;
nic->current_address[0] = 0xBB;
nic->current_address[1] = 0xBB;
nic->current_address[2] = 0xBB;
nic->current_address[3] = 0xBB;
nic->current_address[4] = 0xBB;
nic->current_address[5] = 0xBB;
nic->current_address[6] = 0xBB;
nic->current_address[7] = 0xBB;

if ( ext->device == 1 )
{
ext->fd = open("/dev/ser2", O_RDWR);
} else if ( ext->device == 2 )
{
ext->fd = open("/dev/ser2", O_RDWR);
} else
ext->fd = open("/dev/ser1", O_RDWR);

if (ext->fd == -1)
{
printf(“SER2 not found\n”);
errno = ENODEV;
return -1;
}

ret = devicecc_init_start_threads( nic );
if( ret )
{
slogf( _SLOGC_NETWORK, _SLOG_ERROR, “devn-devicecc: Unable to start driver
threads.” );
return ENODEV;
}

devicecc_reset( nic );

ret = devicecc_init_register_device( nic );

if( ret )
{
slogf( _SLOGC_NETWORK, _SLOG_ERROR, “devn-devicecc: Unable to register
device.” );

devicecc_init_stop_threads( nic );

return ENODEV;
}

devicecc_advertise( ext->reg_hdl, nic );
return EOK;
}


int devicecc_init( void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char
*options )
{
devicecc_args_t args;
int ret;

slogf( _SLOGC_NETWORK, _SLOG_INFO, “Init begin execution” );

memset( args, 0, sizeof( devicecc_args_t ) );
ret = devicecc_init_start_driver( dll_hdl, ion, &args );

if( ret == EOK )
{
slogf( _SLOGC_NETWORK, _SLOG_INFO, “Driver started succesfully” );
return 0;
}
else {
errno = ENODEV;
return -1;
}
}

P.S. reset function does nothing.

hardcoded for both of them - bb:bb:bb:bb:bb:aa, bb:bb:bb:bb:bb:bb.

in binary 10111011:10111011 etc.

I haven’t bothered to look at your code but be aware that ethernet addresses
with the low-order bit of the first byte set indicates a multicast address
rather than a plain old machine address. It might be wise to recode these
addresses with that low-order bit cleared and see what happens then. This
might not be the complete answer but at least one of the unknowns is out of
the equation.

Poseidon

This is right, thanks, i’ve fixed it. But the driver still doesn’t work. (I
gave it the address of real card which I have :slight_smile:

Arunas

“Poseidon” <paul.ryan2@nospam.virgin.net> wrote in message
news:9prq4a$2hd$1@nntp.qnx.com

hardcoded for both of them - bb:bb:bb:bb:bb:aa, bb:bb:bb:bb:bb:bb.

in binary 10111011:10111011 etc.

I haven’t bothered to look at your code but be aware that ethernet
addresses
with the low-order bit of the first byte set indicates a multicast address
rather than a plain old machine address. It might be wise to recode these
addresses with that low-order bit cleared and see what happens then. This
might not be the complete answer but at least one of the unknowns is out
of
the equation.

Poseidon

Hi,
I want to know how a network driver works in QNX. I want to know about
the interaction between the Driver handler, Driver Interface and the Device
driver. What are their responsibilities ?? Do network drivers and handler
deal with the same set of 3 queues as other drivers do ???
Please suggest me any document or page where i can get hold of these
issues…
Thanking in advance…
Regards…
Sudip.