pkg://node-0.3.0-730.src.rpm:62445/node-0.3.0.tar.gz
info downloads
node-0.3.0/ 40755 764 764 0 6740166371 10227 5 ustar tpm tpm node-0.3.0/HISTORY 100644 764 764 16340 6740166365 11437 0 ustar tpm tpm 0.3.0 05 Jul 1999 - Initial version using the new dynamic libax25.
- Moved the IO code to libax25.
0.2.6 04 Feb 1999 - "Links *" doesn't crash anymore if someone
is listening on all ports.
- Added zlib based stream compression to the
io library. See -c option, zconnect command
and ztelnet command in node(8).
- Added signal handlers for SIGINT, SIGQUIT
and SIGSEGV.
- Node should now compile with glibc.
- Plugged a major security hole.
- Node sends a Goodbye message at logout.
- Adapted Links command for 2.1.x changes.
0.2.5 17 Nov 1997 - Small changes in the IO library. Connection
trough multiple LinuxNodes with mixed
protocols should now really be 8 bit clean.
- Added ResolveAddrs configuration command.
- French help files. Tnx Gerard (f6fgz).
- Added NLinks user command.
- Adapted for changes in procutils that permit
connecting to oneself.
- Added some #ifdef HAVExxx conditionals
to the code.
- Memory display might now work with later
2.1.xx kernels.
- Small bug fixed (read_perms() now closes the file).
- Nodeusers uses standard out for output.
- Some restructuring in nodeusers.c.
- Telnet and ax.25 port is printed and logged
in gateway connects.
- Added TTL to ping command output.
- Added sysop configurable prompt (see node.conf(5)).
- Rethink of the command parser. %-escapes and
C-style character literals (\n, \x1f etc.) are
now always parsed except when inside single
quotes ('). Alias and ExtCmd syntax has to
be slightly changed in node.conf (see the example
files).
- Added new %-escapes: %f, %h, %i.
- Added PIDs to mheard command output.
0.2.4 xx May 1997 - Added a user command Escape to set (or
disable) the escape character. Also
EscapeChar config command has now slightly
different syntax.
- Added syslogging to nodeusers
0.2.3 02 May 1997 - Hopefully fixed the "could not get IPC
channel" bug (SIGPIPE is now ignored).
- Not getting an IPC channel is no longer
a fatal error.
- Added a reconnect flag to extcmds. If
flag is set, user gets a prompt after the
extcmd is completed.
- The reason for program termination is now
logged.
- Added an escape mechanism to abort the
current gateway connection.
- NrPort now defaults to NULL ie. the first
netrom port.
- Extensive rewrite of the command parser.
- Aliases and ExtCmds now take positional
parameters. See node.conf(5).
- Telnet command now takes an optional third
argument that is sent to the remote host
right after the connection is established.
- Removed CAllbook command. It can now
be defined as an alias. See the supplied
sample configuration file.
- The DNIC part of a ROSE address now defaults
to the local DNIC in outgoing connects.
Tnx Jean-Paul (f6fbb).
- "nodeusers -i" now waits for a newline before
sending anything.
0.2.2 10 Feb 1997 - Fixed inverting of ssid (port name not
case sensitive anymore)
- Info file now in /etc/ax25/node.info
- Added installhelp target to the makefile.
0.2.1 29 Jan 1997 - Links command behaviour changed (by default
don't list listening sockets)
- A Talk command from Hessu (oh7lzb)
- Loggedin file size is tested at startup
0.2.0 05 Jan 1997 - Added separate nodeusers(1) program
- Added HOst and Status command (see node(8))
- General cleanup here and there
- Telnet command works even if written in
upper case...
- Mheard output format changed
- Logging. See LogLevel command in node.conf(5)
and the README file!!!
- Rose support (tnx Jonathan)
- Added NodeId command (see node.conf(5))
- HiddenPorts probably didn't work. It should now.
- Behaviour of getsockopt(...SOL_SOCKET,SO_ERROR...)
seems to have been changed again...
- The error message given when a connection fails
looks now more like the message given by thenet
and BPQ nodes (always contains the word "Failure").
- Node now sends /etc/ax25/node.motd after login
if it exists
- Correct paclen is now used also when node
isn't on the first netrom device
- NrPort command (see node.conf(5)) is now used
to define the port that is used for outgoing
netrom connects
0.1.12 21 Aug 1996 - Node doesn't need port name anymore (kernel
version 2.0.12 or later is needed for this to work)
- Added support for g4klx mheardd (mheard works
again)
0.1.11 06 Aug 1996 - SSID is now inverted only in outgoing AX.25
connections.
- find_link() now checks port too (procutils.c)
- Small bug in connect_to() fixed.
- First attempt at external command support
- User logging code slightly changed.
- Added "pinging" and "extcmd" states to
"users" command.
- "struct fdset" -> "fdset"
- Paclen defaults to 128 and port name to "unknown"
if no port or invalid port is given in node
command line (AX.25 only).
0.1.10 02 Jun 1996 - Bug in password routine fixed
- Changed syntax of node.perms
- Mheard, Links and Routes won't display
hidden ports anymore
- Added SIGTERM handler
- Some cleaning up in nodeuser.c
(login_user() now uses first free slot
found in loggedin file)
- Removed "speed" field from Ports command
(it isn't necessarily the speed of the
radio channel)
- Added "d" flag to Connect and Telnet
commands (useful for forward scripts).
- Wrote man pages. (node(8), node.conf(5)
and node.perms(5))
0.1.9 22 May 1996 - Argh. A typo in Routes fixed...
- More help texts (tnx Hessu OH7LZB)
- Fixed bug in alias handling
0.1.8 19 May 1996 - Routes shows active link also if the
link is recovering
- Small changes in procutils.c
- Behaviour of getsockopt(...SOL_SOCKET,SO_ERROR...)
seems to have been changed. A small fix in
connect_to()
- Empty node alias field now allowed (needs a
kernel patch to work)
0.1.7 16 May 1996 - Some polishing here and there
- Added "which" field to Nodes <node>
command
0.1.6 15 May 1996 - A small fix in procutils.c
- Added more comments in the sample
configuration files
0.1.5 14 May 1996 - Changed do_ports() to be compatible with
ax25-utils-2.0-ALPHA2
- Implemented hidden ports
- loopback network (127.xx.xx.xx) is now
always counted as "local" network
0.1.4 12 May 1996 - Typo in do_links() fixed
- Updated Links command for new kernels
- Extracted all /proc/net reading routines
into a separate procutils.c file
0.1.3 09 May 1996 - Adapted for the config changes in
ax25-utils-2.0-ALPHA1
- Added callsign validity check at login
- The ping bug _seems_ to be fixed now
0.1.2 08 May 1996 - Bug in do_nodes() with no known nodes fixed
- Small changes in io.c
- Some more comments added
- A few Makefile changes
- An obscure bug in do_ping found but not
yet fixed
0.1.1 May 1996 - Incoming/outgoing telnet support added
- Aliases added
- User priviledges per /usr/local/node/node.perms
added
- Finger and Callbook clients added
- LinuxNode can now be called from command line
- Links command added
0.1 Jan 1996 - First release version (not really released)
- Basic functionality
--
Tomi Manninen
OH2BNS@OH2RBI.FIN.EU
tomi.manninen@hut.fi
node-0.3.0/Makefile 100644 764 764 3760 6732002040 11751 0 ustar tpm tpm all: nodeusers node
CC = gcc
LD = gcc
CFLAGS = -Wall -Wstrict-prototypes -O2
LDFLAGS =
LIBS = -lax25 -lax25io
include Makefile.include
COMMON_SRC = user.c util.c
NODE_SRC = node.c cmdparse.c config.c command.c \
gateway.c extcmd.c sysinfo.c ipc.c
NODEUSERS_SRC = nodeusers.c
COMMON_OBJS = $(COMMON_SRC:.c=.o)
NODE_OBJS = $(NODE_SRC:.c=.o)
NODEUSERS_OBJS = $(NODEUSERS_SRC:.c=.o)
.c.o:
$(CC) $(CFLAGS) -c $<
install: installbin installman installhelp
install -m 755 -o root -g root -d $(VAR_DIR)/node
install -m 644 -o root -g root etc/loggedin $(VAR_DIR)/node
@rm -f /usr/bin/node
@rm -f /usr/bin/nodeusers
installbin: all
install -m 4755 -s -o root -g root node $(SBIN_DIR)
install -m 755 -s -o root -g root nodeusers $(SBIN_DIR)
installhelp:
install -m 755 -o root -g root -d $(LIB_DIR)/ax25/node/help
install -m 644 -o root -g root etc/help/*.hlp $(LIB_DIR)/ax25/node/help
installconf: installhelp
install -m 755 -o root -g root -d $(ETC_DIR)
install -m 600 -o root -g root etc/node.conf $(ETC_DIR)
install -m 600 -o root -g root etc/node.perms $(ETC_DIR)
install -m 600 -o root -g root etc/node.motd $(ETC_DIR)
installman:
install -m 644 -o bin -g bin man/nodeusers.1 $(MAN_DIR)/man1
install -m 644 -o bin -g bin man/node.conf.5 $(MAN_DIR)/man5
install -m 644 -o bin -g bin man/node.perms.5 $(MAN_DIR)/man5
install -m 644 -o bin -g bin man/node.8 $(MAN_DIR)/man8
clean:
rm -f *.o *~ *.bak *.orig
rm -f etc/*~ etc/*.bak etc/*.orig
rm -f etc/help/*~ etc/help/*.bak etc/help/*.orig
distclean: clean
rm -f .depend Makefile.include config.h
rm -f node nodeusers
depend:
$(CC) $(CFLAGS) -M $(COMMON_SRC) $(NODE_SRC) $(NODEUSERS_SRC) > .depend
node: $(COMMON_OBJS) $(NODE_OBJS)
$(LD) $(LDFLAGS) -o node $(COMMON_OBJS) $(NODE_OBJS) $(LIBS) $(ZLIB)
nodeusers: $(COMMON_OBJS) $(NODEUSERS_OBJS)
$(LD) $(LDFLAGS) -o nodeusers $(COMMON_OBJS) $(NODEUSERS_OBJS) $(LIBS) $(ZLIB)
ifeq (.depend,$(wildcard .depend))
include .depend
endif
node-0.3.0/README 100644 764 764 2732 6737174440 11212 0 ustar tpm tpm LinuxNode v0.3.0
Copyright (C) 1996,1997,1998,1999 by Tomi Manninen.
This is a simple node frontend for Linux kernel AX.25, NETROM,
ROSE and TCP. It's based on pms.c by Alan Cox (GW4PTS) but has been
heavily modified since. It's probably not very well tested, not
pretty, not very flexible and it is certainly not ready! However
I think it's already somewhat usable.
The installation instructions are in the file INSTALL.
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
TODO:
The manual pages need some work, some things have changed.
LocalNets should be a list of subnets, not one subnet plus 127/8.
Syslog facility and level should be configurable.
An option to sort the nodes listing by the callsign.
Lots of things (I suppose. Does anyone have any suggestions?).
--
Tomi Manninen OH2BNS, <tomi.manninen@hut.fi>
node-0.3.0/command.c 100644 764 764 37771 6726554402 12145 0 ustar tpm tpm #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include "kernel_ax25.h"
#include "kernel_rose.h"
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include <netax25/nrconfig.h>
#include <netax25/procutils.h>
#include <netax25/mheard.h>
#include "node.h"
#include "sysinfo.h"
struct cmd *Nodecmds = NULL;
void init_nodecmds(void)
{
add_internal_cmd(&Nodecmds, "?", 1, do_help);
add_internal_cmd(&Nodecmds, "Bye", 1, do_bye);
add_internal_cmd(&Nodecmds, "Connect", 1, do_connect);
add_internal_cmd(&Nodecmds, "Escape", 1, do_escape);
add_internal_cmd(&Nodecmds, "Finger", 1, do_finger);
add_internal_cmd(&Nodecmds, "Help", 1, do_help);
add_internal_cmd(&Nodecmds, "HOst", 2, do_host);
add_internal_cmd(&Nodecmds, "Info", 1, do_help);
add_internal_cmd(&Nodecmds, "Links", 1, do_links);
add_internal_cmd(&Nodecmds, "Mheard", 1, do_mheard);
#ifdef HAVE_NETROM
add_internal_cmd(&Nodecmds, "NLinks", 2, do_nlinks);
add_internal_cmd(&Nodecmds, "Nodes", 1, do_nodes);
#endif
add_internal_cmd(&Nodecmds, "PIng", 2, do_ping);
add_internal_cmd(&Nodecmds, "Ports", 1, do_ports);
#ifdef HAVE_NETROM
add_internal_cmd(&Nodecmds, "Routes", 1, do_routes);
#endif
add_internal_cmd(&Nodecmds, "Status", 1, do_status);
add_internal_cmd(&Nodecmds, "TAlk", 2, do_talk);
add_internal_cmd(&Nodecmds, "Telnet", 1, do_connect);
add_internal_cmd(&Nodecmds, "Users", 1, do_users);
#ifdef HAVE_ZLIB_H
add_internal_cmd(&Nodecmds, "ZConnect", 1, do_connect);
add_internal_cmd(&Nodecmds, "ZTelnet", 1, do_connect);
#endif
};
void logout(char *reason)
{
axio_end_all();
logout_user();
ipc_close();
log(L_LOGIN, "%s @ %s logged out: %s", User.call, User.ul_name, reason);
free_cmdlist(Nodecmds);
Nodecmds = NULL;
exit(0);
}
int do_bye(int argc, char **argv)
{
node_msg("Goodbye");
logout("Bye");
return 0; /* Keep gcc happy */
}
int do_escape(int argc, char **argv)
{
int now = 0;
if (argc > 1) {
EscChar = get_escape(argv[1]);
now = 1;
}
if (EscChar < -1 || EscChar > 255) {
node_msg("Invalid escape character: %s", argv[1]);
return 0;
}
if (EscChar == -1) {
node_msg("The escape mechanism is %sdisabled",
now ? "now " : "");
return 0;
}
node_msg("The escape character is %s%s%c",
now ? "now " : "",
EscChar < 32 ? "CTRL-" : "",
EscChar < 32 ? (EscChar + 'A' - 1) : EscChar);
return 0;
}
struct mheard_list {
struct mheard_struct data;
struct mheard_list *next;
};
int do_mheard(int argc, char **argv)
{
FILE *fp;
struct mheard_struct mh;
struct mheard_list *list, *new, *tmp, *p;
char *s, *t, *u;
long ti;
if (argc < 2) {
node_msg("Usage: mheard <port>");
return 0;
}
if (ax25_config_get_dev(argv[1]) == NULL ||
(check_perms(PERM_HIDDEN, 0) == -1 && is_hidden(argv[1]))) {
node_msg("Invalid port");
return 0;
}
if ((fp = fopen(DATA_MHEARD_FILE, "r")) == NULL) {
node_perror(DATA_MHEARD_FILE, errno);
return 0;
}
list = NULL;
while (fread(&mh, sizeof(struct mheard_struct), 1, fp) == 1) {
if (strcmp(argv[1], mh.portname))
continue;
if ((new = calloc(1, sizeof(struct mheard_list))) == NULL) {
node_perror("do_mheard: calloc", errno);
break;
}
new->data = mh;
if (list == NULL || mh.last_heard > list->data.last_heard) {
tmp = list;
list = new;
new->next = tmp;
} else {
for (p = list; p->next != NULL; p = p->next)
if (mh.last_heard > p->next->data.last_heard)
break;
tmp = p->next;
p->next = new;
new->next = tmp;
}
}
fclose(fp);
node_msg("Heard list for port %s:", argv[1]);
nputs("Callsign Frames Last heard Pids\n");
while (list != NULL) {
s = ctime(&list->data.last_heard);
s[19] = 0;
s += 4;
t = ax25_ntoa(&list->data.from_call);
if ((u = strstr(t, "-0")) != NULL)
*u = '\0';
nprintf("%-9s %-8ld %s (", t, list->data.count, s);
ti = time(NULL) - list->data.last_heard;
if (ti < 60L)
nprintf(" %2lds", ti);
else if (ti < 3600L)
nprintf("%2ldm %2lds", ti / 60L, ti % 60L);
else if (ti < 86400L)
nprintf("%2ldh %2ldm", ti / 3600L, (ti % 3600L) / 60L);
else
nprintf("%2ldd %2ldh", ti / 86400L, (ti % 86400L) / 3600L);
nputs(" ago) ");
if (list->data.mode & MHEARD_MODE_ARP)
nprintf(" ARP");
if (list->data.mode & MHEARD_MODE_FLEXNET)
nprintf(" FlexNet");
if (list->data.mode & MHEARD_MODE_IP_DG)
nprintf(" IP-DG");
if (list->data.mode & MHEARD_MODE_IP_VC)
nprintf(" IP-VC");
if (list->data.mode & MHEARD_MODE_NETROM)
nprintf(" NET/ROM");
if (list->data.mode & MHEARD_MODE_ROSE)
nprintf(" Rose");
if (list->data.mode & MHEARD_MODE_SEGMENT)
nprintf(" Segment");
if (list->data.mode & MHEARD_MODE_TEXNET)
nprintf(" TexNet");
if (list->data.mode & MHEARD_MODE_TEXT)
nprintf(" Text");
if (list->data.mode & MHEARD_MODE_PSATFT)
nprintf(" PacsatFT");
if (list->data.mode & MHEARD_MODE_PSATPB)
nprintf(" PacsatPB");
if (list->data.mode & MHEARD_MODE_UNKNOWN)
nprintf(" Unknown");
nputs("\n");
tmp = list;
list = list->next;
free(tmp);
}
return 0;
}
int do_help(int argc, char **argv)
{
FILE *fp;
char fname[80], line[256];
struct cmd *cmdp;
int i = 0;
if (*argv[0] == '?') { /* "?" */
node_msg("Commands:");
for (cmdp = Nodecmds; cmdp != NULL; cmdp = cmdp->next) {
nprintf("%s%s", i ? ", " : "", cmdp->name);
if (++i == 10) {
nprintf("\n");
i = 0;
}
}
if (i) nprintf("\n");
return 0;
}
strcpy(fname, DATA_NODE_HELP_DIR);
if (*argv[0] == 'i') { /* "info" */
strcpy(fname, CONF_NODE_INFO_FILE);
node_msg("%s", VERSION);
} else if (argc == 1) { /* "help" */
strcat(fname, "help.hlp");
} else { /* "help <cmd>" */
if (strchr(argv[1], '/') == NULL) {
strlwr(argv[1]);
strcat(fname, argv[1]);
strcat(fname, ".hlp");
}
}
if ((fp = fopen(fname, "r")) == NULL) {
if (*argv[0] != 'i')
node_msg("No help for command %s", argv[1] ? argv[1] : "help");
return 0;
}
if (*argv[0] != 'i')
node_msg("Help for command %s", argv[1] ? argv[1] : "help");
while (fgets(line, 256, fp) != NULL)
nputs(line);
nputs("\n-- \n");
fclose(fp);
return 0;
}
int do_host(int argc, char **argv)
{
struct hostent *h;
struct in_addr addr;
char **p;
if (argc < 2) {
node_msg("Usage: host <hostname>|<ip address>");
return 0;
}
if (inet_aton(argv[1], &addr) != 0)
h = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
else
h = gethostbyname(argv[1]);
if (h == NULL) {
node_msg("%s", strherror(h_errno));
return 0;
}
node_msg("Host name information for %s:", argv[1]);
nprintf("Hostname: %s\n", h->h_name);
nputs("Aliases: ");
p = h->h_aliases;
while (*p != NULL) {
nprintf(" %s", *p);
p++;
}
nputs("\nAddress(es):");
p = h->h_addr_list;
while (*p != NULL) {
addr.s_addr = ((struct in_addr *)(*p))->s_addr;
nprintf(" %s", inet_ntoa(addr));
p++;
}
nputs("\n");
return 0;
}
int do_ports(int argc, char **argv)
{
char *cp = NULL;
node_msg("Ports:\nPort Description");
while ((cp = ax25_config_get_next(cp)) != NULL) {
if (is_hidden(cp) && check_perms(PERM_HIDDEN, 0L) == -1)
continue;
nprintf("%-6s %s\n", cp, ax25_config_get_desc(cp));
}
return 0;
}
int do_links(int argc, char **argv)
{
struct proc_ax25 *p, *list;
char *cp;
node_msg("AX.25 Link Status:");
if ((list = read_proc_ax25()) == NULL) {
if (errno)
node_perror("do_links: read_proc_ax25:", errno);
return 0;
}
nprintf("Port Remote Local State Unack T1 Retr Rtt Snd-Q Rcv-Q\n");
for (p = list; p != NULL; p = p->next) {
if (argc > 1 && strcasecmp(argv[1], "*") && strcasecmp(p->dest_addr, argv[1]) && strcasecmp(p->src_addr, argv[1]))
continue;
if ((argc < 2) && !strcmp(p->dest_addr, "*"))
continue;
if (strcmp(p->dev, "???") != 0) {
cp = ax25_config_get_name(p->dev);
if (is_hidden(cp) && check_perms(PERM_HIDDEN, 0L) == -1)
continue;
} else
cp = "*";
nprintf("%-6s ", cp);
nprintf("%-9s %-9s ", p->dest_addr, p->src_addr);
#if 0
nprintf("%-9s", p->dest_addr);
for (i = 0; i < p->ndigi; i++) {
if (i == 0)
nprintf(" via ");
else
nprintf(",");
nprintf("%s", p->digi_addr[i]);
}
nprintf(" %-9s ", p->src_addr);
#endif
if (!strcmp(p->dest_addr, "*")) {
nprintf("Listening\n");
continue;
}
switch (p->st) {
case 0:
nputs("Disconnected ");
break;
case 1:
nputs("Conn pending ");
break;
case 2:
nputs("Disc pending ");
break;
case 3:
nputs("Connected ");
break;
case 4:
nputs("Recovery ");
break;
default:
nputs("Unknown ");
break;
}
nprintf("%02d/%02d %03d/%03d %02d/%02d %-3d %-5d %-5d\n",
p->vs < p->va ? p->vs - p->va + 8 : p->vs - p->va,
p->window,
p->t1timer, p->t1,
p->n2count, p->n2,
p->rtt,
p->sndq, p->rcvq);
}
free_proc_ax25(list);
return 0;
}
#ifdef HAVE_NETROM
int do_nlinks(int argc, char **argv)
{
struct proc_nr *p, *list;
char *cp;
node_msg("NET/ROM Link Status:");
if ((list = read_proc_nr()) == NULL) {
if (errno)
node_perror("do_links: read_proc_nr:", errno);
return 0;
}
nprintf("User Remote Local State My id Ur id Unack T1 N2 Snd-Q\n");
for (p = list; p != NULL; p = p->next) {
cp = nr_config_get_name(p->dev);
if (is_hidden(cp) && check_perms(PERM_HIDDEN, 0L) == -1)
continue;
nprintf("%-9s %-9s %-9s ", p->user_addr, p->dest_node, p->src_node);
if (!strcmp(p->user_addr, "*")) {
nprintf("Listening\n");
continue;
}
switch (p->st) {
case 0:
nputs("Disconnected ");
break;
case 1:
nputs("Conn pending ");
break;
case 2:
nputs("Disc pending ");
break;
case 3:
nputs("Connected ");
break;
default:
nputs("Unknown ");
break;
}
nprintf("%s %s ", p->my_circuit, p->ur_circuit);
nprintf("%02d/%02d %03d/%03d %d/%d %-5d\n",
p->vs < p->va ? p->vs - p->va + 256 : p->vs - p->va,
p->window,
p->t1timer, p->t1,
p->n2count, p->n2,
p->sndq);
}
free_proc_nr(list);
return 0;
}
int do_routes(int argc, char **argv)
{
struct proc_nr_neigh *p, *list;
struct proc_ax25 *ap;
char *cp;
int link;
node_msg("Routes:\nLink Port Callsign Quality Destinations Lock");
if ((list = read_proc_nr_neigh()) == NULL) {
if (errno)
node_perror("do_routes: read_proc_nr_neigh", errno);
return 0;
}
for (p = list; p != NULL; p = p->next) {
cp = ax25_config_get_name(p->dev);
if (is_hidden(cp) && check_perms(PERM_HIDDEN, 0L) == -1)
continue;
if ((ap = find_link(nr_config_get_addr(NULL), p->call, p->dev)) != NULL && ap->st >= 3)
link = 1;
else
link = 0;
nprintf("%c %-6s %-9s %-7d %-12d %c\n",
link == 1 ? '>' : ' ',
cp,
p->call,
p->qual,
p->cnt,
p->lock == 1 ? '!' : ' ');
}
free_proc_nr_neigh(list);
return 0;
}
int do_nodes(int argc, char **argv)
{
struct proc_nr_nodes *p, *list;
struct proc_nr_neigh *np, *nlist;
int i = 0;
if ((list = read_proc_nr_nodes()) == NULL) {
if (errno)
node_perror("do_nodes: read_proc_nr_nodes", errno);
else
node_msg("No known nodes");
return 0;
}
/* "nodes" */
if (argc == 1) {
node_msg("Nodes:");
for (p = list; p != NULL; p = p->next) {
nprintf("%-16.16s %c",
print_node(p->alias, p->call),
(++i % 4) ? ' ' : '\n');
}
if ((i % 4) != 0) nprintf("\n");
free_proc_nr_nodes(list);
return 0;
}
if ((nlist = read_proc_nr_neigh()) == NULL) {
node_perror("do_nodes: read_proc_nr_neigh", errno);
return 0;
}
/* "nodes *" */
if (*argv[1] == '*') {
node_msg("Nodes:");
nprintf("Node Quality Obsolescence Port Neighbour\n");
for (p = list; p != NULL; p = p->next) {
nprintf("%-16.16s ", print_node(p->alias, p->call));
/*
* p->n == 0 indicates a local node with no routes.
*/
if (p->n > 0 && (np = find_neigh(p->addr1, nlist)) != NULL) {
nprintf("%-7d %-12d %-6s %s",
p->qual1, p->obs1,
ax25_config_get_name(np->dev),
np->call);
}
nprintf("\n");
if (p->n > 1 && (np = find_neigh(p->addr2, nlist)) != NULL) {
nprintf(" ");
nprintf("%-7d %-12d %-6s %s\n",
p->qual2, p->obs2,
ax25_config_get_name(np->dev),
np->call);
}
if (p->n > 2 && (np = find_neigh(p->addr3, nlist)) != NULL) {
nprintf(" ");
nprintf("%-7d %-12d %-6s %s\n",
p->qual3, p->obs3,
ax25_config_get_name(np->dev),
np->call);
}
}
free_proc_nr_nodes(list);
free_proc_nr_neigh(nlist);
return 0;
}
/* "nodes <node>" */
p = find_node(argv[1], list);
if (p != NULL && p->n == 0) {
node_msg("%s is a local node", print_node(p->alias, p->call));
} else if (p != NULL) {
node_msg("Routes to: %s", print_node(p->alias, p->call));
nprintf("Which Quality Obsolescence Port Neighbour\n");
if (p->n > 0 && (np = find_neigh(p->addr1, nlist)) != NULL) {
nprintf("%c %-7d %-12d %-6s %s\n",
p->w == 1 ? '>' : ' ',
p->qual1, p->obs1,
ax25_config_get_name(np->dev),
np->call);
}
if (p->n > 1 && (np = find_neigh(p->addr2, nlist)) != NULL) {
nprintf("%c %-7d %-12d %-6s %s\n",
p->w == 2 ? '>' : ' ',
p->qual2, p->obs2,
ax25_config_get_name(np->dev),
np->call);
}
if (p->n > 1 && (np = find_neigh(p->addr3, nlist)) != NULL) {
nprintf("%c %-7d %-12d %-6s %s\n",
p->w == 3 ? '>' : ' ',
p->qual3, p->obs3,
ax25_config_get_name(np->dev),
np->call);
}
} else {
node_msg("No such node");
}
free_proc_nr_nodes(list);
free_proc_nr_neigh(nlist);
return 0;
}
#endif /* HAVE_NETROM */
/*
* by Heikki Hannikainen <hessu@pspt.fi>
* The following was mostly learnt from the procps package and the
* gnu sh-utils (mainly uname).
*/
int do_status(int argc, char **argv)
{
int upminutes, uphours, updays;
double uptime_secs;
double av[3];
struct utsname name;
time_t t;
#ifdef HAVE_NETROM
struct proc_nr_nodes *nop, *nolist;
struct proc_nr_neigh *nep, *nelist;
int n;
#endif
node_msg("Status:");
time(&t);
nprintf("System time: %s", ctime(&t));
if (uname(&name) == -1)
nprintf("Cannot get system name\n");
else {
nprintf("Hostname: %s\n", name.nodename);
nprintf("Operating system: %s %s (%s)\n",
name.sysname, name.release, name.machine);
}
/* read and calculate the amount of uptime and format it nicely */
uptime(&uptime_secs, NULL);
updays = (int) uptime_secs / (60*60*24);
upminutes = (int) uptime_secs / 60;
uphours = upminutes / 60;
uphours = uphours % 24;
upminutes = upminutes % 60;
nprintf("Uptime: ");
if (updays)
nprintf("%d day%s, ", updays, (updays != 1) ? "s" : "");
if(uphours)
nprintf("%d hour%s ", uphours, (uphours != 1) ? "s" : "");
nprintf("%d minute%s\n", upminutes, (upminutes != 1) ? "s" : "");
loadavg(&av[0], &av[1], &av[2]);
nprintf("Load average: %.2f, %.2f, %.2f\n", av[0], av[1], av[2]);
if (load_meminfo()) {
nputs("Memory: ");
nprintf("%5d KB available, %5d KB used, %5d KB free\n",
meminfo("memtotal"),
meminfo("memtotal") - meminfo("memfree") -
meminfo("buffers") - meminfo("cached"),
meminfo("memfree") + meminfo("buffers") +
meminfo("cached"));
nputs("Swap: ");
nprintf("%5d KB available, %5d KB used, %5d KB free\n",
meminfo("swaptotal"),
meminfo("swaptotal") - meminfo("swapfree"),
meminfo("swapfree"));
}
#ifdef HAVE_NETROM
if ((nolist = read_proc_nr_nodes()) == NULL && errno != 0)
node_perror("do_status: read_proc_nr_nodes", errno);
n = 0;
for (nop = nolist; nop != NULL; nop = nop->next)
n++;
free_proc_nr_nodes(nolist);
nprintf("Nodes: %d\n", n);
if ((nelist = read_proc_nr_neigh()) == NULL && errno != 0)
node_perror("do_status: read_proc_nr_neigh", errno);
n = 0;
for (nep = nelist; nep != NULL; nep = nep->next)
n++;
free_proc_nr_neigh(nelist);
nprintf("Routes: %d\n", n);
#endif
return 0;
}
node-0.3.0/config.c 100644 764 764 21372 6726554402 11762 0 ustar tpm tpm #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pwd.h>
#include "kernel_ax25.h"
#include "kernel_rose.h"
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include "node.h"
long IdleTimeout = 900L; /* default to 15 mins */
long ConnTimeout = 3600L; /* default to 60 mins */
int ReConnectTo = 0;
int ResolveAddrs = 0;
int LogLevel = L_ERROR;
int EscChar = 20; /* CTRL-T */
char *HostName = NULL;
char *NodeId = "LinuxNode}";
char *NodePrompt = "\n";
char *NrPort = NULL; /* first netrom port */
static unsigned long Permissions = 0L;
static unsigned long LocalNet = 0L;
static unsigned long LocalMask = ~0L;
static char *HiddenPorts[32] = {0};
/*
* Return non-zero if `port' is a hidden port.
*/
int is_hidden(const char *port)
{
int i;
for (i = 0; HiddenPorts[i] != NULL && i < 31; i++)
if (!strcmp(port, HiddenPorts[i]))
return 1;
return 0;
}
/*
* Return non-zero if peer is on "local" or loopback network.
*/
static int is_local(unsigned long peer)
{
return ((peer & LocalMask) == LocalNet) || ((peer & 0xff) == 127);
}
/*
* Return non-zero if peer is on amprnet.
*/
static int is_ampr(unsigned long peer)
{
return ((peer & 0xff) == 44);
}
/*
* Convert NOS style width to a netmask in network byte order.
*/
static unsigned long bits_to_mask(int bits)
{
return htonl(~0L << (32 - bits));
}
int check_perms(int what, unsigned long peer)
{
if (what == PERM_TELNET) {
if (is_local(peer)) {
if (Permissions & PERM_TELNET_LOCAL)
return 0;
} else if (is_ampr(peer)) {
if (Permissions & PERM_TELNET_AMPR)
return 0;
} else {
if (Permissions & PERM_TELNET_INET)
return 0;
}
return -1;
}
if ((Permissions & what) == 0) {
return -1;
}
return 0;
}
/*
* Read permissions file and return a password if needed or "*" if not.
* If user access is denied return NULL.
*/
char *read_perms(struct user *up, unsigned long peer)
{
FILE *fp;
char line[256], *argv[32], *cp, *pw;
int argc, n = 0;
if ((fp = fopen(CONF_NODE_PERMS_FILE, "r")) == NULL) {
node_perror(CONF_NODE_PERMS_FILE, errno);
return NULL;
}
if ((cp = strchr(up->call, '-')) != NULL)
*cp = 0;
pw = NULL;
while (fgets(line, 256, fp) != NULL) {
n++;
argc = parse_args(argv, line);
if (argc == 0 || *argv[0] == '#')
continue;
if (argc != 5) {
node_msg("Configuration error");
log(L_ERROR, "Syntax error in permission file at line %d", n);
break;
}
if (strcmp(argv[0], "*") && strcasecmp(argv[0], up->call))
continue;
switch (up->ul_type) {
case AF_AX25:
if (!strcmp(argv[1], "*"))
break;
if (!strcasecmp(argv[1], "ax25"))
break;
continue;
case AF_NETROM:
if (!strcmp(argv[1], "*"))
break;
if (!strcasecmp(argv[1], "netrom"))
break;
continue;
case AF_ROSE:
if (!strcmp(argv[1], "*"))
break;
if (!strcasecmp(argv[1], "rose"))
break;
continue;
case AF_INET:
if (!strcmp(argv[1], "*"))
break;
if (!strcasecmp(argv[1], "local") && is_local(peer))
break;
if (!strcasecmp(argv[1], "ampr") && is_ampr(peer))
break;
if (!strcasecmp(argv[1], "inet") && !is_local(peer) && !is_ampr(peer))
break;
continue;
case AF_UNSPEC:
if (!strcmp(argv[1], "*"))
break;
if (!strcasecmp(argv[1], "host"))
break;
continue;
}
if (up->ul_type == AF_AX25) {
if (strcmp(argv[2], "*") && strcmp(argv[2], up->ul_name))
continue;
}
if (cp != NULL)
*cp = '-';
if ((Permissions = strtoul(argv[4], NULL, 10)) != 0)
pw = strdup(argv[3]);
break;
}
fclose(fp);
return pw;
}
static int do_alias(int argc, char **argv)
{
struct cmd *new;
int len = 0;
if (argc < 3)
return -1;
if ((new = calloc(1, sizeof(struct cmd))) == NULL) {
node_perror("do_alias: malloc", errno);
return -2;
}
new->name = strdup(argv[1]);
while (isupper(new->name[len]))
len++;
/* Ok. So they can't read... */
if (len == 0) {
strupr(new->name);
len = strlen(new->name);
}
new->len = len;
new->command = strdup(argv[2]);
new->type = CMD_ALIAS;
insert_cmd(&Nodecmds, new);
return 0;
}
static int do_loglevel(int argc, char **argv)
{
if (argc < 2)
return -1;
LogLevel = atoi(argv[1]);
return 0;
}
int get_escape(char *s)
{
int escape;
char *endptr[1];
if (isdigit(*s)) {
escape = strtol(s, endptr, 0);
if (**endptr)
return -2;
else
return escape;
}
if (strlen(s) == 1)
return *s;
if (strlen(s) == 2 && *s == '^')
return (toupper(*++s) - 'A' + 1);
if (strcasecmp(s, "off") == 0 || strcmp(s, "-1") == 0)
return -1;
return -2;
}
static int do_escapechar(int argc, char **argv)
{
if (argc < 2)
return -1;
EscChar = get_escape(argv[1]);
if (EscChar < -1 || EscChar > 255) {
node_msg("Configuration error");
log(L_ERROR, "do_escapechar: Invalid escape character %s",
argv[1]);
return -2;
}
return 0;
}
static int do_idletimeout(int argc, char **argv)
{
if (argc < 2)
return -1;
IdleTimeout = atol(argv[1]);
return 0;
}
static int do_conntimeout(int argc, char **argv)
{
if (argc < 2)
return -1;
ConnTimeout = atol(argv[1]);
return 0;
}
static int do_hostname(int argc, char **argv)
{
if (argc < 2)
return -1;
HostName = strdup(argv[1]);
return 0;
}
static int do_localnet(int argc, char **argv)
{
char *cp;
if (argc < 2)
return -1;
if ((cp = strchr(argv[1], '/')) != NULL) {
*cp = 0;
LocalMask = bits_to_mask(atoi(++cp));
}
LocalNet = inet_addr(argv[1]);
LocalNet &= LocalMask;
return 0;
}
static int do_reconnect(int argc, char **argv)
{
if (argc < 2)
return -1;
if (!strcasecmp(argv[1], "on"))
ReConnectTo = 1;
else
ReConnectTo = 0;
return 0;
}
static int do_resolveaddrs(int argc, char **argv)
{
if (argc < 2)
return -1;
if (!strcasecmp(argv[1], "on"))
ResolveAddrs = 1;
else
ResolveAddrs = 0;
return 0;
}
static int do_hiddenports(int argc, char **argv)
{
int i;
if (argc < 2)
return -1;
for (i = 1; i < argc && i < 31; i++) {
if (ax25_config_get_dev(argv[i]) == NULL) {
node_msg("Configuration error");
log(L_ERROR, "do_hiddenports: invalid port %s", argv[i]);
return -2;
}
HiddenPorts[i - 1] = strdup(argv[i]);
}
HiddenPorts[i - 1] = NULL;
return 0;
}
static int do_extcmd(int argc, char **argv)
{
struct cmd *new;
struct passwd *pw;
char buf[1024];
int i, len;
if (argc < 6)
return -1;
if ((new = calloc(1, sizeof(struct cmd))) == NULL) {
node_perror("do_extcmd: malloc", errno);
return -2;
}
new->name = strdup(argv[1]);
len = 0;
while (isupper(new->name[len]))
len++;
/* Ok. So they can't read... */
if (len == 0) {
strupr(new->name);
len = strlen(new->name);
}
new->len = len;
new->flags = atoi(argv[2]);
if ((pw = getpwnam(argv[3])) == NULL) {
node_msg("Configuration error");
log(L_ERROR, "do_extcmd: Unknown user %s", argv[3]);
return -2;
}
new->uid = pw->pw_uid;
new->gid = pw->pw_gid;
new->path = strdup(argv[4]);
len = 0;
for (i = 0; argv[i + 5] != NULL; i++)
len += sprintf(&buf[len], "\"%s\" ", argv[i + 5]);
new->command = strdup(buf);
new->type = CMD_EXTERNAL;
insert_cmd(&Nodecmds, new);
return 0;
}
static int do_nodeid(int argc, char **argv)
{
if (argc < 2)
return -1;
NodeId = strdup(argv[1]);
return 0;
}
static int do_nodeprompt(int argc, char **argv)
{
if (argc < 2)
return -1;
NodePrompt = strdup(argv[1]);
return 0;
}
static int do_nrport(int argc, char **argv)
{
if (argc < 2)
return -1;
NrPort = strdup(argv[1]);
return 0;
}
int read_config(void)
{
struct cmd *cfg_cmds = NULL;
FILE *fp;
char line[256];
int ret, n = 0;
add_internal_cmd(&cfg_cmds, "alias", 0, do_alias);
add_internal_cmd(&cfg_cmds, "conntimeout", 0, do_conntimeout);
add_internal_cmd(&cfg_cmds, "escapechar", 0, do_escapechar);
add_internal_cmd(&cfg_cmds, "extcmd", 0, do_extcmd);
add_internal_cmd(&cfg_cmds, "hiddenports", 0, do_hiddenports);
add_internal_cmd(&cfg_cmds, "hostname", 0, do_hostname);
add_internal_cmd(&cfg_cmds, "idletimeout", 0, do_idletimeout);
add_internal_cmd(&cfg_cmds, "localnet", 0, do_localnet);
add_internal_cmd(&cfg_cmds, "loglevel", 0, do_loglevel);
add_internal_cmd(&cfg_cmds, "nodeid", 0, do_nodeid);
add_internal_cmd(&cfg_cmds, "nodeprompt", 0, do_nodeprompt);
add_internal_cmd(&cfg_cmds, "nrport", 0, do_nrport);
add_internal_cmd(&cfg_cmds, "reconnect", 0, do_reconnect);
add_internal_cmd(&cfg_cmds, "resolveaddrs", 0, do_resolveaddrs);
if ((fp = fopen(CONF_NODE_FILE, "r")) == NULL) {
node_perror(CONF_NODE_FILE, errno);
return -1;
}
while (fgets(line, 256, fp) != NULL) {
n++;
ret = cmdparse(cfg_cmds, line);
if (ret == -1) {
node_msg("Configuration error");
log(L_ERROR, "Syntax error in config file at line %d: %s", n, line);
}
if (ret < 0) {
fclose(fp);
return -1;
}
}
fclose(fp);
free_cmdlist(cfg_cmds);
cfg_cmds = NULL;
return 0;
}
node-0.3.0/extcmd.c 100644 764 764 6712 6726554402 11762 0 ustar tpm tpm #include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "kernel_ax25.h" /* axutils.h needs this... */
#include "kernel_rose.h"
#include <grp.h>
#include <sys/wait.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include "node.h"
#define ECMD_PIPE 1 /* Run through pipe */
#define ECMD_RECONN 2 /* */
static int norm_extcmd(struct cmd *cmdp, char **argv)
{
int pid;
alarm(0L);
pid = fork();
if (pid == -1) {
/* fork error */
node_perror("norm_extcmd: fork", errno);
return 0;
}
if (pid == 0) {
/* child */
setgroups(0, NULL);
setgid(cmdp->gid);
setuid(cmdp->uid);
execve(cmdp->path, argv, NULL);
node_perror("norm_extcmd: execve", errno);
exit(1);
}
/* parent */
waitpid(pid, NULL, 0);
return 0;
}
static int pipe_extcmd(struct cmd *cmdp, char **argv)
{
ax25io *iop;
int pipe_in[2], pipe_out[2];
int pid, c;
fd_set fdset;
if (pipe(pipe_in) == -1) {
node_perror("pipe_extcmd: pipe_in", errno);
return 0;
}
if (pipe(pipe_out) == -1) {
node_perror("pipe_extcmd: pipe_out", errno);
return 0;
}
signal(SIGCHLD, SIG_IGN);
pid = fork();
if (pid == -1) {
/* fork error */
node_perror("pipe_extcmd: fork", errno);
signal(SIGCHLD, SIG_DFL);
return 0;
}
if (pid == 0) {
/* child */
/*
* Redirect childs output to the pipes closing
* stdin/out/err as we go.
*/
dup2(pipe_in[0], STDIN_FILENO);
dup2(pipe_out[1], STDOUT_FILENO);
dup2(pipe_out[1], STDERR_FILENO);
/* Close the other ends */
close(pipe_in[1]);
close(pipe_out[0]);
setgroups(0, NULL);
setgid(cmdp->gid);
setuid(cmdp->uid);
execve(cmdp->path, argv, NULL);
perror("pipe_extcmd: execve");
exit(1);
}
/* parent */
close(pipe_in[0]);
close(pipe_out[1]);
if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1 ||
fcntl(pipe_out[0], F_SETFL, O_NONBLOCK) == -1) {
node_perror("pipe_extcmd: fcntl - pipe_out", errno);
goto end;
}
iop = axio_init(pipe_out[0], pipe_in[1], 1024, UNSPEC_EOL);
if (iop == NULL) {
node_perror("pipe_extcmd: Error initializing I/O", -1);
goto end;
}
while (1) {
FD_ZERO(&fdset);
FD_SET(STDIN_FILENO, &fdset);
FD_SET(pipe_out[0], &fdset);
if (select(32, &fdset, 0, 0, 0) == -1) {
node_perror("pipe_extcmd: select", errno);
break;
}
if (FD_ISSET(STDIN_FILENO, &fdset)) {
alarm(ConnTimeout);
while((c = axio_getc(NodeIo)) != -1)
axio_putc(c, iop);
if (errno != EAGAIN)
break;
}
if (FD_ISSET(pipe_out[0], &fdset)) {
alarm(ConnTimeout);
while((c = axio_getc(iop)) != -1)
axio_putc(c, NodeIo);
if (errno != EAGAIN) {
if (errno)
node_msg("%s", strerror(errno));
break;
}
}
axio_flush(NodeIo);
axio_flush(iop);
}
axio_end(iop);
end:
signal(SIGCHLD, SIG_DFL);
kill(pid, SIGKILL);
close(pipe_in[1]);
close(pipe_out[0]);
if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1)
node_perror("pipe_extcmd: fcntl - stdin", errno);
return 0;
}
int extcmd(struct cmd *cmdp, char **argv)
{
int ret;
User.state = STATE_EXTCMD;
User.dl_type = AF_UNSPEC;
strcpy(User.dl_name, cmdp->name);
strupr(User.dl_name);
update_user();
if (cmdp->flags & ECMD_PIPE)
ret = pipe_extcmd(cmdp, argv);
else
ret = norm_extcmd(cmdp, argv);
if (cmdp->flags & ECMD_RECONN)
node_msg("Reconnected to %s", HostName);
return ret;
}
node-0.3.0/gateway.c 100644 764 764 43350 6726554402 12156 0 ustar tpm tpm #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "kernel_ax25.h"
#include "kernel_rose.h"
#include <netinet/ip_icmp.h>
#include <netinet/ip.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include <netax25/nrconfig.h>
#include <netax25/rsconfig.h>
#include <netax25/procutils.h>
#include "node.h"
static void invert_ssid(char *out, char *in)
{
char *cp;
if ((cp = strchr(in, '-')) != NULL) {
*cp = 0;
sprintf(out, "%s-%d", in, 15 - atoi(cp + 1));
*cp = '-';
} else {
sprintf(out, "%s-15", in);
}
}
/*
* Initiate a AX.25, NET/ROM, ROSE or TCP connection to the host
* specified by `address'.
*/
static ax25io *connect_to(char **addr, int family, int escape, int compr)
{
int fd;
ax25io *riop;
fd_set read_fdset;
fd_set write_fdset;
int salen;
union {
struct full_sockaddr_ax25 ax;
struct sockaddr_rose rs;
struct sockaddr_in in;
} sa;
struct in_addr inaddr;
char call[10], path[20], *cp, *eol;
int ret, retlen = sizeof(int);
int paclen;
struct hostent *hp;
struct servent *sp;
#ifdef HAVE_NETROM
struct proc_nr_nodes *np;
#endif /* HAVE_NETROM */
strcpy(call, User.call);
/*
* Fill in protocol spesific stuff.
*/
switch (family) {
#ifdef HAVE_ROSE
case AF_ROSE:
if (check_perms(PERM_ROSE, 0L) == -1) {
node_msg("Permission denied");
log(L_GW, "Permission denied: rose");
return NULL;
}
if ((fd = socket(AF_ROSE, SOCK_SEQPACKET, 0)) < 0) {
node_perror("connect_to: socket", errno);
return NULL;
}
sa.rs.srose_family = AF_ROSE;
sa.rs.srose_ndigis = 0;
ax25_aton_entry(call, sa.rs.srose_call.ax25_call);
rose_aton(rs_config_get_addr(NULL), sa.rs.srose_addr.rose_addr);
salen = sizeof(struct sockaddr_rose);
if (bind(fd, (struct sockaddr *)&sa, salen) < 0) {
node_perror("connect_to: bind", errno);
close(fd);
return NULL;
}
memset(path, 0, 11);
memcpy(path, rs_config_get_addr(NULL), 4);
salen = strlen(addr[1]);
if ((salen != 6) && (salen != 10)) {
node_msg("Invalid ROSE address");
return NULL;
}
memcpy(path + (10-salen), addr[1], salen);
sprintf(User.dl_name, "%s @ %s", addr[0], path);
sa.rs.srose_family = AF_ROSE;
sa.rs.srose_ndigis = 0;
if (ax25_aton_entry(addr[0], sa.rs.srose_call.ax25_call) < 0) {
close(fd);
return NULL;
}
if (rose_aton(path, sa.rs.srose_addr.rose_addr) < 0) {
close(fd);
return NULL;
}
if (addr[2] != NULL) {
if (ax25_aton_entry(addr[2], sa.rs.srose_digi.ax25_call) < 0) {
close(fd);
return NULL;
}
sa.rs.srose_ndigis = 1;
}
salen = sizeof(struct sockaddr_rose);
paclen = rs_config_get_paclen(NULL);
eol = ROSE_EOL;
break;
#endif /* HAVE_ROSE */
#ifdef HAVE_NETROM
case AF_NETROM:
if (check_perms(PERM_NETROM, 0L) == -1) {
node_msg("Permission denied");
log(L_GW, "Permission denied: netrom");
return NULL;
}
if ((fd = socket(AF_NETROM, SOCK_SEQPACKET, 0)) < 0) {
node_perror("connect_to: socket", errno);
return NULL;
}
/* Why on earth is this different from ax.25 ????? */
sprintf(path, "%s %s", nr_config_get_addr(NrPort), call);
ax25_aton(path, &sa.ax);
sa.ax.fsa_ax25.sax25_family = AF_NETROM;
salen = sizeof(struct full_sockaddr_ax25);
if (bind(fd, (struct sockaddr *)&sa, salen) == -1) {
node_perror("connect_to: bind", errno);
close(fd);
return NULL;
}
if ((np = find_node(addr[0], NULL)) == NULL) {
node_msg("No such node");
return NULL;
}
strcpy(User.dl_name, print_node(np->alias, np->call));
if (ax25_aton(np->call, &sa.ax) == -1) {
close(fd);
return NULL;
}
sa.ax.fsa_ax25.sax25_family = AF_NETROM;
salen = sizeof(struct sockaddr_ax25);
paclen = nr_config_get_paclen(NrPort);
eol = NETROM_EOL;
break;
#endif /* HAVE_NETROM */
case AF_AX25:
if (check_perms(PERM_AX25, 0L) == -1 || (is_hidden(addr[0]) && check_perms(PERM_HIDDEN, 0L) == -1)) {
node_msg("Permission denied");
log(L_GW, "Permission denied: ax.25 port %s", addr[0]);
return NULL;
}
if (ax25_config_get_addr(addr[0]) == NULL) {
node_msg("Invalid port");
return NULL;
}
if ((fd = socket(AF_AX25, SOCK_SEQPACKET, 0)) < 0) {
node_perror("connect_to: socket", errno);
return NULL;
}
/*
* Invert the SSID only if user is coming in with AX.25
* and going out on the same port he is coming in via.
*/
if (User.ul_type == AF_AX25 && !strcasecmp(addr[0], User.ul_name))
invert_ssid(call, User.call);
sprintf(path, "%s %s", call, ax25_config_get_addr(addr[0]));
ax25_aton(path, &sa.ax);
sa.ax.fsa_ax25.sax25_family = AF_AX25;
salen = sizeof(struct full_sockaddr_ax25);
if (bind(fd, (struct sockaddr *)&sa, salen) < 0) {
node_perror("connect_to: bind", errno);
close(fd);
return NULL;
}
if (ax25_aton_arglist((const char **)addr+1, &sa.ax) < 0) {
close(fd);
return NULL;
}
strcpy(User.dl_name, strupr(addr[1]));
strcpy(User.dl_port, strupr(addr[0]));
sa.ax.fsa_ax25.sax25_family = AF_AX25;
salen = sizeof(struct full_sockaddr_ax25);
paclen = ax25_config_get_paclen(addr[0]);
eol = AX25_EOL;
break;
case AF_INET:
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
node_perror("connect_to: socket", errno);
return NULL;
}
hp = NULL;
if (ResolveAddrs && inet_aton(addr[0], &inaddr) != 0)
hp = gethostbyaddr((char *)&inaddr, sizeof(inaddr), AF_INET);
if (hp == NULL)
hp = gethostbyname(addr[0]);
if (hp == NULL) {
node_msg("Unknown host %s", addr[0]);
close(fd);
return NULL;
}
sa.in.sin_family = AF_INET;
sa.in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
sp = NULL;
if (addr[1] == NULL) {
if ((sp = getservbyname("telnet", "tcp")) != NULL)
sa.in.sin_port = sp->s_port;
else
sa.in.sin_port = htons(IPPORT_TELNET);
} else {
sa.in.sin_port = htons(atoi(addr[1]));
if ((sp = getservbyname(addr[1], "tcp")) != NULL ||
(sp = getservbyport(sa.in.sin_port, "tcp")) != NULL)
sa.in.sin_port = sp->s_port;
}
if (sa.in.sin_port == 0) {
node_msg("Unknown service %s", addr[1]);
close(fd);
return NULL;
}
strncpy(User.dl_name, hp->h_name, 31);
User.dl_name[31] = 0;
if (sp != NULL)
strcpy(User.dl_port, sp->s_name);
else
sprintf(User.dl_port, "%d", ntohs(sa.in.sin_port));
salen = sizeof(struct sockaddr_in);
paclen = 1024;
eol = INET_EOL;
if (check_perms(PERM_TELNET, sa.in.sin_addr.s_addr) == -1) {
node_msg("Permission denied");
log(L_GW, "Permission denied: telnet %s", print_dl(&User));
close(fd);
return NULL;
}
break;
default:
node_msg("Unsupported address family: %d", family);
return NULL;
}
/*
* Ok. Now set up a non-blocking connect...
*/
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
node_perror("connect_to: fcntl - fd", errno);
close(fd);
return NULL;
}
if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) {
node_perror("connect_to: fcntl - stdin", errno);
close(fd);
return NULL;
}
if (connect(fd, (struct sockaddr *)&sa, salen) == -1 && errno != EINPROGRESS) {
node_perror("connect_to: connect", errno);
close(fd);
return NULL;
}
User.dl_type = family;
node_msg("Trying %s... Type <RETURN> to abort", print_dl(&User));
axio_flush(NodeIo);
User.state = STATE_TRYING;
update_user();
/*
* ... and wait for it to finish (or user to abort).
*/
while (1) {
FD_ZERO(&read_fdset);
FD_ZERO(&write_fdset);
FD_SET(fd, &write_fdset);
FD_SET(STDIN_FILENO, &read_fdset);
if (select(fd + 1, &read_fdset, &write_fdset, 0, 0) == -1) {
node_perror("connect_to: select", errno);
break;
}
if (FD_ISSET(fd, &write_fdset)) {
/* See if we got connected or if this was an error */
getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &retlen);
if (ret != 0) {
/*
* This is STUPID !!!!
* FBB interprets "Connection refused" as
* success because it contains the string
* "Connect"...
* But I'm NOT going to toss away valuable
* information (the strerror() info).
* Fortunately (???) FBB is case sensitive
* when examining the return string so
* simply converting the strerror() message
* to lower case fixes the problem. Ugly
* but it _should_ work.
*/
cp = strdup(strerror(ret));
strlwr(cp);
node_msg("Failure with %s: %s",
print_dl(&User), cp);
log(L_GW, "Failure with %s: %s",
print_dl(&User), cp);
free(cp);
close(fd);
return NULL;
}
break;
}
if (FD_ISSET(STDIN_FILENO, &read_fdset)) {
if (axio_getline(NodeIo) != NULL) {
node_msg("Aborted");
close(fd);
return NULL;
} else if (errno != EAGAIN) {
close(fd);
return NULL;
}
}
}
if (escape == -1)
node_msg("Connected to %s", print_dl(&User));
else
node_msg("Connected to %s (Escape: %s%c)",
print_dl(&User),
escape < 32 ? "CTRL-" : "",
escape < 32 ? (escape + 'A' - 1) : escape);
axio_flush(NodeIo);
log(L_GW, "Connected to %s", print_dl(&User));
if ((riop = axio_init(fd, fd, paclen, eol)) == NULL) {
node_perror("connect_to: Initializing I/O failed", errno);
close(fd);
return NULL;
}
if (compr && axio_compr(riop, compr) < 0)
node_msg("connect_to: axio_compr failed");
User.state = STATE_CONNECTED;
update_user();
return riop;
}
int do_connect(int argc, char **argv)
{
ax25io *riop;
int c, family, stay, escape, compress;
fd_set fdset;
char *connstr = NULL;
stay = ReConnectTo;
if (!strcasecmp(argv[argc - 1], "s")) {
stay = 1;
argv[--argc] = NULL;
} else if (!strcasecmp(argv[argc - 1], "d")) {
stay = 0;
argv[--argc] = NULL;
}
compress = 0;
c = argv[0][0];
#ifdef HAVE_ZLIB_H
if (*argv[0] == 'z') {
compress = 1;
c = argv[0][1];
}
#endif
if (argc < 2) {
if (c == 't')
node_msg("Usage: telnet <host> [<port>] [d|s]");
else
node_msg("Usage: connect [<port>] <call> [via <call1> ...] [d|s]");
return 0;
}
if (c == 't')
family = AF_INET;
else
#ifdef HAVE_NETROM
if (argc == 2)
family = AF_NETROM;
else
#endif
#ifdef HAVE_ROSE
if (strspn(argv[2], "0123456789") == strlen(argv[2]))
family = AF_ROSE;
else
#endif
family = AF_AX25;
if (family == AF_INET && argc > 3)
connstr = argv[3];
escape = (check_perms(PERM_NOESC, 0L) == 0) ? -1 : EscChar;
riop = connect_to(++argv, family, escape, compress);
if (riop == NULL) {
if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1)
node_perror("do_connect: fcntl - stdin", errno);
return 0;
}
if (family == AF_INET)
axio_tnmode(riop, 1);
if (connstr) {
axio_printf(riop, "%s\n", connstr);
axio_flush(riop);
}
/*
* If eol conventions are compatible, switch to binary mode,
* else switch to special gateway mode.
*/
if (axio_cmpeol(riop, NodeIo) == 0) {
axio_eolmode(riop, EOLMODE_BINARY);
axio_eolmode(NodeIo, EOLMODE_BINARY);
} else {
axio_eolmode(riop, EOLMODE_GW);
axio_eolmode(NodeIo, EOLMODE_GW);
}
while (1) {
FD_ZERO(&fdset);
FD_SET(riop->ifd, &fdset);
FD_SET(STDIN_FILENO, &fdset);
if (select(32, &fdset, 0, 0, 0) == -1) {
node_perror("do_connect: select", errno);
break;
}
if (FD_ISSET(riop->ifd, &fdset)) {
alarm(ConnTimeout);
while((c = axio_getc(riop)) != -1)
axio_putc(c, NodeIo);
if (errno != EAGAIN) {
switch (errno) {
case 0:
case ENOTCONN:
break;
case ZERR_STREAM_END:
case ZERR_STREAM_ERROR:
case ZERR_UNKNOWN:
case ZERR_DATA_ERROR:
case ZERR_MEM_ERROR:
case ZERR_BUF_ERROR:
node_msg("Decompression error");
break;
default:
node_msg("%s", strerror(errno));
break;
}
break;
}
}
if (FD_ISSET(STDIN_FILENO, &fdset)) {
alarm(ConnTimeout);
while((c = axio_getc(NodeIo)) != -1) {
if (escape != -1 && c == escape)
break;
axio_putc(c, riop);
}
if (escape != -1 && c == escape) {
axio_eolmode(NodeIo, EOLMODE_TEXT);
axio_getline(NodeIo);
break;
}
if (errno != EAGAIN) {
stay = 0;
break;
}
}
axio_flush(riop);
axio_flush(NodeIo);
}
axio_end(riop);
log(L_GW, "Disconnected from %s", print_dl(&User));
if (stay) {
axio_eolmode(NodeIo, EOLMODE_TEXT);
if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1)
node_perror("do_connect: fcntl - stdin", errno);
node_msg("Reconnected to %s", HostName);
} else
logout("No reconnect");
return 0;
}
int do_finger(int argc, char **argv)
{
ax25io *riop;
int c;
char *name, *addr[3], *cp;
if (argc < 2) {
name = "";
addr[0] = "localhost";
} else if ((cp = strchr(argv[1], '@')) != NULL) {
*cp = 0;
name = argv[1];
addr[0] = ++cp;
} else {
name = argv[1];
addr[0] = "localhost";
}
addr[1] = "finger";
addr[2] = NULL;
riop = connect_to(addr, AF_INET, -1, 0);
if (riop != NULL) {
if (fcntl(riop->ifd, F_SETFL, 0) == -1)
node_perror("do_finger: fcntl - fd", errno);
axio_printf(riop, "%s\n", name);
axio_flush(riop);
while((c = axio_getc(riop)) != -1)
axio_putc(c, NodeIo);
axio_end(riop);
node_msg("Reconnected to %s", HostName);
}
axio_eolmode(NodeIo, EOLMODE_TEXT);
if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1)
node_perror("do_finger: fcntl - stdin", errno);
return 0;
}
/*
* Returns difference of tv1 and tv2 in milliseconds.
*/
static long calc_rtt(struct timeval tv1, struct timeval tv2)
{
struct timeval tv;
tv.tv_usec = tv1.tv_usec - tv2.tv_usec;
tv.tv_sec = tv1.tv_sec - tv2.tv_sec;
if (tv.tv_usec < 0) {
tv.tv_sec -= 1L;
tv.tv_usec += 1000000L;
}
return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L));
}
/*
* Checksum routine for Internet Protocol family headers (C Version)
*/
static unsigned short in_cksum(unsigned char *addr, int len)
{
register int nleft = len;
register unsigned char *w = addr;
register unsigned int sum = 0;
unsigned short answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += (*(w + 1) << 8) + *(w);
w += 2;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
sum += *w;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return answer;
}
int do_ping(int argc, char **argv)
{
static int sequence = 0;
unsigned char buf[256];
struct hostent *hp;
struct sockaddr_in to, from;
struct in_addr inaddr;
struct protoent *prot;
struct icmphdr *icp;
struct timeval tv1, tv2;
struct iphdr *ip;
fd_set fdset;
int fd, i, id, len = sizeof(struct icmphdr);
int salen = sizeof(struct sockaddr);
if (argc < 2) {
node_msg("Usage: ping <host> [<size>]");
return 0;
}
if (argc > 2) {
len = atoi(argv[2]) + sizeof(struct icmphdr);
if (len > 256) {
node_msg("Maximum length is %d", 256 - sizeof(struct icmphdr));
return 0;
}
}
hp = NULL;
if (ResolveAddrs && inet_aton(argv[1], &inaddr) != 0)
hp = gethostbyaddr((char *)&inaddr, sizeof(inaddr), AF_INET);
if (hp == NULL)
hp = gethostbyname(argv[1]);
if (hp == NULL) {
node_msg("Unknown host %s", argv[1]);
return 0;
}
memset(&to, 0, sizeof(to));
to.sin_family = AF_INET;
to.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
if ((prot = getprotobyname("icmp")) == NULL) {
node_msg("Unknown protocol icmp");
return 0;
}
if ((fd = socket(AF_INET, SOCK_RAW, prot->p_proto)) == -1) {
node_perror("do_ping: socket", errno);
return 0;
}
node_msg("Pinging %s... Type <RETURN> to abort", inet_ntoa(to.sin_addr));
axio_flush(NodeIo);
strncpy(User.dl_name, hp->h_name, 31);
User.dl_name[31] = 0;
User.dl_type = AF_INET;
User.state = STATE_PINGING;
update_user();
/*
* Fill the data portion (if any) with some garbage.
*/
for (i = sizeof(struct icmphdr); i < len; i++)
buf[i] = (i - sizeof(struct icmphdr)) & 0xff;
/*
* Fill in the icmp header.
*/
id = getpid() & 0xffff;
icp = (struct icmphdr *)buf;
icp->type = ICMP_ECHO;
icp->code = 0;
icp->checksum = 0;
icp->un.echo.id = id;
icp->un.echo.sequence = sequence++;
/*
* Calculate checksum.
*/
icp->checksum = in_cksum(buf, len);
/*
* Take the time and send the packet.
*/
gettimeofday(&tv1, NULL);
if (sendto(fd, buf, len, 0, (struct sockaddr *)&to, salen) != len) {
node_perror("do_ping: sendto", errno);
close(fd);
return 0;
}
/*
* Now wait for it to come back (or user to abort).
*/
if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) {
node_perror("do_ping: fcntl - stdin", errno);
close(fd);
return 0;
}
while (1) {
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
FD_SET(STDIN_FILENO, &fdset);
if (select(fd + 1, &fdset, 0, 0, 0) == -1) {
node_perror("do_ping: select", errno);
break;
}
if (FD_ISSET(fd, &fdset)) {
if ((len = recvfrom(fd, buf, 256, 0, (struct sockaddr *)&from, &salen)) == -1) {
node_perror("do_ping: recvfrom", errno);
break;
}
gettimeofday(&tv2, NULL);
ip = (struct iphdr *)buf;
/* Is it long enough? */
if (len >= (ip->ihl << 2) + sizeof(struct icmphdr)) {
len -= ip->ihl << 2;
icp = (struct icmphdr *)(buf + (ip->ihl << 2));
/* Is it ours? */
if (icp->type == ICMP_ECHOREPLY && icp->un.echo.id == id && icp->un.echo.sequence == sequence - 1) {
node_msg("%s rtt: %ldms (ttl=%d)", inet_ntoa(from.sin_addr), calc_rtt(tv2, tv1), ip->ttl);
break;
}
}
}
if (FD_ISSET(STDIN_FILENO, &fdset)) {
if (axio_getline(NodeIo) != NULL) {
node_msg("Aborted");
break;
} else if (errno != EAGAIN) {
break;
}
}
}
if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1)
node_perror("do_ping: fcntl - stdin", errno);
close(fd);
return 0;
}
node-0.3.0/COPYING 100644 764 764 43076 6724612641 11407 0 ustar tpm tpm GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
node-0.3.0/node.c 100644 764 764 15143 6726554402 11441 0 ustar tpm tpm #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "kernel_ax25.h"
#include "kernel_rose.h"
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include <netax25/nrconfig.h>
#include <netax25/rsconfig.h>
#include <netax25/procutils.h>
#include "node.h"
ax25io *NodeIo = NULL;
/*
* Do some validity checking for callsign pointed to by `s'.
*/
static int check_call(const char *s)
{
int len = 0;
int nums = 0;
int ssid = 0;
char *p[1];
if (s == NULL)
return -1;
while (*s && *s != '-') {
if (!isalnum(*s))
return -1;
if (isdigit(*s))
nums++;
len++;
s++;
}
if (*s == '-') {
if (!isdigit(*++s))
return -1;
ssid = strtol(s, p, 10);
if (**p)
return -1;
}
if (len < 4 || len > 6 || !nums || nums > 2 || ssid < 0 || ssid > 15)
return -1;
return 0;
}
static void signal_handler(int sig)
{
axio_eolmode(NodeIo, EOLMODE_TEXT);
switch (sig) {
case SIGALRM:
nputs("\n");
node_msg("Timeout! Disconnecting...");
logout("Timeout");
case SIGTERM:
nputs("\n");
node_msg("System going down! Disconnecting...");
logout("SIGTERM");
case SIGINT:
logout("SIGINT");
case SIGQUIT:
logout("SIGQUIT");
case SIGSEGV:
nputs("\n");
node_msg("Caught SIGSEGV");
logout("SIGSEGV");
default:
logout("unknown signal");
}
}
int main(int argc, char *argv[])
{
union {
struct full_sockaddr_ax25 sax;
struct sockaddr_rose srose;
struct sockaddr_in sin;
} saddr;
int slen = sizeof(saddr);
char *p, buf[256], *pw;
int paclen;
FILE *fp;
int invalid_cmds = 0;
signal(SIGALRM, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
signal(SIGSEGV, signal_handler);
signal(SIGPIPE, SIG_IGN);
if (ax25_config_load_ports() == 0) {
log(L_ERROR, "No AX.25 port data configured");
return 1;
}
nr_config_load_ports();
rs_config_load_ports();
if (getpeername(STDOUT_FILENO, (struct sockaddr *)&saddr, &slen) == -1) {
if (errno != ENOTSOCK) {
log(L_ERROR, "getpeername: %s", strerror(errno));
return 1;
}
User.ul_type = AF_UNSPEC;
} else
User.ul_type = saddr.sax.fsa_ax25.sax25_family;
switch (User.ul_type) {
case AF_AX25:
strcpy(User.call, ax25_ntoa(&saddr.sax.fsa_ax25.sax25_call));
if (getsockname(STDOUT_FILENO, (struct sockaddr *)&saddr.sax, &slen) == -1) {
log(L_ERROR, "getsockname: %s", strerror(errno));
return 1;
}
strcpy(User.ul_name, ax25_config_get_port(&saddr.sax.fsa_digipeater[0]));
paclen = ax25_config_get_paclen(User.ul_name);
p = AX25_EOL;
break;
case AF_NETROM:
strcpy(User.call, ax25_ntoa(&saddr.sax.fsa_ax25.sax25_call));
strcpy(User.ul_name, ax25_ntoa(&saddr.sax.fsa_digipeater[0]));
if (getsockname(STDOUT_FILENO, (struct sockaddr *)&saddr.sax, &slen) == -1) {
log(L_ERROR, "getsockname: %s", strerror(errno));
return 1;
}
strcpy(User.ul_port, nr_config_get_port(&saddr.sax.fsa_ax25.sax25_call));
paclen = nr_config_get_paclen(User.ul_port);
p = NETROM_EOL;
break;
case AF_ROSE:
strcpy(User.call, ax25_ntoa(&saddr.srose.srose_call));
strcpy(User.ul_name, rose_ntoa(&saddr.srose.srose_addr));
paclen = rs_config_get_paclen(NULL);
p = ROSE_EOL;
break;
case AF_INET:
strcpy(User.ul_name, inet_ntoa(saddr.sin.sin_addr));
paclen = 1024;
p = INET_EOL;
break;
case AF_UNSPEC:
strcpy(User.ul_name, "local");
if ((p = get_call(getuid())) == NULL) {
log(L_ERROR, "No uid->callsign association found", -1);
return 1;
}
strcpy(User.call, p);
paclen = 1024;
p = UNSPEC_EOL;
break;
default:
log(L_ERROR, "Unsupported address family %d", User.ul_type);
return 1;
}
NodeIo = axio_init(STDIN_FILENO, STDOUT_FILENO, paclen, p);
if (NodeIo == NULL) {
log(L_ERROR, "Error initializing I/O");
return 1;
}
#ifdef HAVE_ZLIB_H
if (argc > 1 && strcmp(argv[1], "-c") == 0) {
axio_compr(NodeIo, 1);
}
#endif
if (User.ul_type == AF_INET) {
axio_tnmode(NodeIo, 1);
axio_tn_do_linemode(NodeIo);
}
init_nodecmds();
if (read_config() == -1) {
axio_end(NodeIo);
return 1;
}
if (ResolveAddrs && User.ul_type == AF_INET) {
struct hostent *hp;
hp = gethostbyaddr((char *)&saddr.sin.sin_addr,
sizeof(struct in_addr), AF_INET);
if (hp != NULL) {
strncpy(User.ul_name, hp->h_name, 31);
User.ul_name[31] = 0;
} else
log(L_ERROR, "gethostbyaddr: %s", strherror(h_errno));
}
User.state = STATE_LOGIN;
login_user();
if (User.call[0] == 0) {
nprintf("\n%s (%s)\n\nlogin: ", VERSION, HostName);
axio_flush(NodeIo);
alarm(300L); /* 5 min timeout */
if ((p = axio_getline(NodeIo)) == NULL)
logout("User disconnected");
alarm(0L);
strncpy(User.call, p, 9);
User.call[9] = 0;
strlwr(User.call);
}
if ((p = strstr(User.call, "-0")) != NULL)
*p = 0;
if (check_call(User.call) == -1) {
node_msg("Invalid callsign");
log(L_LOGIN, "Invalid callsign %s @ %s", User.call, User.ul_name);
logout("Invalid callsign");
}
if ((pw = read_perms(&User, saddr.sin.sin_addr.s_addr)) == NULL) {
node_msg("Sorry, I'm not allowed to talk to you...");
log(L_LOGIN, "Login denied for %s @ %s", User.call, User.ul_name);
logout("Login denied");
} else if (strcmp(pw, "*") != 0) {
nputs("Password: ");
if (User.ul_type == AF_INET) {
axio_tn_will_echo(NodeIo);
axio_eolmode(NodeIo, EOLMODE_BINARY);
}
axio_flush(NodeIo);
p = axio_getline(NodeIo);
if (User.ul_type == AF_INET) {
axio_tn_wont_echo(NodeIo);
axio_eolmode(NodeIo, EOLMODE_TEXT);
nputs("\n");
}
if (p == NULL || strcmp(p, pw) != 0) {
nputs("\n");
node_msg("Login failed");
log(L_LOGIN, "Login failed for %s @ %s", User.call, User.ul_name);
logout("Login failed");
}
}
free(pw);
ipc_open();
node_msg("Welcome to %s network node", HostName);
if ((fp = fopen(CONF_NODE_MOTD_FILE, "r")) != NULL) {
while (fgets(buf, 256, fp) != NULL)
nputs(buf);
nputs("--\n");
}
put_prompt();
log(L_LOGIN, "%s @ %s logged in", User.call, User.ul_name);
while (1) {
axio_flush(NodeIo);
User.state = STATE_IDLE;
time(&User.cmdtime);
update_user();
alarm(IdleTimeout);
if ((p = axio_getline(NodeIo)) == NULL) {
if (errno == EINTR)
continue;
logout("User disconnected");
}
alarm(IdleTimeout);
time(&User.cmdtime);
update_user();
if (cmdparse(Nodecmds, p) == -1) {
if (++invalid_cmds < 3) {
node_msg("Unknown command. Type ? for a list");
} else {
node_msg("Too many invalid commands. Disconnecting...");
logout("Too many invalid commands");
}
} else
invalid_cmds = 0;
put_prompt();
}
logout("Out of main loop !?!?!?");
}
node-0.3.0/cmdparse.c 100644 764 764 14302 6731775251 12311 0 ustar tpm tpm #include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include "kernel_ax25.h"
#include "kernel_rose.h"
#include <netax25/axlib.h>
#include "node.h"
#define safe_strcpy(a, b) strncpy(a, b, sizeof(a)); a[sizeof(a)-1] = 0;
static unsigned char parsechr(char *str, char **endptr)
{
switch (*str) {
case 'n':
*endptr = ++str;
return '\n';
case 't':
*endptr = ++str;
return '\t';
case 'v':
*endptr = ++str;
return '\v';
case 'b':
*endptr = ++str;
return '\b';
case 'r':
*endptr = ++str;
return '\r';
case 'f':
*endptr = ++str;
return '\f';
case 'a':
*endptr = ++str;
return '\007';
case '\\':
*endptr = ++str;
return '\\';
case '\"':
*endptr = ++str;
return '\"';
case 'x':
return strtoul(str, endptr, 16);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
return strtoul(str, endptr, 8);
case '\0':
return 0;
default:
*endptr = str + 1;
return *str;
}
/* NOTREACHED */
return 0;
}
static char *parsestr(char *str, char **endptr, int argc, char **argv)
{
static char buf[256];
char def[256];
char *p;
int n, skip;
time_t t;
skip = 1;
buf[0] = 0;
def[0] = 0;
if (*str == '{') {
str++;
if ((p = strchr(str, '}')) != NULL) {
skip = p - str + 1;
p = str + 1;
if (*p == ':') {
p++;
n = min(skip - 3, sizeof(def) - 1);
strncpy(def, p, n);
def[n] = 0;
}
}
}
switch (*str) {
case 'n':
case 'N':
safe_strcpy(buf, NodeId);
break;
case 'i':
case 'I':
time(&t);
p = ctime(&t);
strncpy(buf, p + 11, 8);
buf[8] = 0;
break;
case 'h':
case 'H':
safe_strcpy(buf, HostName);
if ((p = strchr(buf, '.')))
*p = 0;
break;
case 'f':
case 'F':
safe_strcpy(buf, HostName);
break;
case 'u':
case 'U':
safe_strcpy(buf, User.call);
if ((p = strrchr(buf, '-')))
*p = 0;
break;
case 's':
case 'S':
safe_strcpy(buf, User.call);
break;
case 'p':
case 'P':
safe_strcpy(buf, User.ul_name);
if ((p = strrchr(buf, '-')))
*p = 0;
break;
case 'r':
case 'R':
safe_strcpy(buf, User.ul_name);
break;
case 't':
case 'T':
switch (User.ul_type) {
case AF_AX25:
strcpy(buf, "ax25");
break;
case AF_NETROM:
strcpy(buf, "netrom");
break;
case AF_ROSE:
strcpy(buf, "rose");
break;
case AF_INET:
strcpy(buf, "inet");
break;
case AF_UNSPEC:
strcpy(buf, "host");
break;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = *str - '0';
if (argv == NULL || n > argc - 1)
strcpy(buf, def);
else
safe_strcpy(buf, argv[n]);
break;
default:
strcpy(buf, "%");
break;
}
if (isalpha(*str)) {
if (isupper(*str))
strupr(buf);
else
strlwr(buf);
}
*endptr = str + skip;
return buf;
}
char *expand_string(char *str, int argc, char **argv)
{
char buf[1024];
char *p, *src, *dst;
int len, buflen;
if (strcspn(str, "%\\\'") == strlen(str))
return strdup(str);
src = str;
dst = buf;
len = 0;
buflen = sizeof(buf) - 8; /* Slightly on the safe side... */
while (*src && (len < buflen)) {
switch (*src) {
case '\'':
*dst++ = *src++;
len++;
while (*src && (*src != '\'') && (len < buflen)) {
*dst++ = *src++;
len++;
}
if (*src) {
*dst++ = '\'';
len++;
}
break;
case '\\':
src++;
*dst++ = parsechr(src, &src);
len++;
break;
case '%':
src++;
p = parsestr(src, &src, argc, argv);
strncpy(dst, p, min(strlen(p), buflen - len));
dst += min(strlen(p), buflen - len);
break;
default:
*dst++ = *src++;
len++;
break;
}
}
*dst = 0;
return strdup(buf);
}
int parse_args(char **argv, char *cmd)
{
int ct = 0;
char quote;
char *p;
while (ct < 31) {
while (*cmd && isspace(*cmd))
cmd++;
if (*cmd == 0)
break;
argv[ct++] = cmd;
quote = 0;
p = cmd;
while (*cmd) {
if (quote == 0) {
if (isspace(*cmd))
break;
if (*cmd == '\"' || *cmd == '\'')
quote = *cmd;
else
*p++ = *cmd;
} else {
if (*cmd == quote)
quote = 0;
else
*p++ = *cmd;
}
cmd++;
}
if (*cmd == 0) {
*p = 0;
break;
}
*p = 0;
*cmd++ = 0;
}
argv[ct] = NULL;
return ct;
}
int cmdparse(struct cmd *list, char *cmdline)
{
struct cmd *cmdp;
int ret, argc;
char *argv[32];
char *cmdbuf = NULL;
char *aliasbuf = NULL;
while (*cmdline && isspace(*cmdline))
cmdline++;
if (*cmdline == 0 || *cmdline == '#')
return 0;
cmdbuf = expand_string(cmdline, 0, NULL);
argc = parse_args(argv, cmdbuf);
for (cmdp = list; cmdp != NULL; cmdp = cmdp->next) {
if (strlen(argv[0]) < cmdp->len ||
strlen(argv[0]) > strlen(cmdp->name))
continue;
if (strncasecmp(cmdp->name, argv[0], strlen(argv[0])) == 0)
break;
}
if (cmdp == NULL) {
free(cmdbuf);
return -1;
}
strlwr(argv[0]);
switch (cmdp->type) {
case CMD_INTERNAL:
ret = (*cmdp->function)(argc, argv);
break;
case CMD_ALIAS:
aliasbuf = expand_string(cmdp->command, argc, argv);
ret = cmdparse(list, aliasbuf);
break;
case CMD_EXTERNAL:
aliasbuf = expand_string(cmdp->command, argc, argv);
argc = parse_args(argv, aliasbuf);
ret = extcmd(cmdp, argv);
break;
default:
ret = -1;
break;
}
free(cmdbuf);
free(aliasbuf);
return ret;
}
void insert_cmd(struct cmd **list, struct cmd *new)
{
struct cmd *tmp, *p;
if (*list == NULL || strcasecmp(new->name, (*list)->name) < 0) {
tmp = *list;
*list = new;
new->next = tmp;
} else {
for (p = *list; p->next != NULL; p = p->next)
if (strcasecmp(new->name, p->next->name) < 0)
break;
tmp = p->next;
p->next = new;
new->next = tmp;
}
}
int add_internal_cmd(struct cmd **list, char *name, int len, int (*function) (int argc, char **argv))
{
struct cmd *new;
if ((new = calloc(1, sizeof(struct cmd))) == NULL) {
node_perror("add_internal_cmd: calloc", errno);
return -1;
}
new->name = strdup(name);
new->len = len ? len : strlen(name);
new->type = CMD_INTERNAL;
new->function = function;
insert_cmd(list, new);
return 0;
}
void free_cmdlist(struct cmd *list)
{
struct cmd *tmp;
while (list != NULL) {
free(list->name);
free(list->command);
free(list->path);
tmp = list;
list = list->next;
free(tmp);
}
}
node-0.3.0/node.h 100644 764 764 7561 6740156731 11432 0 ustar tpm tpm #include <sys/types.h>
#include <errno.h>
#include "config.h"
#include <netax25/ax25io.h>
#define VERSION "LinuxNode v0.3.0"
#define STATE_IDLE 0
#define STATE_TRYING 1
#define STATE_CONNECTED 2
#define STATE_PINGING 3
#define STATE_EXTCMD 4
#define STATE_LOGIN 5
#define L_NONE 0
#define L_ERROR 1
#define L_LOGIN 2
#define L_GW 3
#define L_DEBUG 4
#define PERM_LOGIN 1 /* Permit login */
#define PERM_AX25 2 /* AX.25 gatewaying */
#define PERM_NETROM 4 /* NETROM gatewaying */
#define PERM_TELNET_LOCAL 8 /* Telnet to "local" hosts */
#define PERM_TELNET_AMPR 16 /* Telnet to 44.xx.xx.xx hosts */
#define PERM_TELNET_INET 32 /* Telnet to other hosts */
#define PERM_HIDDEN 64 /* Use hidden ports */
#define PERM_ROSE 128 /* ROSE gatewaying */
#define PERM_NOESC 256 /* No escape character */
#define PERM_TELNET (PERM_TELNET_LOCAL & PERM_TELNET_AMPR & PERM_TELNET_INET)
struct user
{
pid_t pid;
key_t ipc_key;
time_t logintime;
time_t cmdtime;
unsigned char state;
char call[10];
unsigned short ul_type;
unsigned short dl_type;
char ul_name[32];
char dl_name[32];
char ul_port[32];
char dl_port[32];
char unused[92];
};
extern struct user User;
extern ax25io *NodeIo; /* our own stdin and stdout */
extern long IdleTimeout;
extern long ConnTimeout;
extern int ReConnectTo;
extern int ResolveAddrs;
extern int LogLevel;
extern int EscChar;
extern char *HostName;
extern char *NodeId;
extern char *NodePrompt;
extern char *NrPort;
#define CMD_INTERNAL 1
#define CMD_ALIAS 2
#define CMD_EXTERNAL 3
struct cmd {
char *name;
int len;
int type;
int (*function) (int argc, char **argv);
char *command;
int flags;
int uid;
int gid;
char *path;
struct cmd *next;
};
extern struct cmd *Nodecmds;
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
/* in cmdparse.c */
void free_cmdlist(struct cmd *list);
extern void insert_cmd(struct cmd **list, struct cmd *new);
extern int add_internal_cmd(struct cmd **list, char *name, int len, int (*function) (int argc, char **argv));
extern char *expand_string(char *str, int argc, char **argv);
extern int parse_args(char **argv, char *cmd);
extern int cmdparse(struct cmd *cmdp, char *cmdline);
/* in util.c */
extern int nputs(const char *);
extern int nprintf(const char *, ...);
extern void node_msg(const char *, ...);
extern void node_perror(char *, int);
extern char *print_node(const char *, const char *);
extern char *print_dl(struct user *);
extern void put_prompt(void);
extern void log(int, const char *, ...);
extern char *strherror(int);
/* in user.c */
extern void login_user(void);
extern void logout_user(void);
extern void update_user(void);
extern int do_users(int argc, char **argv);
extern int user_list(int verbose);
extern int user_count(void);
/* in config.c */
extern int is_hidden(const char *port);
extern int check_perms(int what, unsigned long peer);
extern char *read_perms(struct user *up, unsigned long peer);
extern int read_config(void);
extern int get_escape(char *s);
/* in command.c */
void init_nodecmds(void);
extern void logout(char *reason);
extern int do_bye(int argc, char **argv);
extern int do_escape(int argc, char **argv);
extern int do_mheard(int argc, char **argv);
extern int do_help(int argc, char **argv);
extern int do_host(int argc, char **argv);
extern int do_ports(int argc, char **argv);
extern int do_links(int argc, char **argv);
extern int do_nlinks(int argc, char **argv);
extern int do_routes(int argc, char **argv);
extern int do_nodes(int argc, char **argv);
extern int do_status(int argc, char **argv);
/* in gateway.c */
extern int do_connect(int argc, char **argv);
extern int do_finger(int argc, char **argv);
extern int do_ping(int argc, char **argv);
/* in ipc.c */
extern int ipc_open(void);
extern int ipc_close(void);
extern int do_talk(int argc, char **argv);
/* in extcmd.c */
extern int extcmd(struct cmd *cmdp, char **argv);
node-0.3.0/nodeusers.c 100644 764 764 3344 6726554402 12503 0 ustar tpm tpm #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <signal.h>
#include <syslog.h>
#include "kernel_ax25.h"
#include "kernel_rose.h"
#include <netax25/axlib.h>
#include <netax25/procutils.h>
#include "node.h"
/*
* These are needed for util.c to link
*/
int LogLevel = L_NONE;
char *NodeId = "Nodeusers:";
char *NodePrompt = "\n";
char *expand_string(char *str, int argc, char **argv) { return str; }
ax25io *NodeIo = NULL;
static int logging = 0;
static void pipe_handler(int sig)
{
if (logging)
syslog(LOG_ERR, "received SIGPIPE");
axio_end(NodeIo);
exit(1);
}
int main(int argc, char **argv)
{
int n, len = 1024;
char *cp = UNSPEC_EOL;
int inet = 0;
while ((n = getopt(argc, argv, "ail")) != -1) {
switch (n) {
case 'a':
cp = AX25_EOL;
len = 128;
break;
case 'i':
cp = INET_EOL;
inet = 1;
break;
case 'l':
logging = 1;
break;
default:
fprintf(stderr, "usage: nodeusers [-a] [-i] [-l]\r\n");
return 1;
}
}
if (logging)
openlog("nodeusers", LOG_PID, LOG_DAEMON);
signal(SIGPIPE, pipe_handler);
NodeIo = axio_init(STDIN_FILENO, STDOUT_FILENO, len, cp);
if (NodeIo == NULL) {
fprintf(stderr, "nodeusers: axio_init failed\r\n");
return 1;
}
if (inet && axio_getline(NodeIo) == NULL) {
if (logging)
syslog(LOG_ERR, "axio_getline: %m");
axio_end(NodeIo);
return 1;
}
n = user_count();
nprintf("\n%s - %d user%s.\n\n", VERSION, n, n == 1 ? "" : "s");
user_list(1);
if (n > 0)
nputs("\n");
if (axio_flush(NodeIo) == -1 && logging)
syslog(LOG_ERR, "axio_flush: %m");
axio_end(NodeIo);
usleep(500000L);
closelog();
return 0;
}
node-0.3.0/sysinfo.c 100644 764 764 4102 6707433465 12163 0 ustar tpm tpm #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include "node.h"
#include "sysinfo.h"
/*
* This code is heavily modified from the procps package.
*/
#define UPTIME_FILE "/proc/uptime"
#define LOADAVG_FILE "/proc/loadavg"
#define MEMINFO_FILE "/proc/meminfo"
static char buf[512];
/* This macro opens FILE only if necessary and seeks to 0 so that successive
calls to the functions are more efficient. It also reads the current
contents of the file into the global buf.
*/
#define FILE_TO_BUF(FILE) { \
static int n, fd = -1; \
if (fd == -1 && (fd = open(FILE, O_RDONLY)) == -1) { \
node_perror(FILE, errno); \
close(fd); \
return 0; \
} \
lseek(fd, 0L, SEEK_SET); \
if ((n = read(fd, buf, sizeof buf - 1)) < 0) { \
node_perror(FILE, errno); \
close(fd); \
fd = -1; \
return 0; \
} \
buf[n] = '\0'; \
}
#define SET_IF_DESIRED(x,y) if (x) *(x) = (y) /* evals 'x' twice */
int uptime(double *uptime_secs, double *idle_secs)
{
double up=0, idle=0;
FILE_TO_BUF(UPTIME_FILE)
if (sscanf(buf, "%lf %lf", &up, &idle) < 2) {
node_msg("Bad data in " UPTIME_FILE );
return 0;
}
SET_IF_DESIRED(uptime_secs, up);
SET_IF_DESIRED(idle_secs, idle);
return up; /* assume never be zero seconds in practice */
}
int loadavg(double *av1, double *av5, double *av15)
{
double avg_1=0, avg_5=0, avg_15=0;
FILE_TO_BUF(LOADAVG_FILE)
if (sscanf(buf, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) {
node_msg("Bad data in " LOADAVG_FILE );
return 0;
}
SET_IF_DESIRED(av1, avg_1);
SET_IF_DESIRED(av5, avg_5);
SET_IF_DESIRED(av15, avg_15);
return 1;
}
int load_meminfo(void)
{
FILE_TO_BUF(MEMINFO_FILE)
return 1;
}
int meminfo(const char *s)
{
char *cp;
int len;
len = strlen(s);
cp = buf;
while (1) {
if (strncasecmp(cp, s, len) == 0) {
cp += len;
if (*cp == ':')
return atoi(++cp);
}
if ((cp = strchr(cp, '\n')) == NULL)
break;
cp++;
}
return -1;
}
node-0.3.0/sysinfo.h 100644 764 764 272 6414236572 12147 0 ustar tpm tpm extern int loadavg(double *av1, double *av5, double *av15);
extern int uptime (double *uptime_secs, double *idle_secs);
extern int load_meminfo(void);
extern int meminfo(const char *s);
node-0.3.0/user.c 100644 764 764 12674 6707433513 11476 0 ustar tpm tpm #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <signal.h>
#include <netax25/procutils.h>
#include "node.h"
struct user User = {0};
static long CallerPos = -1L;
void login_user(void)
{
FILE *f;
struct user u;
long pos = 0L;
long free = -1L;
struct stat statbuf;
time(&User.logintime);
User.cmdtime = User.logintime;
User.pid = getpid();
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r+")) == NULL) {
node_perror("login_user: fopen: " DATA_NODE_LOGIN_FILE, errno);
return;
}
if (stat(DATA_NODE_LOGIN_FILE, &statbuf) == -1) {
node_perror("login_user: stat: " DATA_NODE_LOGIN_FILE, errno);
fclose(f);
return;
}
if (statbuf.st_size % sizeof(struct user) != 0) {
node_msg("%s: Incorrect size", DATA_NODE_LOGIN_FILE);
log(L_ERROR, "%s: Incorrect size", DATA_NODE_LOGIN_FILE);
fclose(f);
return;
}
if (flock(fileno(f), LOCK_EX) == -1) {
node_perror("login_user: flock", errno);
fclose(f);
return;
}
while (fread(&u, sizeof(u), 1, f) == 1) {
if (u.pid == -1 || (kill(u.pid, 0) == -1 && errno == ESRCH)) {
free = pos;
break;
}
pos += sizeof(u);
}
if (free != -1L && fseek(f, free, 0L) == -1) {
node_perror("login_user: fseek", errno);
flock(fileno(f), LOCK_UN);
fclose(f);
return;
}
fflush(f);
CallerPos = ftell(f);
fwrite(&User, sizeof(User), 1, f);
fflush(f);
flock(fileno(f), LOCK_UN);
fclose(f);
}
void logout_user(void)
{
FILE *f;
if (CallerPos == -1L)
return;
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r+")) == NULL) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
return;
}
if (fseek(f, CallerPos, 0) == -1) {
node_perror("logout_user: fseek", errno);
fclose(f);
return;
}
User.pid = -1;
fwrite(&User, sizeof(User), 1, f);
fclose(f);
}
void update_user(void)
{
FILE *f;
if (CallerPos == -1L)
return;
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r+")) == NULL) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
return;
}
if (fseek(f, CallerPos, 0) == -1) {
node_perror("update_user: fseek", errno);
fclose(f);
return;
}
fwrite(&User, sizeof(User), 1, f);
fclose(f);
}
int do_users(int argc, char **argv)
{
node_msg("Users:");
if (user_list(0) == -1)
node_perror(DATA_NODE_LOGIN_FILE, errno);
return 0;
}
int user_list(int verbose)
{
FILE *f;
struct user u;
struct tm *tp;
struct proc_nr_nodes *np;
char buf[80];
char *cp;
long l;
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL)
return -1;
while (fread(&u, sizeof(u), 1, f) == 1) {
if (u.pid == -1 || (kill(u.pid, 0) == -1 && errno == ESRCH))
continue;
switch (u.ul_type) {
case AF_AX25:
sprintf(buf, "Uplink (%.9s on port %.10s)",
u.call, u.ul_name);
break;
case AF_NETROM:
if ((np = find_node(u.ul_name, NULL)) != NULL) {
sprintf(buf, "Circuit (%.9s %.18s)",
u.call,
print_node(np->alias, np->call));
} else {
sprintf(buf, "Circuit (%.9s %.18s)",
u.call, u.ul_name);
}
break;
case AF_ROSE:
sprintf(buf, "ROSE (%.9s %.18s)",
u.call, u.ul_name);
break;
case AF_INET:
if (!verbose && (cp = strstr(u.ul_name, ".ampr.org")) != NULL)
*cp = 0;
sprintf(buf, "Telnet (%.9s @ %.16s)",
u.call, u.ul_name);
break;
case AF_UNSPEC:
sprintf(buf, "Host (%.9s on local)",
u.call);
break;
default:
/* something strange... */
sprintf(buf, "?????? (%.9s %.18s)",
u.call, u.ul_name);
break;
}
nprintf("%-37.37s ", buf);
switch (u.state) {
case STATE_LOGIN:
nputs(" -> Logging in");
break;
case STATE_IDLE:
time(&l);
l -= u.cmdtime;
tp = gmtime(&l);
nprintf(" -> Idle (%d:%02d:%02d:%02d)",
tp->tm_yday, tp->tm_hour,
tp->tm_min, tp->tm_sec);
break;
case STATE_TRYING:
switch (u.dl_type) {
case AF_AX25:
nprintf(" -> Trying (%s on port %s)",
u.dl_name, u.dl_port);
break;
case AF_NETROM:
nprintf(" -> Trying (%s)",
u.dl_name);
break;
case AF_ROSE:
nprintf(" -> Trying (%s)",
u.dl_name);
break;
case AF_INET:
if (!verbose && (cp = strstr(u.dl_name, ".ampr.org")) != NULL)
*cp = 0;
nprintf(" -> Trying (%s:%s)",
u.dl_name, u.dl_port);
break;
default:
nputs(" -> ???");
break;
}
break;
case STATE_CONNECTED:
switch (u.dl_type) {
case AF_AX25:
nprintf("<--> Downlink (%s on port %s)",
u.dl_name, u.dl_port);
break;
case AF_NETROM:
nprintf("<--> Circuit (%s)",
u.dl_name);
break;
case AF_ROSE:
nprintf("<--> ROSE (%s)",
u.dl_name);
break;
case AF_INET:
if (!verbose && (cp = strstr(u.dl_name, ".ampr.org")) != NULL)
*cp = 0;
nprintf("<--> Telnet (%s:%s)",
u.dl_name, u.dl_port);
break;
default:
nprintf("<--> ???");
break;
}
break;
case STATE_PINGING:
if (!verbose && (cp = strstr(u.dl_name, ".ampr.org")) != NULL)
*cp = 0;
nprintf("<--> Pinging (%s)", u.dl_name);
break;
case STATE_EXTCMD:
nprintf("<--> Extcmd (%s)", u.dl_name);
break;
default:
/* something strange... */
nputs(" -> ??????");
break;
}
nputs("\n");
}
fclose(f);
return 0;
}
int user_count(void)
{
FILE *f;
struct user u;
int cnt = 0;
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
return 0;
}
while (fread(&u, sizeof(u), 1, f) == 1)
if (u.pid != -1 && (kill(u.pid, 0) != -1 || errno != ESRCH))
cnt++;
fclose(f);
return cnt;
}
node-0.3.0/util.c 100644 764 764 5043 6707433523 11446 0 ustar tpm tpm #include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <time.h>
#include <sys/file.h>
#include <netdb.h>
#include <sys/socket.h>
#include "node.h"
static char buf[4096];
int nputs(const char *str)
{
return axio_puts(str, NodeIo);
}
int nprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
return nputs(buf);
}
void node_msg(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
nputs(NodeId);
nputs(" ");
nputs(buf);
nputs("\n");
}
void node_perror(char *str, int err)
{
int oldmode;
oldmode = axio_eolmode(NodeIo, EOLMODE_TEXT);
buf[0] = 0;
if (str)
strcpy(buf, str);
if (str && err != -1)
strcat(buf, ": ");
if (err != -1)
strcat(buf, strerror(err));
nputs(NodeId);
nputs(" ");
nputs(buf);
nputs("\n");
axio_flush(NodeIo);
axio_eolmode(NodeIo, oldmode);
log(L_ERROR, buf);
}
char *print_node(const char *alias, const char *call)
{
static char node[17];
sprintf(node, "%s%s%s",
!strcmp(alias, "*") ? "" : alias,
!strcmp(alias, "*") ? "" : ":",
call);
return node;
}
char *print_dl(struct user *u)
{
static char buf[64];
switch (u->dl_type) {
case AF_AX25:
sprintf(buf, "%s on port %s", u->dl_name, u->dl_port);
break;
case AF_NETROM:
case AF_ROSE:
sprintf(buf, "%s", u->dl_name);
break;
case AF_INET:
sprintf(buf, "%s:%s", u->dl_name, u->dl_port);
break;
}
return buf;
}
void put_prompt(void)
{
char *p;
if (strchr(NodePrompt, '%') == NULL) {
nputs(NodePrompt);
return;
}
p = expand_string(NodePrompt, 0, NULL);
nputs(p);
free(p);
}
void log(int loglevel, const char *fmt, ...)
{
va_list args;
int pri;
static int opened = 0;
if (LogLevel < loglevel)
return;
if (!opened) {
openlog("node", LOG_PID, LOG_LOCAL7);
opened = 1;
}
switch (loglevel) {
case L_ERROR:
pri = LOG_ERR;
break;
case L_LOGIN:
pri = LOG_NOTICE;
break;
case L_GW:
pri = LOG_INFO;
break;
default:
pri = LOG_INFO;
break;
}
va_start(args, fmt);
vsprintf(buf, fmt, args);
syslog(pri, buf);
va_end(args);
}
char *strherror(int err)
{
static char buf[64];
switch (err) {
case HOST_NOT_FOUND:
strcpy(buf, "Unknown host");
break;
case TRY_AGAIN:
strcpy(buf, "Temporary name server error");
break;
case NO_RECOVERY:
strcpy(buf, "Non-recoverable name server error");
break;
case NO_ADDRESS:
strcpy(buf, "No address");
break;
default:
strcpy(buf, "Unknown error");
break;
}
return buf;
}
node-0.3.0/etc/ 40755 764 764 0 6740167127 11002 5 ustar tpm tpm node-0.3.0/etc/loggedin 100644 764 764 0 6266456343 12524 0 ustar tpm tpm node-0.3.0/etc/node.conf 100644 764 764 3125 6740167036 12673 0 ustar tpm tpm # /etc/ax25/node.conf - LinuxNode configuration file
#
# see node.conf(5)
# Idle timeout (seconds).
#
IdleTimeout 900
# Timeout when gatewaying (seconds).
#
ConnTimeout 14400
# Visible hostname. Will be shown at telnet login.
#
HostName oh2bns.ampr.org
# Node ID.
#
NodeId #BNSNR:OH2BNS-10}
#NodeId \033[01;31m***\033[0m
# ReConnect flag.
#
ReConnect on
# "Local" network.
#
LocalNet 44.139.0.0/16
# Command aliases.
#
Alias CAllbook 'telnet %{2:jazz.oh7lzb.ampr.org} 1235 %1'
Alias CONVers 'telnet %{2:hydra.carleton.ca} 3600 "/n %u %{1:32768}\n/w *"'
Alias CLuster 'c hkiclh'
# Hidden ports.
#
#HiddenPorts 2
# External commands
#
# Flags: 1 Run command through pipe
# 2 Reconnect prompt
#
ExtCmd PMS 3 root /usr/sbin/pms pms -u \%U -o OH2BNS
#ExtCmd PS 1 nobody /bin/ps ps ax
#ExtCmd TPM 1 nobody /usr/bin/finger finger tpm
#ExtCmd Vpaiva 1 nobody /home/tpm/bin/vpaiva vpaiva
#ExtCmd NOde 0 root /usr/local/bin/node node
ExtCmd ECho 1 nobody /bin/echo echo \%U\%u \%S\%s \%P\%p \%R\%r \%T\%t \%\% \%0 \%1 \%2 \%3 \%4 \%5 \%6 \%7 \%8 \%9
#ExtCmd ECho 1 nobody /bin/echo echo foo\%{1:***}bar \%{U}\%{0:foo}\%{1:bar}\%{2:huu}\%{3:haa}
ExtCmd TIme 1 nobody /bin/echo echo %N Node session started at %I, current time is \%I.
# Netrom port name. This port is used for outgoing netrom connects.
#
NrPort netrom
# Logging level
#
LogLevel 3
# The escape character (CTRL-T)
#
EscapeChar ^T
# Resolve ip numbers to addresses?
#
ResolveAddrs off
# Node prompt.
#
NodePrompt "\n"
#NodePrompt "\n%s@%h \%i> "
#NodePrompt "\033[36m%U\033[0m de \033[01;35m#LNODE\033[0m:\033[01;31mOH2BNS-10\033[0m> "
node-0.3.0/etc/node.perms 100644 764 764 643 6330424573 13053 0 ustar tpm tpm # /etc/ax25/node.perms - LinuxNode permissions file
#
# see node.perms(5)
# user type port passwd perms
# User oh2bns can login without password from anywhere else but 'inet'.
#
oh2bns inet * qwerty 95
oh2bns * * * 95
# OH2RBI is a bbs so it needs escape disabled.
#
oh2rbi * * * 287
# Default permissions per connection type.
#
* ax25 * * 31
* netrom * * 31
* local * * 31
* ampr * * 31
* inet * * 0
* host * * 31
node-0.3.0/etc/help/ 40755 764 764 0 6425201307 11717 5 ustar tpm tpm node-0.3.0/etc/help/bye.hlp 100644 764 764 110 6266456343 13267 0 ustar tpm tpm
USAGE
bye
DESCRIPTION
Disconnects you from this node.
node-0.3.0/etc/help/connect.hlp 100644 764 764 1746 6266456343 14201 0 ustar tpm tpm
USAGE
connect <port> <call> [via <digi1> ...] [s|d] For AX.25
connect <call | alias> [s|d] For NET/ROM
connect <call> <address> [<digi>] [d|s] For ROSE
DESCRIPTION
Initiates an AX.25, NET/ROM or ROSE connection to a remote
host. If more than two parameters are entered and the
second parameter is ten charachers in length then it is
interpreted as a ROSE connection, otherwise the first
parameter is interpreted as a port name and AX.25 is used
to make the connection via that port. If only one parameter
is given the connection is made using NET/ROM.
If a single `s' is entered as the last parameter, then when
the remote host disconnects you will be returned to this node.
If a single `d' is entered as the last parameter, you will
be disconnected from this node too. Default behaviour (neither
`s' nor `d' entered) depends on sysop configuration.
node-0.3.0/etc/help/help.hlp 100644 764 764 362 6266456343 13451 0 ustar tpm tpm
USAGE
help [<command>]
DESCRIPTION
Gives help for the specified command or this text if no
command is specified. Commands can not be abbreviated.
Use the "?" command to retrieve a list of available commands.
node-0.3.0/etc/help/info.hlp 100644 764 764 331 6300553463 13436 0 ustar tpm tpm
USAGE
info
DESCRIPTION
Displays the version information and the contents of the
/etc/ax25/node.info file, which describes those aspects of
the system that the sysop likes to brag about.
node-0.3.0/etc/help/mheard.hlp 100644 764 764 260 6266456343 13756 0 ustar tpm tpm
USAGE
mheard <port>
DESCRIPTION
Gives a list of heard AX.25 stations on the specified port.
Use the "Ports" command to get a list of available ports.
node-0.3.0/etc/help/finger.hlp 100644 764 764 570 6266456343 13774 0 ustar tpm tpm
USAGE
finger [<username>][@<hostname>]
DESCRIPTION
Retrieves information about users of a system. If the user
name is omitted, shows the users currently logged on the
host. If the hostname is omitted, defaults to the local host.
EXAMPLES
finger @soul.oh7rba.ampr.org
finger oh7lzb@soul.oh7rba.ampr.org
finger oh7lzb
node-0.3.0/etc/help/links.hlp 100644 764 764 537 6270751314 13634 0 ustar tpm tpm
USAGE
links [* | <call>]
DESCRIPTION
Gives a list of active AX.25 connections to and from the
local host. With an asterisk (*) as an argument shows also
AX.25 sockets in listening state. With a callsign as an
argument gives a list of all connections with either
source or destination callsign <call>.
node-0.3.0/etc/help/nodes.hlp 100644 764 764 1217 6266456343 13651 0 ustar tpm tpm
USAGE
nodes [*|<nodecall>]
DESCRIPTION
Shows the NET/ROM node table of the local host. The nodes on this
list can be reached using the Connect command without knowing the
actual network path used (assuming the network is OK).
The optional parameter * toggles verbose mode, showing the
Obsolescence counter, relative path quality and the port and
neighbour node used to reach each node. You can also specify
a node callsign to get the verbose information for a single node.
In that case a "which" field that tells what route the kernel
will use to reach the node is shown.
node-0.3.0/etc/help/ping.hlp 100644 764 764 735 6266456343 13462 0 ustar tpm tpm
USAGE
ping <hostname> [<length>]
DESCRIPTION
Checks if a host can be reached trough the network by sending
an ICMP Echo Request packet to the host and waiting for it to
reply. If a reply is received the round-trip-time (RTT)
between the local and remote hosts is shown.
If an optional length is specified the data portion of the
packet is filled with length number of bytes.
EXAMPLE
ping soul.oh7rba.ampr.org
node-0.3.0/etc/help/ports.hlp 100644 764 764 641 6266456343 13670 0 ustar tpm tpm
USAGE
ports
DESCRIPTION
Shows the available AX.25 ports. Shown are the port name, the speed
of the port (in bits/sec) and a short description for the port.
The port name is used when using the Connect command to connect
to an user or service not running NET/ROM (eg. not visible in the
Nodes list). The port name is also visible in the Route and Link
lists.
node-0.3.0/etc/help/routes.hlp 100644 764 764 1216 6266456343 14061 0 ustar tpm tpm
USAGE
routes
DESCRIPTION
Shows the NET/ROM route table of the local host (eg. the nodes
which the local node directly talks with). These nodes are used
to reach the other nodes on the node table. Fields shown are:
Link - Is there an AX.25 connection active to this node
Port - Which port is this route on
Callsign - The callsign of the neighbour node
Quality - A relative quality for the path (0-255)
Destinations - Number of other nodes reached via this route
Lock - Is the quality of this route locked by the operator
node-0.3.0/etc/help/telnet.hlp 100644 764 764 1744 6266456343 14041 0 ustar tpm tpm
USAGE
telnet <host> [<port>] [s|d]
DESCRIPTION
Initiates a telnet session to a remote host using TCP/IP.
You might not be able to connect to a given host due to the
local operator's policy of using this node, or simply because
the host is unreachable due to a network failure. You can use
the ping command to check if a host is reachable.
By default, the telnet command connects to the TCP port 23
(allocated for telnet). You can specify another TCP port or
a TCP port name.
If a single `s' is entered as the last parameter, then when
the remote host disconnects you will be returned to this node.
If a single `d' is entered as the last parameter, you will
be disconnected from this node too. Default behaviour (neither
`s' nor `d' entered) depends on sysop configuration.
EXAMPLES
telnet soul.oh7rba.ampr.org
telnet soul.oh7rba 7
telnet 44.139.39.8 echo
node-0.3.0/etc/help/users.hlp 100644 764 764 277 6266456343 13667 0 ustar tpm tpm
USAGE
users
DESCRIPTION
Shows a list of users currently connected to the local node,
where the users are coming from, and what are they doing at the
moment.
node-0.3.0/etc/help/status.hlp 100644 764 764 1023 6266456343 14057 0 ustar tpm tpm
USAGE
status
DESCRIPTION
Returns information about the status of the Linux system which this
LinuxNode runs on. All information is taken directly from the
operating system.
The "load average" values indicate the average amount of processes
waiting for processor time during the last 1, 5 and 15 minutes.
Load average of 1.0 would mean that the all of the processor time is
used by the processes, and all processes still get all of the time
they can use.
node-0.3.0/etc/help/host.hlp 100644 764 764 617 6266456343 13501 0 ustar tpm tpm
USAGE
host <hostname>|<ip address>
DESCRIPTION
Tells information about an Internet host. The host can be identified
using a host name (for example, zone.oh7rba.ampr.org) or an IP
address (for example, 44.139.39.6).
Returns the host name, IP addresses and known aliases for the host.
The information is gathered from the DNS (domain name service).
node-0.3.0/etc/help/talk.hlp 100644 764 764 754 6272432644 13454 0 ustar tpm tpm
USAGE
talk <user> <message>
DESCRIPTION
Sends a one-line message to another user of the node. The user
in question must be in idle state (ie. not connected/connecting
anywhere or running a program).
If the user has an SSID other than zero, the SSID must be
specified. If multiple users are logged in with the same
callsign/SSID pair, those who are in idle state, get the message.
EXAMPLES
talk oh7lzb-3 Good evening, Hessu!
node-0.3.0/etc/help/escape.hlp 100644 764 764 1101 6404550267 13763 0 ustar tpm tpm
USAGE
escape <escape char>
DESCRIPTION
Sets the character will be treated as the signal to close down any
open connection made from the node.
You can specify the escape character in a number of ways. They are:
<char> the actual binary character
^T to set it to Control-T (or any other control character)
0xNN to set it to hexadecimal value NN
0NNN to set it to Octal value NNN
NNN to set it to decimal value NNN (no leading zero!)
off to disable the escape character
node-0.3.0/etc/help/nlinks.hlp 100644 764 764 213 6425171026 13777 0 ustar tpm tpm
USAGE
nlinks
DESCRIPTION
Gives a list of both active NET/ROM connections and NET/ROM
sockets in listening state.
node-0.3.0/etc/help_french/ 40775 764 764 0 6404550637 13260 5 ustar tpm tpm node-0.3.0/etc/help_french/bbs.hlp 100644 764 764 102 6402074460 14570 0 ustar tpm tpm
USAGE
bbs
DESCRIPTION
Connexion au BBS F8KAE-1.
node-0.3.0/etc/help_french/bye.hlp 100644 764 764 101 6402074460 14600 0 ustar tpm tpm
USAGE
bye
DESCRIPTION
Deconnexion de ce noeud.
node-0.3.0/etc/help_french/connect.hlp 100644 764 764 2055 6402074460 15504 0 ustar tpm tpm
USAGE
connect <port> <indicatif> [via <digi1> ...] [s|d] Pour AX.25
connect <indicatif | alias> [s|d] Pour NET/ROM
connect <indicatif> <adresse> [<digi>] [d|s] Pour ROSE
DESCRIPTION
Ouvre une connexion AX.25, NET/ROM ou ROSE sur un hote eloigne.
Si plus de deux parametres sont entres et que le deuxieme
parametre fait dix caracteres, alors c'est interprete comme
une connexion ROSE, autrement le premier parametre est
interprete en tant que nom de port et AX.25 est utilise pour
faire la connexion via ce port. Si un seul parametre est entre
la connexion est faite en utilisant NET/ROM.
Si un simple `s' est entre comme dernier parametre, alors quand
l'hote eloigne fera une deconnexion, vous reviendrez sur ce
noeud. Si un simple `d' est entre comme dernier parametre, alors
vous serez egalement deconnecte de ce noeud. Le comportement par
defaut (ni `s' ni `d' entres) depend de la configuration par
le sysop.
node-0.3.0/etc/help_french/dx.hlp 100644 764 764 111 6402074460 14435 0 ustar tpm tpm
USAGE
dx
DESCRIPTION
Connexion au PacketCluster F6BEE.
node-0.3.0/etc/help_french/escape.hlp 100644 764 764 1203 6402074460 15305 0 ustar tpm tpm
USAGE
escape <escape car>
DESCRIPTION
Defini le caractere qui sera traite comme le signal de fermeture
de n'importe quelle connexion ouverte a partir du noeud.
Vous pouvez specifier le caractere d'echappement de differentes
facons. Les voici:
<char> le veritable caractere binaire
^T Pour le definir en Controle-T
(ou n'importe quel autre caractere de controle)
0xNN Pour le definir en valeur Hexadecimale NN
0NNN Pour le definir en valeur Octale NNN
NNN Pour le definir en valeur Decimale NNN (sans zero avant !)
node-0.3.0/etc/help_french/finger.hlp 100644 764 764 622 6402074460 15303 0 ustar tpm tpm
USAGE
finger [<utilisateur>][@<serveur>]
DESCRIPTION
Informe sur les utilisateurs d'un systeme. Si le nom de
l'utilisateur est omis, affiche les utilisateurs actuellement
enregistres sur le serveur. Si le nom du serveur est omis,
le defaut est le serveur local.
EXEMPLES
finger @f6fgz.ampr.org
finger f5suy@f6fgz.ampr.org
finger f5suy
node-0.3.0/etc/help_french/help.hlp 100644 764 764 426 6402074460 14763 0 ustar tpm tpm
USAGE
help [<commande>]
DESCRIPTION
Aide pour la commande specifiee ou ce texte si aucune commande
n'est specifiee. Les commandes ne peuvent pas etre abregees.
Utilisez la commande "?" pour retrouver la liste des commandes
disponibles.
node-0.3.0/etc/help_french/host.hlp 100644 764 764 641 6402074460 15007 0 ustar tpm tpm
USAGE
host <serveur>|<adresse ip>
DESCRIPTION
Informe sur un serveur Internet. Le serveur peut etre identifie
par un nom (par exemple, f6fgz.ampr.org) ou par une adresse IP
(par exemple, 44.151.78.19).
Renvoie le nom du serveur, les adresses IP et les alias connus
pour le serveur. L'information est recueillie a partir du serveur
DNS (domain name service).
node-0.3.0/etc/help_french/info.hlp 100644 764 764 325 6402074460 14764 0 ustar tpm tpm
USAGE
info
DESCRIPTION
Affiche l'information de version ainsi que le contenu du
fichier /etc/ax25/node.info, qui decrit ces aspects du
systeme dont les sysops aiment a se vanter.
node-0.3.0/etc/help_french/links.hlp 100644 764 764 603 6402074460 15150 0 ustar tpm tpm
USAGE
links [* | <indicatif>]
DESCRIPTION
Liste les connexions AX.25 actives depuis et vers le serveur
local. Avec un asterisque (*) comme argument, affiche aussi
les prises AX.25 en etat d'ecoute. Avec un indicatif comme
argument, liste toutes les connexions avec soit l'indicatif
en source soit l'indicatif en destination <indicatif>.
node-0.3.0/etc/help_french/mheard.hlp 100644 764 764 303 6402074460 15265 0 ustar tpm tpm
USAGE
mheard <port>
DESCRIPTION
Liste les stations AX.25 entendues sur le port specifie.
Utilisez la commande "Ports" pour avoir la liste des ports
disponibles.
node-0.3.0/etc/help_french/nodes.hlp 100644 764 764 1424 6402074460 15162 0 ustar tpm tpm
USAGE
nodes [*|<indicatif>]
DESCRIPTION
Affiche la table des noeuds NET/ROM sur le serveur local. Les
noeuds sur cette liste peuvent etre atteints en utilisant la
commande Connect sans connaitre le veritable cheminement utilise
dans le reseau (en supposant que le reseau est OK).
Le parameter optionnel * alterne le mode verbeux, affichant le
compteur d'obsolescence, la qualite relative du chemin ainsi que
le port et le noeud voisin utilise pour atteindre chaque noeud.
Vous pouvez aussi specifier un indicatif de noeud pour obtenir
l'information verbeuse pour un simple noeud. Dans ce cas, un
champ "which" est affiche pour dire quelle route le noyau utilisera
pour atteindre le noeud.
node-0.3.0/etc/help_french/ping.hlp 100644 764 764 1033 6402074460 15003 0 ustar tpm tpm
USAGE
ping <serveur> [<longueur>]
DESCRIPTION
Verifie si un serveur peut etre atteint au travers du reseau
en envoyant un paquet demande d'echo ICMP vers le serveur et
en attendant sa reponse. Si une reponse est recue, le temps
d'aller-retour (round-trip-time RTT) entre le serveur distant
et local, est affiche.
Si une longueur facultative est specifiee, la portion de
donnees du paquet est remplie du nombre d'octets de la longueur.
EXEMPLE
ping f6fgz.ampr.org
node-0.3.0/etc/help_french/ports.hlp 100644 764 764 735 6402074460 15205 0 ustar tpm tpm
USAGE
ports
DESCRIPTION
Affiche les ports AX.25 disponibles. Sont affiches le nom du port,
la vitesse du port (en bits/sec) et une courte description pour
le port. Le nom du port est utilise en utilisant la commande
Connect pour se connecter vers un utilisateur ou un service
n'utilisant pas NET/ROM (c.a.d. non visible dans la liste des
Noeuds). Le nom du port est aussi visible dans les listes Route
et Link.
node-0.3.0/etc/help_french/routes.hlp 100644 764 764 1354 6402074460 15375 0 ustar tpm tpm
USAGE
routes
DESCRIPTION
Affiche la table de routage NET/ROM du serveur local (c.a.d. les
noeuds pour lesquels le noeud local dialogue directement).
Ces noeuds sont utilises pour atteindre les autres noeuds dans
la table des noeuds. Les champs affiches sont:
Link - Si il y a une connexion AX.25 active vers ce noeud
Port - Sur quel port est cette route
Callsign - L'indicatif du noeud voisin
Quality - Une qualite relative pour le chemin (0-255)
Destinations - Nombre des autres noeuds atteints via cette route
Lock - Si la qualite de cette route est verrouillee par
l'operateur
node-0.3.0/etc/help_french/status.hlp 100644 764 764 1107 6402074460 15373 0 ustar tpm tpm
USAGE
status
DESCRIPTION
Renvoie l'information de l'etat du systeme Linux sur lequel ce
LinuxNode fonctionne. Toutes les informations sont prises
directement depuis le systeme d'operation.
La valeur de la "charge moyenne" (load average) indique la quantite
moyenne des taches attendant du temps CPU durant les 1, 5 et 15
dernieres minutes. Une charge moyenne de 1.0 signifierait que
tout le temps CPU est utilise par les taches, et que toutes les
taches obtiennent encore le temps qu'elles peuvent utiliser.
node-0.3.0/etc/help_french/talk.hlp 100644 764 764 1037 6402074460 15005 0 ustar tpm tpm
USAGE
talk <utilisateur> <message>
DESCRIPTION
Envoie un message d'une ligne vers un autre utilisateur du noeud.
L'utilisateur en question doit etre inoccupe (idle)(ex. ni
connecte/connectant quelque part ou utilisant un programme).
Si l'utilisateur a un SSID autre que zero, le SSID doit etre
specifie. Si de multiples utilisateurs sont enregistres avec
la meme paire indicatif/SSID, ceux qui sont inoccupes recoivent
le message.
EXEMPLE
talk f5suy-3 Bonsoir, Yvan!
node-0.3.0/etc/help_french/telnet.hlp 100644 764 764 2135 6402074460 15345 0 ustar tpm tpm
USAGE
telnet <serveur> [<port>] [s|d]
DESCRIPTION
Ouvre une session telnet vers un serveur distant utilisant
TCP/IP. Vous pourriez ne pas connecter un serveur donne a
cause de la politique d'utilisation de ce noeud par l'operateur
local, ou simplement parce que le serveur n'est pas atteint
a cause d'une panne de reseau. Vous pouvez utiliser la
commande Ping pour verifier si on peut atteindre un serveur.
Par defaut, la commande Telnet connecte sur le port TCP 23
(alloue pour telnet). Vous pouvez specifier un autre port
TCP ou un nom de port TCP.
Si un simple `s' est entre comme dernier parametre, alors quand
l'hote eloigne fera une deconnexion, vous reviendrez sur ce
noeud. Si un simple `d' est entre comme dernier parametre, alors
vous serez egalement deconnecte de ce noeud. Le comportement par
defaut (ni `s' ni `d' entres) depend de la configuration par
le sysop.
EXEMPLES
telnet f6fgz.ampr.org
telnet f6fgz.ampr.org 41112
telnet 44.151.78.19 echo
node-0.3.0/etc/help_french/users.hlp 100644 764 764 302 6402074460 15165 0 ustar tpm tpm
USAGE
users
DESCRIPTION
Affiche une liste d'utilisateurs actuellement connectes au
noeud local, d'ou les utilisateurs viennent, et ce qu'ils
font en ce moment.
node-0.3.0/etc/node.motd 100644 764 764 136 6732001755 12664 0 ustar tpm tpm
Type ? for a list of commands. help <commandname> gives a description
of the named command.
node-0.3.0/ipc.c 100644 764 764 5713 6707433742 11253 0 ustar tpm tpm #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "node.h"
/*
* This one (c) 1996 by Heikki Hannikainen, OH7LZB <hessu@pspt.fi>
*/
#define FIRST_KEY (3694 - 1) /* Where to start looking for a key */
#define LAST_KEY (FIRST_KEY + 200) /* How far to search */
#define M_LEN 1024 /* Largest message transferred */
struct nmsgbuf {
long mtype; /* message type, must be > 0 */
char mtext[M_LEN]; /* message data */
};
static int ipc_id = -1;
static void usr2_handler(int sig)
{
struct nmsgbuf buf;
if (msgrcv(ipc_id, (struct msgbuf *)&buf, M_LEN, 0, IPC_NOWAIT|MSG_NOERROR) != -1) {
node_msg(buf.mtext);
} else
log(L_ERROR, "usr2_handler: Catched SIGUSR2, but couldn't receive a message");
signal(SIGUSR2, usr2_handler); /* Restore handler */
}
int ipc_send(key_t key, long mtype, char *mtext)
{
struct nmsgbuf buf;
int id;
if ((id = msgget(key, 7)) == -1) {
node_perror("ipc_send: Could not get transmit channel", errno);
return -1;
}
buf.mtype = mtype;
strncpy(buf.mtext, mtext, M_LEN);
if (msgsnd(id, (struct msgbuf *)&buf, M_LEN, 0) == -1) {
node_perror("ipc_send: Could not send message", errno);
return -1;
}
return 0;
}
int ipc_open(void)
{
key_t key = FIRST_KEY;
do {
key++;
ipc_id = msgget(key, 7 | IPC_CREAT | IPC_EXCL);
} while ((ipc_id == -1) && (key != LAST_KEY));
if (ipc_id == -1)
node_perror("ipc_open: Could not get an IPC channel", errno);
#if 0
node_msg("debug: ipc_id=%d key=%d", ipc_id, key);
#endif
User.ipc_key = key;
if (key != -1)
signal(SIGUSR2, usr2_handler);
else
signal(SIGUSR2, SIG_IGN);
return 0;
}
int ipc_close(void)
{
struct msqid_ds buf;
if (ipc_id != -1) /* Remove the IPC channel */
if (msgctl(ipc_id, IPC_RMID, &buf) == -1) {
log(L_ERROR, "ipc_close: Could not remove IPC channel: %s", strerror(errno));
return -1;
}
return 0;
}
int do_talk(int argc, char **argv)
{
FILE *f;
struct user u;
char call[10];
char mtext[M_LEN];
int i, hits = 0, sent = 0;
if (argc < 3) {
node_msg("Usage: talk <user> <message>");
return 0;
}
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
return 0;
}
sprintf(mtext, "Message from %s:\n", User.call);
for (i = 2; i < argc; i++) {
strncat(mtext, argv[i], M_LEN - strlen(mtext));
strncat(mtext, " ", M_LEN - strlen(mtext));
}
strncat(mtext, "\n--", M_LEN - strlen(mtext));
strncpy(call, argv[1], 9);
call[9] = 0;
while (fread(&u, sizeof(u), 1, f) == 1) {
if (u.pid == -1 || (kill(u.pid, 0) == -1 && errno == ESRCH))
continue;
if (!strcasecmp(u.call, call)) {
hits++;
if (u.ipc_key != -1 && u.state == STATE_IDLE) {
ipc_send(u.ipc_key, 1, mtext);
kill(u.pid, SIGUSR2);
sent++;
}
}
}
fclose(f);
if (hits == 0)
node_msg("No such user %s", call);
else if (sent == 0)
node_msg("%s is busy, cannot talk to him right now.", call);
return 0;
}
node-0.3.0/telnet.h 100644 764 764 2746 6454011245 11770 0 ustar tpm tpm /* Telnet command characters */
#define TN_SE 240 /* End of subnegotiation parameters */
#define TN_NOP 241 /* No operation */
#define TN_DM 242 /* Data Mark */
#define TN_BRK 243 /* NVT character BRK */
#define TN_IP 244 /* Interrupt Process */
#define TN_AO 245 /* Abort output */
#define TN_AYT 246 /* Are You There */
#define TN_EC 247 /* Erase character */
#define TN_EL 248 /* Erase Line */
#define TN_GA 249 /* Go ahead */
#define TN_SB 250 /* Start of of subnegotiation params */
#define TN_WILL 251
#define TN_WONT 252
#define TN_DO 253
#define TN_DONT 254
#define TN_IAC 255 /* Interpret as command */
/* Linemode extensions to telnet command characters */
#define TN_EOF 236 /* End Of File */
#define TN_SUSP 237 /* Suspend */
#define TN_ABORT 238 /* Abort */
/* Telnet options */
#define TN_TRANS_BINARY 0 /* Binary Transmission */
#define TN_ECHO 1 /* Echo */
#define TN_SUPPRESS_GA 3 /* Suppress Go Ahead */
#define TN_STATUS 5 /* Status */
#define TN_TIMING_MARK 6 /* Timing Mark */
#define TN_LINEMODE 34 /* Linemode */
/* Linemode options */
#define TN_LINEMODE_MODE 1
#define TN_LINEMODE_MODE_EDIT 1 /* Local edit */
#define TN_LINEMODE_MODE_TRAPSIG 2 /* Trap signals */
#define TN_LINEMODE_MODE_MODEACK 4 /* Acknowledge mode */
#define TN_LINEMODE_MODE_SOFTTAB 8 /* Soft Tab */
#define TN_LINEMODE_MODE_LITECHO 16 /* Literal Echo */
#define TN_LINEMODE_FORWARDMASK 2
#define TN_LINEMODE_SLC 3
node-0.3.0/AUTHORS 100644 764 764 571 6724621236 11355 0 ustar tpm tpm LinuxNode is based on the original pms.c by Alan Cox GW4PTS, but has been
mostly rewritten by me since. Also at least the following people have
conributed code:
Jonathan Naylor G4KLX
Heikki Hannikainen OH7LZB
Jean-Paul Roubelat F6FBB
Terry Dawson VK2KTJ
If you were accidentally left out, don't hesitate to email me.
--
Tomi Manninen OH2BNS, <tomi.manninen@hut.fi>
node-0.3.0/man/ 40755 764 764 0 6732000003 10756 5 ustar tpm tpm node-0.3.0/man/node.8 100644 764 764 20255 6731773020 12134 0 ustar tpm tpm .TH NODE 8 "16 June 1999" Linux "Linux System Managers Manual"
.SH NAME
node \- Node front end for AX.25, NET/ROM, Rose and TCP
.SH SYNOPSIS
.B node [-c]
.SH DESCRIPTION
.LP
.B Node
is a simple node front end, modelled after the node shells of TheNet
and G8BPQ nodes.
.SH OPTIONS
.TP 14
.BI \-c
Enable compression. With this option it is assumed that the incoming
call is using Zlib based compression (modified Lempel-Ziv 1977).
Currently no negotiation is done so the
caller must be aware of this. You probably want to set up a separate
AX.25, NET/ROM or ROSE callsign in ax25d.conf or a separate TCP port
in inetd.conf to listen to compressed connects.
.sp 1
At the moment I know only two implementations compatible with this
compression method, namely LinuxNode and Clussed.
.SH NODE COMMANDS
The following commands are supported for users of
.B node:
.TP 14
.BI ?
Give short list of available commands.
.TP 14
.BI Bye
Disconnect user from the node.
.TP 14
.BI "Connect <port> <call> [via <call1> ...] [d|s] For AX.25"
.TP 14
.BI "Connect <call | alias> [d|s] For NET/ROM"
.TP 14
.BI "Connect <call> <address> [<digi>] [d|s] For ROSE"
.sp 1
Initiate an AX.25, NET/ROM or ROSE connection to a remote host.
If only one argument is supplied then the connection is assumed to be a
NET/ROM connection and the argument specifies the callsign of alias of a
NET/ROM node. If more than one argument is supplied and the second parameter
is composed of numeric characters only then the connection is assumed to be
a ROSE connection. Any other combination is assumed to be an AX.25 connection
with the first argument being the AX25 port to use for the connection.
.sp
For a ROSE connection the <address> part must be exactly six or ten digits.
If only six digits are supplied, the DNIC (first four digits) default to the
local DNIC. The local DNIC is assumed to be that of the first configured
Rose port in /etc/ax25/rsports.
.sp
The user may optionally supply as the last argument a single character
which modifies the default behaviour on disconnection of the connection.
If a single `s' is entered as the last argument, then when the remote host
disconnects you will be returned to this node. If a single `d' is entered as
the last argument, you will be disconnected from this node too. The Default
behaviour (neither `s' nor `d' entered) is configured in the node configuration
file and depends on the sysop preference.
.TP 14
.BI "Escape [<escape string>]"
Override the sysop configured default escape character setting. If the Escape
command is given without an argument then the current escape character setting
is returned to the user. The escape string may be specified using any of the
well known codings:
.IP
.BI "<char>"
to enter the escape character in its binary form.
.IP
.BI "^C"
to enter the escape character as a control character value.
.IP
.BI "NNN"
to set the escape character to a Decimal value.
.IP
.BI "0xNN"
to set the escape character to a HexaDecimal value.
.IP
.BI "0NNN"
to set the escape character to an Octal value.
.IP
.BI "off"
to disable the escape character.
.TP 14
.BI "Finger [<username>][@<hostname>]"
Retrieve information about users of a system. If the user
name is omitted, shows the users currently logged on the
host. If the hostname is omitted, defaults to the local host.
.TP 14
.BI "Help [<command>]"
Give help for the specified command or this text if no
command is specified. Commands can not be abbreviated.
Use the "?" command to retrieve a list of available commands.
.TP 14
.BI "HOst <hostname> | <ip address>"
Give the Domain Name Service host name information about <hostname> or
<ip address>.
.TP 14
.BI Info
Display the version information and the contents of the
/etc/ax25/node.info file, which should describe any aspects
of your system that you would like to brag about.
.TP 14
.BI "Links [* | <call>]"
Give a list of active AX.25 connections to and from the local host.
With an optional argument * list also AX.25 sockets in state listening.
A callsign as argument gives a list of all connections with <call> as
source or destination address.
.TP 14
.BI "Mheard <portname>"
Give a list of heard AX.25 stations on the specified port.
.TP 14
.BI "NLinks"
Give a list of active NET/ROM connections to and from the local host.
.TP 14
.BI "Nodes [* | <node>]"
Show the NET/ROM node table of the local host. The nodes on this
list can be reached using the Connect command without knowing the
actual network path used (assuming the network is OK).
.sp
The optional argument '*' toggles verbose mode, showing the
Obsolescence counter, relative path quality and the port and
neighbour node used to reach each node. You can also specify
a node callsign to get the verbose information for a single node.
In that case a "which" field that tells what route the kernel
will use to reach the node is also shown.
.TP 14
.BI Ports
Show the available AX.25 ports. Shown are the port name and a short
description for the port. The port name is used when using the Connect
command to connect to an user or service not running NET/ROM (eg. not
visible in the Nodes list).
.TP 14
.BI "PIng <host> [<size>]"
Check if a host can be reached trough the network by sending
an ICMP Echo Request packet to the host and waiting for it to
reply. If a reply is received the round-trip-time (RTT)
between the local and remote hosts is shown.
.sp
If an optional length is specified the data portion of the
packet is filled with length number of bytes.
.TP 14
.BI Routes
Show the NET/ROM neighbour table of the local host (ie. the nodes
which the local node directly talks with). These nodes are used
to reach the other nodes on the node table.
.TP 14
.BI Status
Give some more or less useful information about the system.
.TP 14
.BI "Telnet <host> [<port>] [<string>] [d|s]"
Initiate a telnet session to a remote host using TCP/IP.
By default, the telnet command connects to the TCP port 23
(allocated for telnet). You can specify another TCP port or
a TCP port name.
.sp
If an optional third argument <string> is given, that string, followed
by a CRLF is sent to the remote host right after the connection is
established. This is mainly useful for command aliases.
.sp
If a single `s' is entered as the last parameter, then when
the remote host disconnects you will be returned to this node.
If a single `d' is entered as the last parameter, you will
be disconnected from this node too. Default behaviour (neither
`s' nor `d' entered) depends on sysop configuration.
.TP 14
.BI "TAlk <user> <message>"
Send a message to another user of the node. The user
in question must be in idle state (ie. not connected/connecting
anywhere or running a program).
.sp
If the user has an SSID other than zero, the SSID must be
specified. If multiple users are logged in with the same
callsign/SSID pair, those who are in idle state, get the message.
.TP 14
.BI Users
Show a list of users currently connected to the local node,
where the users are coming from, and what are they doing at the
moment.
.TP 14
.BI "ZConnect"
Initiate a compressed AX.25, NET/ROM or ROSE connection. The command
arguments are the same as in
.B "Connect"
command. Note that the other end must be expecting a compressed
connection (a LinuxNode started with the -c command line option).
No negotiation of compression is done.
.TP 14
.BI "ZTelnet"
Initiate a compressed telnet session. The command
arguments are the same as in
.B "Telnet"
command. Note that the other end must be expecting a compressed
connection (a LinuxNode started with the -c command line option).
No negotiation of compression is done.
.SH FILES
.LP
.TP 5
.B /etc/ax25/node.conf
LinuxNode configuration file.
.br
.TP 5
.B /etc/ax25/node.perms
LinuxNode permissions file.
.br
.TP 5
.B /etc/ax25/node.motd
LinuxNode message of the day file.
.br
.TP 5
.B /etc/ax25/node.info
The response to the 'info' command.
This file should be edited to reflect the local configuration.
.br
.TP 5
.B /var/ax25/node/loggedin
Database of current users.
.br
.TP 5
.B /var/ax25/mheard/mheard.dat
Information about AX.25 stations heard.
.br
.TP 5
.B /usr/lib/ax25/node/help/*.hlp
The online help files.
.SH "SEE ALSO"
.BR node.conf (5),
.BR node.perms (5),
.BR axports (5),
.BR ax25d (8),
.BR mheardd (8).
.SH AUTHOR
Tomi Manninen OH2BNS <tpmannin@cc.hut.fi>
.br
Alan Cox GW4PTS <gw4pts@gw4pts.ampr.org>
node-0.3.0/man/node.conf.5 100644 764 764 23653 6731777230 13071 0 ustar tpm tpm .TH NODE.CONF 5 "16 June 1999" Linux "Linux Programmer's Manual"
.SH NAME
node.conf \- LinuxNode configuration file.
.SH DESCRIPTION
.LP
.B Node.conf
file is read by LinuxNode at program startup and is used to modify the
behaviour of the node.
.LP
The lines within
.B node.conf
must either be a comment line, which starts with a # in the first column, or
one of the commands listed below. Commands and arguments are delimited
by white space. Arguments can contain white space if they are enclosed
in single or double quotes. C style character literals are not parsed and
parameter expansion (see below) is not done inside single quotes.
.sp
Available configuration commands are:
.TP 14
.B Alias <NAme> '<command> [<args...>]'
Sets up a command alias. The number of uppercase characters at the
beginning of <NAme> specifies how much the user may abbreviate the
command. The uppercase part should be long enough to separate the command
from other commands starting with the same letters. If there are no
uppercase letters in the beginning, the whole name is converted to upper
case and user can not abbreviate the command. Note that certain %-escapes
(positional parameters, current time) have a reasonable meaning only when
the alias is actually executed and thus they should not be parsed at the
time the configuration file is read. This can be achieved by enclosing
the command and argument part in single quotes. Another possibility is
to use double quotes and escape the percent sign with a backslash (eg. \\%1)
.TP 14
.B ConnTimeout <timeout>
When user is connected to another system via this system and the
connection is idle (no data flowing in either direction) for <timeout>
seconds the connection is dropped and user disconnected from node.
Default is 3600 seconds
(1 hour).
.TP 14
.B EscapeChar <escape string>
Specifies the escape character.
The escape string may be specified using any of the
well known codings:
.IP
.BI "<char>"
to enter the escape character in its binary form.
.IP
.BI "^C"
to enter the escape character as a control character value.
.IP
.BI "NNN"
to set the escape character to a Decimal value.
.IP
.BI "0xNN"
to set the escape character to a HexaDecimal value.
.IP
.BI "0NNN"
to set the escape character to an Octal value.
.IP
.BI "off"
to disable the escape character.
.sp
The default is CTRL-T (^T).
.sp
Note that the escape mechanism breaks 8-bit transparency of LinuxNode
and you should either disable it or set the no-escape flag in node.perms
for the forwarding stations if (compressed) forward is run trough
LinuxNode. Also the Escape user command can be used in a forward script
to disable the escape (see node(8)).
.TP 14
.B ExtCmd <NAme> <flags> <uid> <exec> <args...>
Sets up an external command.
.RS
.TP 10
.B NAme
This is the name under which the command appears at nodes command list.
The number of uppercase characters at the beginning of <NAme> specifies
how much the user may abbreviate the command.
The uppercase part should be long enough to separate the command
from other commands starting with the same letters. If there are no
uppercase letters in the beginning, the whole name is converted to upper
case and user can not abbreviate the command.
.TP 10
.B flags
This is a sum of flags that control the way the external
command is executed. Currently two flags are implemented:
.RS
.TP 5
.B 1
Run command through pipe. Without this flag node just fork()s and exec()s
the specified command and then waits for it to terminate. The command must
it self be aware about the underlying protocol. It must handle packetising
and any end of line conversions. With this flag however node sets up a pipe
between it self and the command and handles packetising and end of line
conversions for it.
.TP 5
.B 2
Reconnected to flag. If this flag is set, the user gets a reconnected to
prompt after the external command is finished.
.RE
.TP 10
.B uid
This is the userid that the following command should run under when
executing.
.TP 10
.B exec
This is the executable that should be executed.
.TP 10
.B args...
These are the optional arguments that are passed to the executable.
The first argument is the command name that is passed to the program
(argv[0]). It is usually the executable name without path.
See the Alias command for a discussion about the command arguments
and %-escapes (parameter expansion).
.RE
.TP 14
.B HiddenPorts <portname> ...
Marks the AX.25 port <portname> as hidden. Hidden ports are not shown
to users in
Links, Mheard, Ports and Routes commands and can not be used to make
AX.25 downlink connections unless user is specially permitted to do
so (see node.perms(5)). Up to 32 hidden ports can be specified with
this command.
.TP 14
.B HostName <hostname>
This is the visible hostname of the node. It will be shown at telnet
login and in the node welcome message.
.TP 14
.B IdleTimeout <timeout>
After <timeout> seconds of inactivity while waiting for a command user
is disconnected from node. Default is 900 seconds (15 mins).
.TP 14
.B LocalNet <network>
Defines a "local" network. Users telneting from hosts in this network
are treated separately (see node.perms(5)). <network> is a KA9Q NOS
style network address consisting of a dotted-quad IP address of the
network and a number of significant bits separated by a slash. Note
that 127.0.0.0/8 (loopback net) is also considered "local" by default.
.TP 14
.B LogLevel <loglevel>
Specifies what node should log. The available levels are:
.RS
.TP 5
.B 0
Don't log anything.
.TP 5
.B 1
Log only critical errors.
.TP 5
.B 2
Log errors and logins/logouts.
.TP 5
.B 3
Log errors, logins/logouts and all gateway commands.
.LP
Default is to log only critical errors.
.RE
.TP 14
.B NodeId <id>
This is the id that is shown in every message from node. Default
is "LinuxNode}".
.TP 14
.B NodePrompt <prompt>
Sets the prompt string. The prompt string is evaluated every time it is
printed so what was previously said about %-escapes (parameter expansion)
in Alias command is valid here also.
.TP 14
.B NrPort <portname>
This is the name of the netrom port that is used when making outgoing
netrom connects. Normally it should match the portname that is used
in ax25d.conf to listen for incoming netrom calls. Default is the first
netrom port.
.TP 14
.B ReConnect on|off
ReConnect flag. If enabled, users gatewaying to another host
get reconnected to this node after the remote host closes connection.
If it's off connection to the user will also be closed. User can
override the default behaviour with a single `s' or `d' at the end
of the gatewaying command (connect or telnet).
Default is off.
.TP 14
.B ResolveAddrs on|off
If enabled, dotted-quad IP addresses are resolved to symbolic names
when pinging or telneting out. Also, the domain name of the peer is
resolved for telnet logins.
Default is off.
.SH CHARACTER LITERALS
.LP
C style character literals are parsed when reading the configuration file.
The following formats are expanded:
.TP 14
\\n
This is substituted with Line Feed
.TP 14
\\t
This is substituted with Horizontal Tab
.TP 14
\\v
This is substituted with Vertical Tab
.TP 14
\\b
This is substituted with Backspace
.TP 14
\\r
This is substituted with Carriage Return
.TP 14
\\f
This is substituted with Form Feed
.TP 14
\\a
This is substituted with Alert (BELL)
.TP 14
\\\\
This is substituted with Backslash (\\)
.TP 14
\\"
This is substituted with double quote (")
.TP 14
\\'
This is substituted with single quote (')
.TP 14
\\xNN
This is substituted with the character corresponding to the code value
of NN interpreted as a hexadecimal number.
.TP 14
\\0NN
This is substituted with the character corresponding to the code value
of NN interpreted as an octal number.
.TP 14
\\0
This is substituted with the NUL character (ascii 0)
.SH PARAMETER EXPANSION
.LP
While reading the configuration file a word starting with a % is
expanded. The following formats are expanded:
.TP 14
.B %parameter
This is substituted with the value of
.B parameter
.
.TP 14
.B %{parameter}
The same as above.
.TP 14
.B %{parameter:default}
If
.B parameter
is defined this is susbtituted with the value of it. If not, the default
value is substituted. This currently applies only to positional parameters
0...9.
.LP
The following parameters are defined:
.LP
.TP 8
.B 0...9
The positional parameters. Positional parameters are not meaningful
while reading the node.conf so the default value (if present) is always
substituted.
.TP 8
.B F
The full hostname in upper case.
.TP 8
.B f
The full hostname in lower case.
.TP 8
.B H
The hostname in upper case.
.TP 8
.B h
The hostname in lower case.
.TP 8
.B I or i
Current time (HH:MM:SS).
.TP 8
.B N or n
The node ID as set with the NodeId command.
.TP 8
.B U
The username (callsign) of the remote station in upper case without the SSID.
.TP 8
.B u
The username (callsign) of the remote station in lower case without the SSID.
.TP 8
.B S
The username (callsign) of the remote station in upper case with the SSID.
.TP 8
.B s
The username (callsign) of the remote station in lower case with the SSID.
.TP 8
.B P
The nodename (callsign) of the remote station (NET/ROM), the portname the
user is coming in via (AX.25) or the ip address of the remote host (TCP).
In upper case without the SSID.
.TP 8
.B p
The nodename (callsign) of the remote station (NET/ROM), the portname the
user is coming in via (AX.25) or the ip address of the remote host (TCP).
In lower case without the SSID.
.TP 8
.B R
The nodename (callsign) of the remote station (NET/ROM), the portname the
user is coming in via (AX.25) or the ip address of the remote host (TCP).
In upper case with the SSID.
.TP 8
.B r
The nodename (callsign) of the remote station (NET/ROM), the portname the
user is coming in via (AX.25) or the ip address of the remote host (TCP).
In lower case with the SSID.
.TP 8
.B t
The type of the user connection (ax25, netrom, rose, inet, host) in lower case.
.TP 8
.B T
The type of the user connection (ax25, netrom, rose, inet, host) in upper case.
.LP
Anything else after a % is substituted with a %.
.SH FILES
.LP
/etc/ax25/node.conf
.SH "SEE ALSO"
.BR node (8),
.BR node.perms (5),
.BR axports (5),
.BR ax25 (4).
node-0.3.0/man/node.perms.5 100644 764 764 5260 6731773313 13242 0 ustar tpm tpm .TH NODE.PERMS 5 "16 June 1999" Linux "Linux Programmer's Manual"
.SH NAME
node.perms \- LinuxNode permissions file.
.SH DESCRIPTION
.LP
.B Node.perms
file is read at program startup with the knowledge of users username
(call), connection type (AX.25, NET/ROM, ROSE, TCP/IP), peers IP address
(for TCP/IP) and port name (for AX.25). The first entry matching this
information is taken and user is asked for password and given permissions
according to it.
.LP
The lines within
.B node.perms
must either be a comment line, which starts with a # in the first column, or
a permission entry in the following format, each field being delimited by
white space:
.sp
.RS
username type portname password permissions
.RE
.sp
The field descriptions are:
.sp
.TP 14
.B username
This is matched against users username (call) without SSID. An asterisk
(*) matches any username.
.TP 14
.B type
This is matched against the type of the connection to user.
Possible values for this field are:
.RS 14
.TP
.B *
matches any type of connection.
.TP
.B ax25
matches users coming in with AX.25.
.TP
.B netrom
matches users coming in with NET/ROM.
.TP
.B rose
matches users coming in with ROSE.
.TP
.B local
matches TCP/IP connections where users host is in "local" network
as defined in node.conf(5).
.TP
.B ampr
matches TCP/IP connections where users host is in amprnet (44.0.0.0/8).
.TP
.B inet
matches TCP/IP connections where users host is neither in "local"
network nor in amprnet.
.TP
.B host
matches users starting LinuxNode from
shell.
.RE
.TP 14
.B portname
If user is coming in with AX.25 this field is matched against the
local port name the user is coming in via. An asterisk (*) matches
any port name.
.TP 14
.B password
If the previous tree fields match and this field is not a single
asterisk (*) the user is asked for a password. The password is
then matched against this field.
.TP 14
.B permissions
This field represents a a bitmask of operations the user is permitted
to do. It is a sum of the values listed here:
.RS 14
.TP
.B 1
permits logging in even if no other permissions are given.
.TP
.B 2
permits outgoing AX.25 connects.
.TP
.B 4
permits outgoing NET/ROM connects.
.TP
.B 8
permits telneting to hosts in the "local" network as defined in
node.conf(5).
.TP
.B 16
permits telneting to hosts in amprnet.
.TP
.B 32
permits telneting to hosts neither in the "local" network nor in amprnet.
.TP
.B 64
permits using hidden ports in outgoing AX.25 connections.
(See HiddenPorts command in node.conf(5).)
.TP
.B 128
permits outgoing ROSE connects.
.TP
.B 256
The no-escape flag. Disables the escape mechanism for this user.
.RE
.SH FILES
.LP
/etc/ax25/node.perms
.SH "SEE ALSO"
.BR node (8),
.BR node.conf (5),
.BR axports (5),
.BR ax25 (4).
node-0.3.0/man/nodeusers.1 100644 764 764 1573 6731773510 13175 0 ustar tpm tpm .TH NODEUSERS 1 "16 June 1999" Linux "Linux Programmer's Manual"
.SH NAME
nodeusers \- LinuxNode user information lookup program
.SH SYNOPSIS
.B nodeusers [-a] [-i] [-l]
.SH DESCRIPTION
.LP
.B Nodeusers
displays information about current LinuxNode users.
.SH OPTIONS
.TP 10
.BI \-a
Tells nodeusers to use a plain <CR> as end-of-line. This is usefull
if nodeusers is called from ax25d.
.TP 10
.BI \-i
Tells nodeusers to use a <CR><LF> pair as end-of-line sequence and also
to wait for one line of input before sending the user data. This
should be used if nodeusers is used in an internet environment (eg. as
a fingerd replacement). The received line is ignored.
.TP 10
.BI \-l
Enables logging of errors to the system logging facility.
.SH FILES
.LP
.TP 5
.B /var/ax25/node/loggedin
Database of current users.
.SH "SEE ALSO"
.BR node (8)
.SH AUTHOR
Tomi Manninen OH2BNS <tpmannin@cc.hut.fi>
node-0.3.0/kernel_ax25.h 100644 764 764 11420 6713361556 12634 0 ustar tpm tpm /* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _NETAX25_AX25_H
#define _NETAX25_AX25_H 1
#include <features.h>
#include <bits/sockaddr.h>
/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx. */
#define SOL_AX25 257
/* AX.25 flags: */
#define AX25_WINDOW 1
#define AX25_T1 2
#define AX25_T2 5
#define AX25_T3 4
#define AX25_N2 3
#define AX25_BACKOFF 6
#define AX25_EXTSEQ 7
#define AX25_IDLE 9
#define AX25_PACLEN 10
#define AX25_IPMAXQUEUE 11
#define AX25_IAMDIGI 12
#define AX25_KILL 99
/* AX.25 socket ioctls: */
#define SIOCAX25GETUID (SIOCPROTOPRIVATE)
#define SIOCAX25ADDUID (SIOCPROTOPRIVATE+1)
#define SIOCAX25DELUID (SIOCPROTOPRIVATE+2)
#define SIOCAX25NOUID (SIOCPROTOPRIVATE+3)
#define SIOCAX25BPQADDR (SIOCPROTOPRIVATE+4)
#define SIOCAX25GETPARMS (SIOCPROTOPRIVATE+5)
#define SIOCAX25SETPARMS (SIOCPROTOPRIVATE+6)
#define SIOCAX25OPTRT (SIOCPROTOPRIVATE+7)
#define SIOCAX25CTLCON (SIOCPROTOPRIVATE+8)
#define SIOCAX25GETINFO (SIOCPROTOPRIVATE+9)
#define SIOCAX25ADDFWD (SIOCPROTOPRIVATE+10)
#define SIOCAX25DELFWD (SIOCPROTOPRIVATE+11)
/* unknown: */
#define AX25_NOUID_DEFAULT 0
#define AX25_NOUID_BLOCK 1
#define AX25_SET_RT_IPMODE 2
/* Digipeating flags: */
#define AX25_DIGI_INBAND 0x01 /* Allow digipeating within port */
#define AX25_DIGI_XBAND 0x02 /* Allow digipeating across ports */
/* Maximim number of digipeaters: */
#define AX25_MAX_DIGIS 8
typedef struct
{
char ax25_call[7]; /* 6 call + SSID (shifted ascii) */
}
ax25_address;
struct sockaddr_ax25
{
sa_family_t sax25_family;
ax25_address sax25_call;
int sax25_ndigis;
};
/*
* The sockaddr struct with the digipeater adresses:
*/
struct full_sockaddr_ax25
{
struct sockaddr_ax25 fsa_ax25;
ax25_address fsa_digipeater[AX25_MAX_DIGIS];
};
#define sax25_uid sax25_ndigis
struct ax25_routes_struct
{
ax25_address port_addr;
ax25_address dest_addr;
unsigned char digi_count;
ax25_address digi_addr[AX25_MAX_DIGIS];
};
/* The AX.25 ioctl structure: */
struct ax25_ctl_struct
{
ax25_address port_addr;
ax25_address source_addr;
ax25_address dest_addr;
unsigned int cmd;
unsigned long arg;
unsigned char digi_count;
ax25_address digi_addr[AX25_MAX_DIGIS];
};
struct ax25_info_struct
{
unsigned int n2, n2count;
unsigned int t1, t1timer;
unsigned int t2, t2timer;
unsigned int t3, t3timer;
unsigned int idle, idletimer;
unsigned int state;
unsigned int rcv_q, snd_q;
};
struct ax25_fwd_struct
{
ax25_address port_from;
ax25_address port_to;
};
/* AX.25 route structure: */
struct ax25_route_opt_struct
{
ax25_address port_addr;
ax25_address dest_addr;
int cmd;
int arg;
};
/* AX.25 BPQ stuff: */
struct ax25_bpqaddr_struct
{
char dev[16];
ax25_address addr;
};
/* Definitions for the AX.25 `values' fields: */
#define AX25_VALUES_IPDEFMODE 0 /* 'D'=DG 'V'=VC */
#define AX25_VALUES_AXDEFMODE 1 /* 8=Normal 128=Extended Seq Nos */
#define AX25_VALUES_NETROM 2 /* Allow NET/ROM - 0=No 1=Yes */
#define AX25_VALUES_TEXT 3 /* Allow PID=Text - 0=No 1=Yes */
#define AX25_VALUES_BACKOFF 4 /* 'E'=Exponential 'L'=Linear */
#define AX25_VALUES_CONMODE 5 /* Allow connected modes - 0=No 1=Yes */
#define AX25_VALUES_WINDOW 6 /* Default window size for standard AX.25 */
#define AX25_VALUES_EWINDOW 7 /* Default window size for extended AX.25 */
#define AX25_VALUES_T1 8 /* Default T1 timeout value */
#define AX25_VALUES_T2 9 /* Default T2 timeout value */
#define AX25_VALUES_T3 10 /* Default T3 timeout value */
#define AX25_VALUES_N2 11 /* Default N2 value */
#define AX25_VALUES_DIGI 12 /* Digipeat mode */
#define AX25_VALUES_IDLE 13 /* mode vc idle timer */
#define AX25_VALUES_PACLEN 14 /* AX.25 MTU */
#define AX25_VALUES_IPMAXQUEUE 15 /* Maximum number of buffers enqueued */
#define AX25_MAX_VALUES 20
struct ax25_parms_struct
{
ax25_address port_addr;
unsigned