mirror of https://github.com/wb2osz/direwolf.git
More error checking for valid AX.25 format.
This commit is contained in:
parent
357f2e633c
commit
69fc783a17
83
ax25_pad.c
83
ax25_pad.c
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011 , 2013, 2014, 2015 John Langner, WB2OSZ
|
// Copyright (C) 2011 , 2013, 2014, 2015, 2019 John Langner, WB2OSZ
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
@ -87,18 +87,18 @@
|
||||||
* http://www.aprs.org/aprs12/preemptive-digipeating.txt
|
* http://www.aprs.org/aprs12/preemptive-digipeating.txt
|
||||||
* http://www.aprs.org/aprs12/RR-bits.txt
|
* http://www.aprs.org/aprs12/RR-bits.txt
|
||||||
*
|
*
|
||||||
* I don't recall why I originally intended to set the source/destination C bits both to 1.
|
* I don't recall why I originally set the source & destination C bits both to 1.
|
||||||
* Reviewing this 5 years later, after spending more time delving into the
|
* Reviewing this 5 years later, after spending more time delving into the
|
||||||
* AX.25 spec, I think it should be 1 for destination and 0 for source.
|
* AX.25 spec, I think it should be 1 for destination and 0 for source.
|
||||||
* In practice you see all four combinations being used by APRS stations
|
* In practice you see all four combinations being used by APRS stations
|
||||||
* and no one really cares about these two bits.
|
* and everyone apparently ignores them for APRS. They do make a big
|
||||||
|
* difference for connected mode.
|
||||||
*
|
*
|
||||||
* The final octet of the Source has the form:
|
* The final octet of the Source has the form:
|
||||||
*
|
*
|
||||||
* C R R SSID 0, where,
|
* C R R SSID 0, where,
|
||||||
*
|
*
|
||||||
* C = command/response = 1 (originally, now I think it should be 0 for source.)
|
* C = command/response = 0
|
||||||
* (Haven't gone back to check to see what code actually does.)
|
|
||||||
* R R = Reserved = 1 1
|
* R R = Reserved = 1 1
|
||||||
* SSID = substation ID
|
* SSID = substation ID
|
||||||
* 0 = zero (or 1 if no repeaters)
|
* 0 = zero (or 1 if no repeaters)
|
||||||
|
@ -373,10 +373,7 @@ packet_t ax25_from_text (char *monitor, int strict)
|
||||||
* Tearing it apart is destructive so make our own copy first.
|
* Tearing it apart is destructive so make our own copy first.
|
||||||
*/
|
*/
|
||||||
char stuff[512];
|
char stuff[512];
|
||||||
|
|
||||||
char *pinfo;
|
char *pinfo;
|
||||||
char *pa;
|
|
||||||
char *saveptr; /* Used with strtok_r because strtok is not thread safe. */
|
|
||||||
|
|
||||||
int ssid_temp, heard_temp;
|
int ssid_temp, heard_temp;
|
||||||
char atemp[AX25_MAX_ADDR_LEN];
|
char atemp[AX25_MAX_ADDR_LEN];
|
||||||
|
@ -384,6 +381,10 @@ packet_t ax25_from_text (char *monitor, int strict)
|
||||||
char info_part[AX25_MAX_INFO_LEN+1];
|
char info_part[AX25_MAX_INFO_LEN+1];
|
||||||
int info_len;
|
int info_len;
|
||||||
|
|
||||||
|
// text_color_set(DW_COLOR_DEBUG);
|
||||||
|
// dw_printf ("DEBUG: ax25_from_text ('%s', %d)\n", monitor, strict);
|
||||||
|
// fflush(stdout); sleep(1);
|
||||||
|
|
||||||
packet_t this_p = ax25_new ();
|
packet_t this_p = ax25_new ();
|
||||||
|
|
||||||
#if AX25MEMDEBUG
|
#if AX25MEMDEBUG
|
||||||
|
@ -410,7 +411,7 @@ packet_t ax25_from_text (char *monitor, int strict)
|
||||||
this_p->frame_data[AX25_DESTINATION*7+6] = SSID_H_MASK | SSID_RR_MASK;
|
this_p->frame_data[AX25_DESTINATION*7+6] = SSID_H_MASK | SSID_RR_MASK;
|
||||||
|
|
||||||
memset (this_p->frame_data + AX25_SOURCE*7, ' ' << 1, 6);
|
memset (this_p->frame_data + AX25_SOURCE*7, ' ' << 1, 6);
|
||||||
this_p->frame_data[AX25_SOURCE*7+6] = SSID_H_MASK | SSID_RR_MASK | SSID_LAST_MASK;
|
this_p->frame_data[AX25_SOURCE*7+6] = SSID_RR_MASK | SSID_LAST_MASK;
|
||||||
|
|
||||||
this_p->frame_data[14] = AX25_UI_FRAME;
|
this_p->frame_data[14] = AX25_UI_FRAME;
|
||||||
this_p->frame_data[15] = AX25_PID_NO_LAYER_3;
|
this_p->frame_data[15] = AX25_PID_NO_LAYER_3;
|
||||||
|
@ -440,9 +441,10 @@ packet_t ax25_from_text (char *monitor, int strict)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Source address.
|
* Source address.
|
||||||
* Don't use traditional strtok because it is not thread safe.
|
|
||||||
*/
|
*/
|
||||||
pa = strtok_r (stuff, ">", &saveptr);
|
|
||||||
|
char *pnxt = stuff;
|
||||||
|
char *pa = strsep (&pnxt, ">");
|
||||||
if (pa == NULL) {
|
if (pa == NULL) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Failed to create packet from text. No source address\n");
|
dw_printf ("Failed to create packet from text. No source address\n");
|
||||||
|
@ -465,7 +467,7 @@ packet_t ax25_from_text (char *monitor, int strict)
|
||||||
* Destination address.
|
* Destination address.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pa = strtok_r (NULL, ",", &saveptr);
|
pa = strsep (&pnxt, ",");
|
||||||
if (pa == NULL) {
|
if (pa == NULL) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Failed to create packet from text. No destination address\n");
|
dw_printf ("Failed to create packet from text. No destination address\n");
|
||||||
|
@ -487,11 +489,26 @@ packet_t ax25_from_text (char *monitor, int strict)
|
||||||
/*
|
/*
|
||||||
* VIA path.
|
* VIA path.
|
||||||
*/
|
*/
|
||||||
while (( pa = strtok_r (NULL, ",", &saveptr)) != NULL && this_p->num_addr < AX25_MAX_ADDRS ) {
|
|
||||||
|
|
||||||
int k;
|
// Originally this used strtok_r.
|
||||||
|
// strtok considers all adjacent delimiters to be a single delimiter.
|
||||||
|
// This is handy for varying amounts of whitespace.
|
||||||
|
// It will never return a zero length string.
|
||||||
|
// All was good until this bizarre case came along:
|
||||||
|
|
||||||
k = this_p->num_addr;
|
// AISAT-1>CQ,,::CQ-0 :From AMSAT INDIA & Exseed Space |114304|48|45|42{962
|
||||||
|
|
||||||
|
// Apparently there are two digipeater fields but they are empty.
|
||||||
|
// When we parsed this text representation, the extra commas were ignored rather
|
||||||
|
// than pointed out as being invalid.
|
||||||
|
|
||||||
|
// Use strsep instead. This does not collapse adjacent delimiters.
|
||||||
|
|
||||||
|
while (( pa = strsep (&pnxt, ",")) != NULL && this_p->num_addr < AX25_MAX_ADDRS ) {
|
||||||
|
|
||||||
|
int k = this_p->num_addr;
|
||||||
|
|
||||||
|
// printf ("DEBUG: get digi loop, num addr = %d, address = '%s'\n", k, pa);// FIXME
|
||||||
|
|
||||||
if ( ! ax25_parse_addr (k, pa, strict, atemp, &ssid_temp, &heard_temp)) {
|
if ( ! ax25_parse_addr (k, pa, strict, atemp, &ssid_temp, &heard_temp)) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
@ -726,7 +743,7 @@ packet_t ax25_dup (packet_t copy_from)
|
||||||
* out_heard - True if "*" found.
|
* out_heard - True if "*" found.
|
||||||
*
|
*
|
||||||
* Returns: True (1) if OK, false (0) if any error.
|
* Returns: True (1) if OK, false (0) if any error.
|
||||||
* When 0, out_addr, out_ssid, and out_heard are unpredictable.
|
* When 0, out_addr, out_ssid, and out_heard are undefined.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
|
@ -747,10 +764,17 @@ int ax25_parse_addr (int position, char *in_addr, int strict, char *out_addr, in
|
||||||
*out_ssid = 0;
|
*out_ssid = 0;
|
||||||
*out_heard = 0;
|
*out_heard = 0;
|
||||||
|
|
||||||
|
// dw_printf ("ax25_parse_addr in: position=%d, '%s', strict=%d\n", position, in_addr, strict);
|
||||||
|
|
||||||
if (position < -1) position = -1;
|
if (position < -1) position = -1;
|
||||||
if (position > AX25_REPEATER_8) position = AX25_REPEATER_8;
|
if (position > AX25_REPEATER_8) position = AX25_REPEATER_8;
|
||||||
position++; /* Adjust for position_name above. */
|
position++; /* Adjust for position_name above. */
|
||||||
|
|
||||||
|
if (strlen(in_addr) == 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("%sAddress \"%s\" is empty.\n", position_name[position], in_addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (strict && strlen(in_addr) >= 2 && strncmp(in_addr, "qA", 2) == 0) {
|
if (strict && strlen(in_addr) >= 2 && strncmp(in_addr, "qA", 2) == 0) {
|
||||||
|
|
||||||
|
@ -759,8 +783,7 @@ int ax25_parse_addr (int position, char *in_addr, int strict, char *out_addr, in
|
||||||
dw_printf ("APRS Internet Servers. It should never appear when going over the radio.\n");
|
dw_printf ("APRS Internet Servers. It should never appear when going over the radio.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//dw_printf ("ax25_parse_addr in: %s\n", in_addr);
|
// dw_printf ("ax25_parse_addr in: %s\n", in_addr);
|
||||||
|
|
||||||
|
|
||||||
maxlen = strict ? 6 : (AX25_MAX_ADDR_LEN-1);
|
maxlen = strict ? 6 : (AX25_MAX_ADDR_LEN-1);
|
||||||
p = in_addr;
|
p = in_addr;
|
||||||
|
@ -838,7 +861,7 @@ int ax25_parse_addr (int position, char *in_addr, int strict, char *out_addr, in
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//dw_printf ("ax25_parse_addr out: %s %d %d\n", out_addr, *out_ssid, *out_heard);
|
// dw_printf ("ax25_parse_addr out: '%s' %d %d\n", out_addr, *out_ssid, *out_heard);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
|
@ -984,6 +1007,11 @@ void ax25_set_addr (packet_t this_p, int n, char *ad)
|
||||||
|
|
||||||
//dw_printf ("ax25_set_addr (%d, %s) num_addr=%d\n", n, ad, this_p->num_addr);
|
//dw_printf ("ax25_set_addr (%d, %s) num_addr=%d\n", n, ad, this_p->num_addr);
|
||||||
|
|
||||||
|
if (strlen(ad) == 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Set address error! Station address for position %d is empty!\n", n);
|
||||||
|
}
|
||||||
|
|
||||||
if (n >= 0 && n < this_p->num_addr) {
|
if (n >= 0 && n < this_p->num_addr) {
|
||||||
|
|
||||||
//dw_printf ("ax25_set_addr , existing case\n");
|
//dw_printf ("ax25_set_addr , existing case\n");
|
||||||
|
@ -1065,6 +1093,11 @@ void ax25_insert_addr (packet_t this_p, int n, char *ad)
|
||||||
|
|
||||||
//dw_printf ("ax25_insert_addr (%d, %s)\n", n, ad);
|
//dw_printf ("ax25_insert_addr (%d, %s)\n", n, ad);
|
||||||
|
|
||||||
|
if (strlen(ad) == 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Set address error! Station address for position %d is empty!\n", n);
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't do it if we already have the maximum number. */
|
/* Don't do it if we already have the maximum number. */
|
||||||
/* Should probably return success/fail code but currently the caller doesn't care. */
|
/* Should probably return success/fail code but currently the caller doesn't care. */
|
||||||
|
|
||||||
|
@ -1305,6 +1338,11 @@ void ax25_get_addr_with_ssid (packet_t this_p, int n, char *station)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen(station) == 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Station address, in position %d, is empty! This is not a valid AX.25 frame.\n", n);
|
||||||
|
}
|
||||||
|
|
||||||
ssid = ax25_get_ssid (this_p, n);
|
ssid = ax25_get_ssid (this_p, n);
|
||||||
if (ssid != 0) {
|
if (ssid != 0) {
|
||||||
snprintf (sstr, sizeof(sstr), "-%d", ssid);
|
snprintf (sstr, sizeof(sstr), "-%d", ssid);
|
||||||
|
@ -1379,6 +1417,11 @@ void ax25_get_addr_no_ssid (packet_t this_p, int n, char *station)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen(station) == 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("Station address, in position %d, is empty! This is not a valid AX.25 frame.\n", n);
|
||||||
|
}
|
||||||
|
|
||||||
} /* end ax25_get_addr_no_ssid */
|
} /* end ax25_get_addr_no_ssid */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1918,6 +1961,8 @@ void ax25_format_addrs (packet_t this_p, char *result)
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat (result, ":");
|
strcat (result, ":");
|
||||||
|
|
||||||
|
// dw_printf ("DEBUG ax25_format_addrs, num_addr = %d, result = '%s'\n", this_p->num_addr, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue