Hello,

I just joined the list because I got a tip that you are
discussing this 'buggy message' thing from the kernel.

I'm building an APRS digipeater (DIGI_NED) and I get
complaints about these messages too from my users. I'm
running RH 5.2 with 2.0.36 so I can not realy debug it
since this 'buggy' thing only shows up in the new kernel.

---------------------------------------------------------------
On Tue, Jun 27, 2000 at 09:53:05AM +0200, Joerg Reuter wrote: 

> I'll take a look where it happens. 

Strange, I cannot find a reason for this behaviour. At least 
skb->protocol gets set correctly in all places. We either 
have memory corruption here or a weird race condition. I've 
observed the same messages with 'listen' running, thus it's not 
'ax25digi' causing it. There are reports for this happening with 
_every_ AX.25 network device driver, hence it isn't the mkiss 
driver. Weird. 

vy 73, 
        Joerg 
---------------------------------------------------------------

I did some searching on the Internet before and got the impression
that the problem was in af_packet. I assume ax25digi will also use
raw packets, just like DIGI_NED and just like net2kiss. Also listen
uses raw packets - but only reception and I strongly suspect that
transmission of raw packets causes this.

I can show you how I open the sockets and send/receive the packets.
I stole the principal from the 'net2kiss' code of the AX.25 utils.

1) Opening the socket for reception and transmission
---------------------------------------------------------------
/*
 * Initialize access to MAC layer
 *
 * returns: 0 if MAC layer cannot be found
 *          1 if MAC layer is found in memory
 */
short init_mac(void)
{
    struct sockaddr  sa;
    ports_t         *prt_p;
    short            i;

    /* general startup, done once */
    if (ax25_config_load_ports() == 0) {
        say("ERROR: problem with axports file\r\n");
        return 0;
    }

    /* convert axport to device and open transmitter sockets */
    for(i = 0; i < lnx_port_nr; i++)
    {
        prt_p = &(lnx_port[i]);

        if ((prt_p->dev_p = ax25_config_get_dev(prt_p->port_p)) == NULL)
        {
            say("ERROR: invalid port name - %s\r\n", prt_p->port_p);
            return 0;
        }

        /* do transmitter side */
        prt_p->s_out = socket(PF_INET, SOCK_PACKET, htons(ETH_P_AX25));
        if (prt_p->s_out < 0)
        {
            perror("tx socket");
            return 0;
        }

        bzero(&sa,sizeof(struct sockaddr));
        strcpy(sa.sa_data, prt_p->dev_p);
        sa.sa_family = AF_INET;
        if (bind(prt_p->s_out, &sa, sizeof(struct sockaddr)) < 0)
        {
            perror("bind");
            close(prt_p->s_out);
            return 0;
        }
    }

    /* open receive socket, one receiver will do for al ports  */
    /*
     * Use ETH_P_AX25 because with PF_AX25 we also will read the data
     * that we transmit ourselfs, that's useless!
     */
    lnx_s_in = socket(PF_INET, SOCK_PACKET, htons(ETH_P_AX25));
    if (lnx_s_in < 0)
    {
        perror("rx socket");
        return 0;
    }

    return 1;
}
---------------------------------------------------------------
- note that I previously used ETH_P_ALL instead of ETH_P_AX25,
  I don't know for sure if using ETH_P_AX25 still triggers the
  'buggy' messages.
- It seems that I need the 'bind' because without it I get
  NET: messages. Transmission works find without the 'bind' though
  (but gives 'buggy' messages on new kernels).

2) Receiving
---------------------------------------------------------------
/* AX25_MAC call to retrieve RX data */
short mac_inp(frame_t far *frame_p)
{
    struct sockaddr  from;
    unsigned int     from_len;
    char             data[MAX_FRAME_LENGTH + 1];
    int              data_length;
    int              i;
    ports_t         *prt_p;

    from_len = sizeof(from);
    data_length = recvfrom(lnx_s_in, data, MAX_FRAME_LENGTH + 1, 0,
                                                            &from, &from_len);

    if(data_length < 0) {
        if (errno == EWOULDBLOCK)
            return -1;
        say("Error returned from \"recvfrom\" in function mac_inp()\r\n");
        exit(1);
    }

    if(data_length < 2)
        return -1; /* short packet */

    if(data[0] != 0)
        return -1; /* not a data packet */

    data_length--;

    memcpy(frame_p->frame, &(data[1]), data_length);
    frame_p->len  = data_length;

    /* find out from which port this came */
    for(i = 0; i < lnx_port_nr; i++)
    {
        prt_p      = &(lnx_port[i]);

        if(strcmp(prt_p->dev_p, from.sa_data) == 0)
        {
            /* found it! */
            frame_p->port = i;
            return 0;
        }
    }

    /* data on a port we don't use for DIGI_NED */
    return -1;
}
---------------------------------------------------------------
- Before reception I have a 'select' elsewhere to see if there
  is data to be received.
- This method is the same as used by 'listen' (concept stolen
  with pride).

3) Transmitting
---------------------------------------------------------------
/* AX25_MAC call to put TX data in the MAC layer */
short mac_out(frame_t far *frame_p)
{

    struct sockaddr  to;
    char             data[MAX_FRAME_LENGTH + 1];
    int              res;
    ports_t         *prt_p;

    prt_p = &(lnx_port[(short) frame_p->port]);

    bzero(&to,sizeof(struct sockaddr));
    to.sa_family = AF_INET;
    strcpy(to.sa_data, prt_p->dev_p);

    data[0] = 0; /* this is data */
    memcpy(&data[1], frame_p->frame, frame_p->len);

    res = sendto(prt_p->s_out, data, frame_p->len + 1, 0, &to, sizeof(to));
    if (res >= 0)
    {
            return 0;
    }
    if (errno == EMSGSIZE) {
            vsay("Sendto: packet (size %d) too long\r\n", frame_p->len + 1);
            return -1;
    }
    if (errno == EWOULDBLOCK) {
            vsay("Sendto: busy\r\n", frame_p->len);
            return -1;
    }
    perror("sendto");
    return -1;
}
---------------------------------------------------------------
- no specific comment here. I added 'bzero' later but that did
  not make a difference for the 'buggy' messages.

This code seems to trigger the 'buggy' messages, at least if on
opening the socket "ETH_P_ALL" is used. I resently changed it
since I don't want to hear my own packet back but I do not
know if it bypasses the 'buggy' message. Maybe it helps to find
out why this happens. On the internet I could find that some
totally unrelated software - I think it was apple networking
stuff - caused the same 'buggy' messages.

Anyway, my kernel-hacking knowledge is to limited to find out
myself what is causing is.

In the original code this is surrounded by #ifdef/#else/#endif
because the software runs in DOS too. If you want full functional
source, it is available at:

http://www.homepages.hetnet.nl/~remko

DIGI_NED is a rule based digipeater with a lot of functions. I
need this raw access to do all kind of manipulations with the
digipeater path. I also get raw frames from the DOS MAC-layer
if DOS compile is used so using raw frames makes the difference
between DOS and Linux very small.

If there is a better way to send and receive raw AX.25 frames,
please let me know.

Kind regards,

Henk.

--
#####################################################################
The difference between theory and practice in practice is bigger than
the difference between theory and practice in theory.

Henk de Groot                    |  Tel: +31 53 4505400     Ext: 5400
<[EMAIL PROTECTED]>  |  Ericsson Business Mobile Networks

Reply via email to