struct ax_routes *find_mheard(char *dest_call) { FILE *fp; static struct ax_routes a; struct mheard_struct mh; char call[12]; char *cp; int k; if ((fp = fopen(DATA_MHEARD_FILE, "r")) == NULL) { return NULL; } safe_strncpy(call,dest_call,9); cp=strchr(call, '-'); if (cp==NULL) strcat(call,"-0"); while (fread(&mh, sizeof(struct mheard_struct), 1, fp) == 1) { if (strcasecmp(call, ax25_ntoa(&mh.from_call))==0) { fclose(fp); safe_strncpy(a.dest_call, ax25_ntoa(&mh.from_call), 9); safe_strncpy(a.dev, mh.portname, 13); for(k=0;k<AX25_MAX_DIGIS;k++) { if (k<=mh.ndigis) safe_strncpy(a.digis[k],ax25_ntoa(&mh.digis[k]),9); else strcpy(a.digis[k],"\0"); } return &a; } } fclose(fp); return NULL; }
/* is_heard : from awznode */ int is_heard(char **av) { FILE *fp; static char port[14]; static char dest[10]; static char digi[10][AX25_MAX_DIGIS]; struct mheard_struct mh; char call[12]; char *cp; int k; if ((fp = fopen(DATA_MHEARD_FILE, "r")) == NULL) { printf("Error : file %s not found\n", DATA_MHEARD_FILE); return 0; } safe_strncpy(call, av[0], 9); cp = strchr(call, '-'); if (cp == NULL) strcat(call, "-0"); while (fread(&mh, sizeof(struct mheard_struct), 1, fp) == 1) { if (strcasecmp(call, ax25_ntoa(&mh.from_call)) == 0) { fclose(fp); safe_strncpy(port, mh.portname, 13); safe_strncpy(dest, ax25_ntoa(&mh.from_call), 9); av[0] = port; av[1] = dest; for (k = 0; k < AX25_MAX_DIGIS; k++) { if (k <= mh.ndigis) { safe_strncpy(digi[k], ax25_ntoa(&mh.digis[k]), 9); av[2 + k] = digi[k]; } else { av[2 + k] = NULL; break; } } return 1; } } fclose(fp); return 0; }
static PyObject * ax25_address_str(ax25_address_object* self) { const char* ret; ret = ax25_ntoa(&self->field); return PyUnicode_FromStringAndSize(ret, strlen(ret)); }
void dump_rose(char *title, struct full_sockaddr_rose *rose) { int i; printf("%s\n", title); printf("\tFamily = %d\n", rose->srose_family); printf("\tCallsign = %s\n", ax25_ntoa(&rose->srose_call)); printf("\tAddress = %s\n", rose_ntoa(&rose->srose_addr)); printf("\tndigis = %d\n", rose->srose_ndigis); for (i = 0; i < rose->srose_ndigis ; i++) { if (i == 6) { printf("Error : Nb digis = %d\n", rose->srose_ndigis); break; } printf("\tdigi %d = %s\n", i+1, ax25_ntoa(&rose->srose_digis[i])); } printf("\n"); }
void dump_ax25(char *title, struct full_sockaddr_ax25 *ax25) { int i; printf("%s\n", title); printf("\tFamily = %d\n", ax25->fsa_ax25.sax25_family); printf("\tCallsign = %s\n", ax25_ntoa(&ax25->fsa_ax25.sax25_call)); printf("\tndigis = %d\n", ax25->fsa_ax25.sax25_ndigis); for (i = 0; i < ax25->fsa_ax25.sax25_ndigis ; i++) { if (i == 6) { printf("Error : Nb digis = %d\n", ax25->fsa_ax25.sax25_ndigis); break; } printf("\tdigi %d = %s%c\n", i+1, ax25_ntoa(&ax25->fsa_digipeater[i]), (ax25->fsa_digipeater[i].ax25_call[6] & AX25_HBIT) ? '*' : ' '); } printf("\n"); }
static void PrintPortEntry(struct PortRecord *pr, int portnr, int c_index) { char lh[30], fh[30], *call, *s, data[255]; int i; strcpy(lh, ctime(&pr->entry.last_heard)); lh[19] = 0; strcpy(fh, ctime(&pr->entry.first_heard)); fh[19] = 0; call = ax25_ntoa(&pr->entry.from_call); if ((s = strstr(call, "-0")) != NULL) *s = '\0'; sprintf(data,"%s %s %s ", call, fh, lh); for (i=strlen(data);i<sizeof(data);i++) data[i]=0; send_frame('H',connection[c_index].fd,portlist[portnr].dev,data,strlen(data)+33,"",""); }
int wp_update_addr(struct full_sockaddr_rose *addr) { wp_t wp; char *ptr; /* Only valid callsigns ! */ ptr = ax25_ntoa(&addr->srose_call); if ((ptr == NULL) || (wp_check_call(ptr) != 0)) { syslog(LOG_INFO, "wp_update_addr() invalid callsign '%s'\n", ptr); return -1; } memset(&wp, 0, sizeof(wp_t)); if (wp_get(&addr->srose_call, &wp) != 0) { syslog(LOG_INFO, "wp_update_addr() callsign '%s' not found\n", ptr); /* return -1; */ } wp.is_deleted = 0; wp.address = *addr; return wp_set(&wp); }
int main(int ac, char **av) { FILE *fptr; old_wp_t old_wp; wp_t new_wp; wp_header wph; char dnic[5]; char *add, *call; char buf[20]; if (ac < 2) { fprintf(stderr, "format : wpconv database\n"); return 1; } fptr = fopen(av[1], "r"); if (fptr == NULL) { fprintf(stderr, "Cannot open %s\n", av[1]); return 2; } if (fread(&wph, sizeof(wph), 1, fptr) == 0) { fclose(fptr); fprintf(stderr, "database %s is empty\n", av[1]); return 3; } /* Check the first record for compatibility */ if (strcmp(wph.signature,OLD_FILE_SIGNATURE) != 0) { fprintf(stderr, "database %s is not compatible\n", av[1]); fclose(fptr); return 4; } printf("%u callsigns in database\n", wph.nb_record); if (wp_open("WPCNVT")) { perror("Cannot open WP service"); exit(1); } while (fread(&old_wp, sizeof(old_wp_t), 1, fptr)) { if (old_wp.date == 0) continue; add = rose_ntoa(&old_wp.address.srose_addr); call = ax25_ntoa(&old_wp.address.srose_call); if (wp_check_call(call) != 0) continue; strncpy(dnic, add, 4); dnic[4] = '\0'; my_date(buf, old_wp.date), printf("%-9s %s => %s %-7s ", call, buf, dnic, add+4); if (old_wp.address.srose_ndigis) printf("%s ", ax25_ntoa(&old_wp.address.srose_digi)); printf("%s %s\n", old_wp.name, old_wp.city); /* Add to the running database */ memset(&new_wp, 0, sizeof(wp_t)); new_wp.date = old_wp.date; new_wp.address.srose_addr = old_wp.address.srose_addr; new_wp.address.srose_call = old_wp.address.srose_call; new_wp.address.srose_digis[0] = old_wp.address.srose_digi; new_wp.address.srose_ndigis = old_wp.address.srose_ndigis; wp_set(&new_wp); } wp_close(); return(0); }
static void PrintPortEntry(struct PortRecord *pr, int data) { char lh[30], fh[30], *call, *s; char buffer[80]; int i; switch (data) { case 0: strcpy(lh, ctime(&pr->entry.last_heard)); lh[19] = 0; call = ax25_ntoa(&pr->entry.from_call); if ((s = strstr(call, "-0")) != NULL) *s = '\0'; printf("%-10s %-5s %5d %s\n", call, pr->entry.portname, pr->entry.count, lh); break; case 1: buffer[0] = '\0'; call = ax25_ntoa(&pr->entry.from_call); if ((s = strstr(call, "-0")) != NULL) *s = '\0'; strcat(buffer, call); call = ax25_ntoa(&pr->entry.to_call); if ((s = strstr(call, "-0")) != NULL) *s = '\0'; strcat(buffer, ">"); strcat(buffer, call); for (i = 0; i < pr->entry.ndigis && i < 4; i++) { strcat(buffer, ","); call = ax25_ntoa(&pr->entry.digis[i]); if ((s = strstr(call, "-0")) != NULL) *s = '\0'; strcat(buffer, call); } if (pr->entry.ndigis >= 4) strcat(buffer, ",..."); printf("%-70s %-5s\n", buffer, pr->entry.portname); break; case 2: strcpy(lh, ctime(&pr->entry.last_heard)); lh[19] = 0; strcpy(fh, ctime(&pr->entry.first_heard)); fh[19] = 0; call = ax25_ntoa(&pr->entry.from_call); if ((s = strstr(call, "-0")) != NULL) *s = '\0'; printf("%-10s %-5s %5d %5d %5d %s %s\n", call, pr->entry.portname, pr->entry.iframes, pr->entry.sframes, pr->entry.uframes, fh, lh); break; case 3: call = ax25_ntoa(&pr->entry.from_call); if ((s = strstr(call, "-0")) != NULL) *s = '\0'; printf("%-10s %-5s %5d %5s ", call, pr->entry.portname, pr->entry.count, types[pr->entry.type]); if (pr->entry.mode & MHEARD_MODE_ARP) printf(" ARP"); if (pr->entry.mode & MHEARD_MODE_FLEXNET) printf(" FlexNet"); if (pr->entry.mode & MHEARD_MODE_IP_DG) printf(" IP-DG"); if (pr->entry.mode & MHEARD_MODE_IP_VC) printf(" IP-VC"); if (pr->entry.mode & MHEARD_MODE_NETROM) printf(" NET/ROM"); if (pr->entry.mode & MHEARD_MODE_ROSE) printf(" Rose"); if (pr->entry.mode & MHEARD_MODE_SEGMENT) printf(" Segment"); if (pr->entry.mode & MHEARD_MODE_TEXNET) printf(" TexNet"); if (pr->entry.mode & MHEARD_MODE_TEXT) printf(" Text"); if (pr->entry.mode & MHEARD_MODE_PSATFT) printf(" PacsatFT"); if (pr->entry.mode & MHEARD_MODE_PSATPB) printf(" PacsatPB"); if (pr->entry.mode & MHEARD_MODE_UNKNOWN) printf(" Unknown"); printf("\n"); break; } }
int main(int argc, char **argv) { unsigned char buffer[512], *addr, *p; char rose_address[11]; fd_set read_fd; int n, s, dnicindex = -1, addrindex = -1; int yes = 1, verbose = 1; socklen_t addrlen; struct sockaddr_rose rosebind, roseconnect; struct full_sockaddr_ax25 ax25sock, ax25peer; openlog("rsuplnk", LOG_PID, LOG_DAEMON); /* * Arguments should be "rsuplnk [-q] roseport" */ if (argc > 2 && strcmp(argv[1], "-q") == 0) { verbose = 0; --argc; ++argv; } if (argc != 2) { syslog(LOG_ERR, "invalid number of parameters\n"); closelog(); return 1; } if (rs_config_load_ports() == 0) { syslog(LOG_ERR, "problem with rsports file\n"); closelog(); return 1; } addrlen = sizeof(struct full_sockaddr_ax25); if (getsockname(STDIN_FILENO, (struct sockaddr *)&ax25sock, &addrlen) == -1) { syslog(LOG_ERR, "cannot getsockname, %s\n", strerror(errno)); closelog(); return 1; } addrlen = sizeof(struct full_sockaddr_ax25); if (getpeername(STDIN_FILENO, (struct sockaddr *)&ax25peer, &addrlen) == -1) { syslog(LOG_ERR, "cannot getpeername, %s\n", strerror(errno)); closelog(); return 1; } #ifdef HAVE_AX25_PIDINCL if (setsockopt(STDIN_FILENO, SOL_AX25, AX25_PIDINCL, &yes, sizeof(yes)) == -1) { syslog(LOG_ERR, "cannot setsockopt(AX25_PIDINCL) - %s\n", strerror(errno)); closelog(); return 1; } #endif /* HAVE_AX25_PIDINCL */ roseconnect.srose_family = rosebind.srose_family = AF_ROSE; roseconnect.srose_ndigis = rosebind.srose_ndigis = 0; addrlen = sizeof(struct sockaddr_rose); if ((addr = rs_config_get_addr(argv[1])) == NULL) { syslog(LOG_ERR, "invalid Rose port name - %s\n", argv[1]); closelog(); return 1; } if (rose_aton(addr, rosebind.srose_addr.rose_addr) == -1) { syslog(LOG_ERR, "invalid ROSE port address - %s\n", argv[1]); closelog(); return 1; } /* * Copy our DNIC in as default. */ memset(rose_address, 0x00, 11); memcpy(rose_address, addr, 4); for (n = 0; n < ax25peer.fsa_ax25.sax25_ndigis; n++) { addr = ax25_ntoa(&ax25peer.fsa_digipeater[n]); if (strspn(addr, "0123456789-") == strlen(addr)) { if ((p = strchr(addr, '-')) != NULL) *p = '\0'; switch (strlen(addr)) { case 4: memcpy(rose_address + 0, addr, 4); dnicindex = n; break; case 6: memcpy(rose_address + 4, addr, 6); addrindex = n; break; default: break; } } } /* * The user didn't give an address. */ if (addrindex == -1) { strcpy(buffer, "*** No ROSE address given\r"); write(STDOUT_FILENO, buffer, strlen(buffer)); sleep(20); closelog(); return 1; } if (rose_aton(rose_address, roseconnect.srose_addr.rose_addr) == -1) { syslog(LOG_ERR, "invalid Rose address - %s\n", argv[4]); closelog(); return 1; } rosebind.srose_call = ax25peer.fsa_ax25.sax25_call; roseconnect.srose_call = ax25sock.fsa_ax25.sax25_call; /* * A far end digipeater was specified. */ if (addrindex > 0) { roseconnect.srose_ndigis = 1; roseconnect.srose_digi = ax25peer.fsa_digipeater[addrindex - 1]; } /* * Check for a local digipeater. */ if (dnicindex != -1) { if (ax25peer.fsa_ax25.sax25_ndigis - dnicindex > 2) { rosebind.srose_ndigis = 1; rosebind.srose_digi = ax25peer.fsa_digipeater[dnicindex + 2]; } } else { if (ax25peer.fsa_ax25.sax25_ndigis - addrindex > 2) { rosebind.srose_ndigis = 1; rosebind.srose_digi = ax25peer.fsa_digipeater[addrindex + 2]; } } /* * Open the socket into the kernel. */ if ((s = socket(AF_ROSE, SOCK_SEQPACKET, 0)) < 0) { syslog(LOG_ERR, "cannot open ROSE socket, %s\n", strerror(errno)); closelog(); return 1; } /* * Set our AX.25 callsign and Rose address accordingly. */ if (bind(s, (struct sockaddr *)&rosebind, addrlen) != 0) { syslog(LOG_ERR, "cannot bind ROSE socket, %s\n", strerror(errno)); closelog(); close(s); return 1; } if (setsockopt(s, SOL_ROSE, ROSE_QBITINCL, &yes, sizeof(yes)) == -1) { syslog(LOG_ERR, "cannot setsockopt(ROSE_QBITINCL) - %s\n", strerror(errno)); closelog(); close(s); return 1; } if (verbose) { strcpy(buffer, "*** Connection in progress\r"); write(STDOUT_FILENO, buffer, strlen(buffer)); } /* * If no response in 5 minutes, go away. */ alarm(300); signal(SIGALRM, alarm_handler); /* * Lets try and connect to the far end. */ if (connect(s, (struct sockaddr *)&roseconnect, addrlen) != 0) { switch (errno) { case ECONNREFUSED: strcpy(buffer, "*** Disconnected - 0100 - Number Busy\r"); break; case ENETUNREACH: strcpy(buffer, "*** Disconnected - 0D00 - Not Obtainable\r"); break; case EINTR: strcpy(buffer, "*** Disconnected - 3900 - Ship Absent\r"); break; default: sprintf(buffer, "*** Disconnected - %d - %s\r", errno, strerror(errno)); break; } close(s); if (verbose) { write(STDOUT_FILENO, buffer, strlen(buffer)); sleep(20); } return 0; } /* * We got there. */ alarm(0); if (verbose) { strcpy(buffer, "*** Connected\r"); write(STDOUT_FILENO, buffer, strlen(buffer)); } /* * Loop until one end of the connection goes away. */ for (;;) { FD_ZERO(&read_fd); FD_SET(STDIN_FILENO, &read_fd); FD_SET(s, &read_fd); select(s + 1, &read_fd, NULL, NULL, NULL); if (FD_ISSET(s, &read_fd)) { if ((n = read(s, buffer, 512)) == -1) { strcpy(buffer, "\r*** Disconnected - 0000 - DTE Originated\r"); write(STDOUT_FILENO, buffer, strlen(buffer)); break; } if (buffer[0] == 0) { /* Q Bit not set */ buffer[0] = 0xF0; write(STDOUT_FILENO, buffer, n); } else { /* Lose the leading 0x7F */ write(STDOUT_FILENO, buffer + 2, n - 2); } } if (FD_ISSET(STDIN_FILENO, &read_fd)) { if ((n = read(STDIN_FILENO, buffer + 2, sizeof(buffer)-2)) == -1) { close(s); break; } if (buffer[2] == 0xF0) { buffer[2] = 0; write(s, buffer + 2, n); } else { buffer[0] = 1; /* Set Q bit on */ buffer[1] = 0x7F; /* PID Escape */ write(s, buffer, n + 2); } } } closelog(); return 0; }
int nr_config_load_ports(void) { FILE *fp = NULL; char buffer[256], *s; int fd = -1, lineno = 1, n = 0, i; const char **calllist = NULL; const char **devlist = NULL; const char **pp; int callcount = 0; struct ifreq ifr; /* Reliable listing of all network ports on Linux is only available via reading /proc/net/dev ... */ if ((fd = socket(PF_FILE, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "nrconfig: unable to open socket (%s)\n", strerror(errno)); goto cleanup; } if ((fp = fopen("/proc/net/dev", "r"))) { /* Two header lines.. */ s = fgets(buffer, sizeof(buffer), fp); s = fgets(buffer, sizeof(buffer), fp); /* .. then network interface names */ while (!feof(fp)) { if (!fgets(buffer, sizeof(buffer), fp)) break; s = strchr(buffer, ':'); if (s) *s = 0; s = buffer; while (isspace(*s & 0xff)) ++s; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, s, IFNAMSIZ-1); ifr.ifr_name[IFNAMSIZ-1] = 0; if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { fprintf(stderr, "nrconfig: SIOCGIFHWADDR: %s\n", strerror(errno)); return FALSE; } if (ifr.ifr_hwaddr.sa_family != ARPHRD_NETROM) continue; /* store found interface callsigns */ /* ax25_ntoa() returns pointer to static buffer */ s = ax25_ntoa((void*)ifr.ifr_hwaddr.sa_data); if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { fprintf(stderr, "nrconfig: SIOCGIFFLAGS: %s\n", strerror(errno)); return FALSE; } if (!(ifr.ifr_flags & IFF_UP)) continue; if ((pp = realloc(calllist, sizeof(char *) * (callcount+2))) == 0) break; calllist = pp; if ((pp = realloc(devlist, sizeof(char *) * (callcount+2))) == 0) break; devlist = pp; if ((calllist[callcount] = strdup(s)) != NULL) { if ((devlist[callcount] = strdup(ifr.ifr_name)) != NULL) { ++callcount; calllist[callcount] = NULL; devlist [callcount] = NULL; } else { free((void*)calllist[callcount]); calllist[callcount] = NULL; devlist[callcount] = NULL; } } } fclose(fp); fp = NULL; } if ((fp = fopen(CONF_NRPORTS_FILE, "r")) == NULL) { fprintf(stderr, "nrconfig: unable to open nrports file %s (%s)\n", CONF_NRPORTS_FILE, strerror(errno)); goto cleanup; } while (fp && fgets(buffer, 255, fp)) { if ((s = strchr(buffer, '\n'))) *s = '\0'; if (strlen(buffer) > 0 && *buffer != '#') if (nr_config_init_port(fd, lineno, buffer, calllist, devlist)) n++; lineno++; } cleanup:; if (fd >= 0) close(fd); if (fp) fclose(fp); for(i = 0; calllist && calllist[i]; ++i) { free((void*)calllist[i]); if (devlist[i] != NULL) free((void*)devlist[i]); } if (calllist) free(calllist); if (devlist) free(devlist); if (nr_ports == NULL) return 0; return n; }
int main (int argc, char **argv) { char call[20]; char buf[2048]; int i, k, cnt, digits, letters, invalid, ssid, ssidcnt; unsigned int addrlen; int fdmaster; int identify = TRUE; pid_t pid = -1; fd_set fds_read; int chargc; char *chargv[20]; int envc; char *envp[20]; struct winsize win = {24, 80, 0, 0}; union { struct full_sockaddr_ax25 fsax25; struct full_sockaddr_rose rose; } sockaddr; char *protocol; cfg_t cfg; if ((argc > 1) && (strcmp(argv[1], "-n") == 0)) { identify = FALSE; --argc; ++argv; } digits = letters = invalid = ssid = ssidcnt = 0; openlog ("fpacshell", LOG_PID, LOG_DAEMON); addrlen = sizeof (struct full_sockaddr_ax25); memset(&sockaddr.rose, 0x00, sizeof(struct full_sockaddr_rose)); k = getpeername (0, (struct sockaddr *) &sockaddr, &addrlen); if (k == 0) { switch (sockaddr.fsax25.fsa_ax25.sax25_family) { case AF_AX25: strcpy (call, ax25_ntoa (&sockaddr.fsax25.fsa_ax25.sax25_call)); protocol = "AX.25"; paclen = AX_PACLEN; break; case AF_NETROM: strcpy (call, ax25_ntoa (&sockaddr.fsax25.fsa_ax25.sax25_call)); protocol = "NET/ROM"; paclen = NETROM_PACLEN; break; case AF_ROSE: strcpy (call, ax25_ntoa (&sockaddr.rose.srose_call)); protocol = "Rose"; paclen = ROSE_PACLEN; break; default: /* syslog (LOG_NOTICE, "peer is not an AX.25, NET/ROM or Rose socket\n"); */ strcpy (call, "UNKNOWN"); protocol = "SHELL"; crlf = 0; paclen = AX_PACLEN; break; } } else { strcpy (call, "UNKNOWN"); protocol = "SHELL"; crlf = 0; paclen = AX_PACLEN; } /* Get FPAC configuration */ if (cfg_open (&cfg) != 0) { write_ax25 (MSG_NOCFG, sizeof (MSG_NOCFG)); syslog (LOG_NOTICE, "FPAC configuration file not found\n"); sleep (EXITDELAY); return 1; } /* Check for MD password */ if ((identify) && (!md_check (&cfg))) return 2; if (argc == 1) { chargc = 0; chargv[chargc++] = user_shell; } else { /* int i;*/ for (i = 0 ; i < (argc-1) ; i++) { if (i == 20) break; chargv[i] = argv[i+1]; } chargc = argc-1; } chargv[chargc] = NULL; envc = 0; envp[envc] = (char *) malloc (30); sprintf (envp[envc++], "AXCALL=%s", call); envp[envc] = (char *) malloc (30); sprintf (envp[envc++], "PROTOCOL=%s", protocol); /* envp[envc] = (char *) malloc (30); sprintf (envp[envc++], "TERM=linux"); */ envp[envc] = NULL; fdmaster = pty_open(&pid, &win, chargv, envp); if (fdmaster == -1) return 4; if (pid != -1) { child_pid = 0; signal (SIGHUP, signal_handler); signal (SIGTERM, signal_handler); signal (SIGINT, signal_handler); signal (SIGQUIT, signal_handler); while (1) { FD_ZERO (&fds_read); FD_SET (0, &fds_read); FD_SET (fdmaster, &fds_read); k = select (fdmaster + 1, &fds_read, NULL, NULL, NULL); if (k > 0) { if (FD_ISSET (0, &fds_read)) { cnt = read_ax25 (buf, sizeof (buf)); if (cnt < 0) /* Connection died */ { break; } else write (fdmaster, buf, cnt); } if (FD_ISSET (fdmaster, &fds_read)) { cnt = read (fdmaster, buf, sizeof (buf)); if (cnt < 0) { break; } write_ax25 (buf, cnt); } } else if (k < 0 && errno != EINTR) { break; } } } else { syslog (LOG_ERR, "cannot fork %m, closing connection to %s\n", call); write_ax25 (MSG_CANNOTFORK, sizeof (MSG_CANNOTFORK)); sleep (EXITDELAY); return 1; } sleep (EXITDELAY); return 0; }