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