@@ -335,9 +335,18 @@ void ax25_delete (packet_t this_p)
335
335
* Purpose: Parse a frame in human-readable monitoring format and change
336
336
* to internal representation.
337
337
*
338
- * Input: monitor - "TNC-2" format of a monitored packet. i.e.
338
+ * Input: monitor - "TNC-2" monitor format for packet. i.e.
339
339
* source>dest[,repeater1,repeater2,...]:information
340
340
*
341
+ * The information part can have non-printable characters
342
+ * in the form of <0xff>. This will be converted to single
343
+ * bytes. e.g. <0x0d> is carriage return.
344
+ * In version 1.4H we will allow nul characters which means
345
+ * we have to maintain a length rather than using strlen().
346
+ * I maintain that it violates the spec but want to handle it
347
+ * because it does happen and we want to preserve it when
348
+ * acting as an IGate rather than corrupting it.
349
+ *
341
350
* strict - True to enforce rules for packets sent over the air.
342
351
* False to be more lenient for packets from IGate server.
343
352
*
@@ -369,17 +378,11 @@ packet_t ax25_from_text (char *monitor, int strict)
369
378
char * pa ;
370
379
char * saveptr ; /* Used with strtok_r because strtok is not thread safe. */
371
380
372
- static int first_time = 1 ;
373
- static regex_t unhex_re ;
374
- int e ;
375
- char emsg [100 ];
376
- #define MAXMATCH 1
377
- regmatch_t match [MAXMATCH ];
378
- int keep_going ;
379
- char temp [512 ];
380
381
int ssid_temp , heard_temp ;
381
382
char atemp [AX25_MAX_ADDR_LEN ];
382
383
384
+ char info_part [AX25_MAX_INFO_LEN + 1 ];
385
+ int info_len ;
383
386
384
387
packet_t this_p = ax25_new ();
385
388
@@ -392,58 +395,15 @@ packet_t ax25_from_text (char *monitor, int strict)
392
395
393
396
/* Is it possible to have a nul character (zero byte) in the */
394
397
/* information field of an AX.25 frame? */
395
- /* Yes, but it would be difficult in the from-text case. */
398
+ /* At this point, we have a normal C string. */
399
+ /* It is possible that will convert <0x00> to a nul character later. */
400
+ /* There we need to maintain a separate length and not use normal C string functions. */
396
401
397
402
strlcpy (stuff , monitor , sizeof (stuff ));
398
403
399
- /*
400
- * Translate hexadecimal values like <0xff> to non-printing characters.
401
- * MIC-E message type uses 5 different non-printing characters.
402
- */
403
-
404
- if (first_time )
405
- {
406
- e = regcomp (& unhex_re , "<0x[0-9a-fA-F][0-9a-fA-F]>" , 0 );
407
- if (e ) {
408
- regerror (e , & unhex_re , emsg , sizeof (emsg ));
409
- text_color_set (DW_COLOR_ERROR );
410
- dw_printf ("%s:%d: %s\n" , __FILE__ , __LINE__ , emsg );
411
- }
412
-
413
- first_time = 0 ;
414
- }
415
-
416
- #if 0
417
- text_color_set (DW_COLOR_DEBUG );
418
- dw_printf ("BEFORE: %s\n" , stuff );
419
- ax25_safe_print (stuff , -1 , 0 );
420
- dw_printf ("\n" );
421
- #endif
422
- keep_going = 1 ;
423
- while (keep_going ) {
424
- if (regexec (& unhex_re , stuff , MAXMATCH , match , 0 ) == 0 ) {
425
- int n ;
426
- char * p ;
427
-
428
- stuff [match [0 ].rm_so + 5 ] = '\0' ;
429
- n = strtol (stuff + match [0 ].rm_so + 3 , & p , 16 );
430
- stuff [match [0 ].rm_so ] = n ;
431
- strlcpy (temp , stuff + match [0 ].rm_eo , sizeof (temp ));
432
- strlcpy (stuff + match [0 ].rm_so + 1 , temp , sizeof (stuff )- match [0 ].rm_so - 1 );
433
- }
434
- else {
435
- keep_going = 0 ;
436
- }
437
- }
438
- #if 0
439
- text_color_set (DW_COLOR_DEBUG );
440
- dw_printf ("AFTER: %s\n" , stuff );
441
- ax25_safe_print (stuff , -1 , 0 );
442
- dw_printf ("\n" );
443
- #endif
444
404
445
405
/*
446
- * Initialize the packet with two addresses and control/pid
406
+ * Initialize the packet structure with two addresses and control/pid
447
407
* for APRS.
448
408
*/
449
409
memset (this_p -> frame_data + AX25_DESTINATION * 7 , ' ' << 1 , 6 );
@@ -473,12 +433,6 @@ packet_t ax25_from_text (char *monitor, int strict)
473
433
* pinfo = '\0' ;
474
434
pinfo ++ ;
475
435
476
- if (strlen (pinfo ) > AX25_MAX_INFO_LEN ) {
477
- text_color_set (DW_COLOR_ERROR );
478
- dw_printf ("Warning: Information part truncated to %d characters.\n" , AX25_MAX_INFO_LEN );
479
- pinfo [AX25_MAX_INFO_LEN ] = '\0' ;
480
- }
481
-
482
436
/*
483
437
* Separate the addresses.
484
438
* Note that source and destination order is swappped.
@@ -535,7 +489,6 @@ packet_t ax25_from_text (char *monitor, int strict)
535
489
*/
536
490
while (( pa = strtok_r (NULL , "," , & saveptr )) != NULL && this_p -> num_addr < AX25_MAX_ADDRS ) {
537
491
538
- //char *last;
539
492
int k ;
540
493
541
494
k = this_p -> num_addr ;
@@ -561,11 +514,61 @@ packet_t ax25_from_text (char *monitor, int strict)
561
514
}
562
515
}
563
516
517
+
518
+ /*
519
+ * Finally, process the information part.
520
+ *
521
+ * Translate hexadecimal values like <0xff> to single bytes.
522
+ * MIC-E format uses 5 different non-printing characters.
523
+ * We might want to manually generate UTF-8 characters such as degree.
524
+ */
525
+
526
+ //#define DEBUG14H 1
527
+
528
+ #if DEBUG14H
529
+ text_color_set (DW_COLOR_DEBUG );
530
+ dw_printf ("BEFORE: %s\nSAFE: " , pinfo );
531
+ ax25_safe_print (pinfo , -1 , 0 );
532
+ dw_printf ("\n" );
533
+ #endif
534
+
535
+ info_len = 0 ;
536
+ while (* pinfo != '\0' && info_len < AX25_MAX_INFO_LEN ) {
537
+
538
+ if (strlen (pinfo ) >= 6 &&
539
+ pinfo [0 ] == '<' &&
540
+ pinfo [1 ] == '0' &&
541
+ pinfo [2 ] == 'x' &&
542
+ isxdigit (pinfo [3 ]) &&
543
+ isxdigit (pinfo [4 ]) &&
544
+ pinfo [5 ] == '>' ) {
545
+
546
+ char * p ;
547
+
548
+ info_part [info_len ] = strtol (pinfo + 3 , & p , 16 );
549
+ info_len ++ ;
550
+ pinfo += 6 ;
551
+ }
552
+ else {
553
+ info_part [info_len ] = * pinfo ;
554
+ info_len ++ ;
555
+ pinfo ++ ;
556
+ }
557
+ }
558
+ info_part [info_len ] = '\0' ;
559
+
560
+ #if DEBUG14H
561
+ text_color_set (DW_COLOR_DEBUG );
562
+ dw_printf ("AFTER: %s\nSAFE: " , info_part );
563
+ ax25_safe_print (info_part , info_len , 0 );
564
+ dw_printf ("\n" );
565
+ #endif
566
+
564
567
/*
565
568
* Append the info part.
566
569
*/
567
- strlcpy ((char * )(this_p -> frame_data + this_p -> frame_len ), pinfo , sizeof ( this_p -> frame_data ) - this_p -> frame_len );
568
- this_p -> frame_len += strlen ( pinfo ) ;
570
+ memcpy ((char * )(this_p -> frame_data + this_p -> frame_len ), info_part , info_len );
571
+ this_p -> frame_len += info_len ;
569
572
570
573
return (this_p );
571
574
}
@@ -2536,7 +2539,7 @@ unsigned short ax25_m_m_crc (packet_t pp)
2536
2539
*
2537
2540
* Inputs: pstr - Pointer to string.
2538
2541
*
2539
- * len - Maximum length if not -1 .
2542
+ * len - Number of bytes. If < 0 we use strlen() .
2540
2543
*
2541
2544
* ascii_only - Restrict output to only ASCII.
2542
2545
* Normally we allow UTF-8.
@@ -2587,7 +2590,6 @@ void ax25_safe_print (char *pstr, int len, int ascii_only)
2587
2590
if (len > MAXSAFE )
2588
2591
len = MAXSAFE ;
2589
2592
2590
- //while (len > 0 && *pstr != '\0')
2591
2593
while (len > 0 )
2592
2594
{
2593
2595
ch = * ((unsigned char * )pstr );
0 commit comments