/* * lib/ax25.c This file contains an implementation of the "AX.25" * support functions. * * Version: $Id: ax25.c,v 1.9 1999/09/27 11:00:45 philip Exp $ * * NOTE: I will redo this module as soon as I got the libax25.a * library sorted out. This library contains some useful * and often used address conversion functions, database * lookup stuff, and more of the like. * * Author: Fred N. van Kempen, * Copyright 1993 MicroWalt Corporation * * 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 the Free Software * Foundation; either version 2 of the License, or (at * your option) any later version. */ #include "config.h" #if HAVE_AFAX25 || HAVE_HWAX25 #include #include #include #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) #include #else #include #endif #include #include #include #include #include #include #include #include #include #include "net-support.h" #include "pathnames.h" #include "intl.h" #include "util.h" static char AX25_errmsg[128]; extern struct aftype ax25_aftype; static const char *AX25_print(const char *ptr) { static char buff[8]; int i; for (i = 0; i < 6; i++) { buff[i] = ((ptr[i] & 0377) >> 1); if (buff[i] == ' ') buff[i] = '\0'; } buff[6] = '\0'; i = ((ptr[6] & 0x1E) >> 1); if (i != 0) sprintf(&buff[strlen(buff)], "-%d", i); return (buff); } /* Display an AX.25 socket address. */ static const char * AX25_sprint(const struct sockaddr_storage *sasp, int numeric) { const struct sockaddr *sap = (const struct sockaddr *)sasp; static char buf[64]; if (sap->sa_family == 0xFFFF || sap->sa_family == 0) return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf)); return (AX25_print(((const struct sockaddr_ax25 *) sasp)->sax25_call.ax25_call)); } #ifdef DEBUG #define _DEBUG 1 #else #define _DEBUG 0 #endif static int AX25_input(int type, char *bufp, struct sockaddr_storage *sasp) { struct sockaddr *sap = (struct sockaddr *)sasp; char *ptr; char *orig, c; int i; sap->sa_family = ax25_aftype.af; ptr = ((struct sockaddr_ax25 *) sasp)->sax25_call.ax25_call; /* First, scan and convert the basic callsign. */ orig = bufp; i = 0; while ((*bufp != '\0') && (*bufp != '-') && (i < 6)) { c = *bufp++; if (islower(c)) c = toupper(c); if (!(isupper(c) || isdigit(c))) { safe_strncpy(AX25_errmsg, _("Invalid callsign"), sizeof(AX25_errmsg)); if (_DEBUG) fprintf(stderr, "ax25_input(%s): %s !\n", AX25_errmsg, orig); errno = EINVAL; return (-1); } *ptr++ = (unsigned char) ((c << 1) & 0xFE); i++; } /* Callsign too long? */ if ((i == 6) && (*bufp != '-') && (*bufp != '\0')) { safe_strncpy(AX25_errmsg, _("Callsign too long"), sizeof(AX25_errmsg)); if (_DEBUG) fprintf(stderr, "ax25_input(%s): %s !\n", AX25_errmsg, orig); errno = E2BIG; return (-1); } /* Nope, fill out the address bytes with blanks. */ while (i++ < sizeof(ax25_address) - 1) { *ptr++ = (unsigned char) ((' ' << 1) & 0xFE); } /* See if we need to add an SSID field. */ if (*bufp == '-') { i = atoi(++bufp); *ptr = (unsigned char) ((i << 1) & 0xFE); } else { *ptr = (unsigned char) '\0'; } /* All done. */ if (_DEBUG) { fprintf(stderr, "ax25_input(%s): ", orig); for (i = 0; i < sizeof(ax25_address); i++) fprintf(stderr, "%02X ", sap->sa_data[i] & 0377); fprintf(stderr, "\n"); } return (0); } /* Display an error message. */ static void AX25_herror(const char *text) { if (text == NULL) fprintf(stderr, "%s\n", AX25_errmsg); else fprintf(stderr, "%s: %s\n", text, AX25_errmsg); } static int AX25_hinput(char *bufp, struct sockaddr_storage *sasp) { struct sockaddr *sap = (struct sockaddr *)sasp; if (AX25_input(0, bufp, sasp) < 0) return (-1); sap->sa_family = ARPHRD_AX25; return (0); } #if 0 /* Set the line discipline of a terminal line. */ static int KISS_set_disc(int fd, int disc) { if (ioctl(fd, TIOCSETD, &disc) < 0) { fprintf(stderr, "KISS_set_disc(%d): %s\n", disc, strerror(errno)); return (-errno); } return (0); } /* Start the KISS encapsulation on the file descriptor. */ static int KISS_init(int fd) { if (KISS_set_disc(fd, N_SLIP) < 0) return (-1); if (ioctl(fd, SIOCSIFENCAP, 4) < 0) return (-1); return (0); } #endif struct hwtype ax25_hwtype = { "ax25", NULL, /*"AMPR AX.25", */ ARPHRD_AX25, 7, AX25_print, AX25_hinput, NULL }; struct aftype ax25_aftype = { "ax25", NULL, /*"AMPR AX.25", */ AF_AX25, 7, AX25_print, AX25_sprint, AX25_input, AX25_herror, NULL, NULL, NULL, -1, "/proc/net/ax25" }; #endif /* HAVE_xxAX25 */