Imported Upstream version 2.3.1

This commit is contained in:
Dave Hibberd 2015-09-03 20:01:45 +01:00
commit 4013fe89db
81 changed files with 10204 additions and 0 deletions

6
BBS.txt Normal file
View File

@ -0,0 +1,6 @@
Note in regards to PBBS forwarding:
If you do compressed forwarding with other PBBS systems, insure you flag
your connection so that you do NOT have ANSI turned on for that interface
AND that you disable the escape character. See: man uronode.perms
for the proper flags. This insures that compression will stay enabled
and that a compressed ctrl+t is not sent via compressed ascii codes.

929
CHANGES.1 Normal file
View File

@ -0,0 +1,929 @@
URONode bug fix and change notes:
30/4/1998 v0.3a:
Users with no permissions on AX25, NETROM, ROSE, TELNET outgoing connections,
can use alias commands that connect a remote node by AX25, NETROM, ROSE and
TELNET outgoing connections.
30/4/1998 v0.3b:
"!" command crashed on systems with no swap: CORRECTED!
Reconnected on Telnet sended two prompt-line: CORRECTED!
8/1/2000 v0.4-pre1:
Now compile and run under kernel 2.2.x, glibc6 and new ax25 and ax25io libs!
Added Gateway special tranfer mode.
18/2/2000 v0.4-pre2:
"Ports" command crashed on systems without listening sockets: CORRECTED!
Bad Pre-compiler directive order for systems without ROSE support: CORRECTED!
Now AWZNode have a better I/O flushing.
Other little code bugs resolved.
*Rewrites by Brian N1URO
**Note: this is being done on a debian linux server running kernel 2.4.20.
your milage may vary depending on the flavor of linux you're using. It
may be possible that with the exception of screen pushes, the AWZNode
could infact be working 100% fine, this I don't know.
5/4/2003 v0.5.2:
Renamed the project to AWZ-URONode.
Stripped out the recursing prompt to the end users.
Redesigned the output of the node to be similar to that of TheNet X1J type
nodes.
Added NodeId variable header of several command output lines, this is
totally configurable in /etc/ax25/node.conf under the "NodeId" option. I
suggest in keeping with the design of TheNet X1J to use a format similar
to: UROHUB:N1URO-2} (that's my personal preference hi!)
In flexd.c (line 310), changed i++ from (2) to (16) to ignore additional ctext.
If by chance you only get one packet burst worth of ctext or login.fpr
information, you may reduce (16) below to 8, or if yo uget 3 packets worth
of information you may go higher. In my case, I receive two packets of connect
texts from my FlexNet gateway node so I use 16 for myself. You will have to
experiment with this. You have been notified. Failure to adjust the parsing
code properly -will- result in any connect text strings as being falsely
parsed as bogus flexnet destinations and will maintain a sloppy list.
5/4/2003 v0.5.3:
With the amount of rewrites, I decided to rename the node to URONode.
Did more cosmetic cleanups and changed the node to look more like TheNet
type node. This also included some code cleanup and rewrites of some
minor routines.
Readded a node prompt as an option, however unlike the previous way
the prompt was programmed, if there was no prompt defined, a generic
AWZNode -> prompt displayed. If in /etc/ax25/node.conf the prompt
was left blank (aka: "") then a null line feed occurred. Now in
regards to the prompt, if no Prompt is defined in /etc/ax25/node.conf
a flexnet type prompt "=>" will display, or if you set the prompt in
/etc/ax25/node.conf to Prompt "", then the prompt will be defeated
and no additional lines of text (null or not) will be displayed.
*I found it VERY frustrating that when a sysop or a user with
shell permissions accessed the shell, upon return, there was
no notification that you were back into the node! Added a routine
that welcomed the user back to the node upon shell logout.
Repeated the above for the PMS gateway. I guess AWZ hardcoded in
a prompt for such notifications so I assume I am the one who
broke this hi!
6/4/2003 v0.5.4
Cleaned out some coded carriage returns which to me only adds junk to the
code (unless the intent was for this to ensure a local echo wasn't working
or something of that nature... ) at any rate, commented it out for now.
Tightned some more of the displays which also cleans up some code as well.
By now you may be wondering the madness behind my logic:
As I stated when I first started this project, my goal was to use the
existing AWZNode code and make it behave (oh austin powers behave!) as
much like a TheNet X1J node as I could, with enhancing upon the existing
tcp/ip and flexnet features this node has. Of course, code cleanup is part
of the process. One thing I noticed on both AWZ and Tomi's node programs
were the added strings both push such as the "Trying" messages when a
user requests a connect to another node, etc. Personally, and especially
on busy 1k2 baud links, i find it a bit irritating (as I'm sure end users
do also) that additional lag due to a null line-feed or the node telling
me what I asked it to is in process. In essance, this *should* make the
node appear to connect faster for the end user... I hope *grin*
Cleaned up the Sessions display... the net/rom sessions screen had an
allocation for Rtt when it's not in use. This also caused the Sendq
colum to appear grunged/misplaced.
There's still some line-feeds here n there I'm cleaning as I go to which
the subversion will increase hi!
6/4/2003 v0.5.5
Changed mailbox.c and system.c from looking at the users's environment
mail variable to point to /usr/bin/mail and /var/spool/mail/ respectively.
I noticed (on debian anyway) that the hardcoded paths failed mail to no
end. Doing more work on mail as I go along. Note: this only affects internet
based email! A seperate PBBS such as F6FBB is recommended for AX.25 mail.
Changed MSession command back to Sessions. I have no idea why this was done.
Deleted the Send command. It refuses to send no matter what I do anyway, so
to me it's useless. Also changed ! (STats) to STats to match Tomi's node.
Personally, I found this confusing between the two nodes. Added a Quit
hardcoded command to match both TheNet X1J and FlexNet style nodes.
Tweeked the way the Stats displayed. Memory shows not just 'memory' but
the definitions between swap and physical ram are displayed. Also AX.25
daemon socket stats are also a bit more defined.
Mail checking sometimes worked, other times didn't. Fixed the mailpoll
routines so that polling would keep displaying to the user that he/she
has new mail. This may irritate the user, but considering it's your
hard disk space that's storing their internet email, for them to be
on the node and simply choose *not* to read and/or delete mail from
your resources is just as rude to you (my train of thought anyway).
**NOTE: I can't stress enough on how dangerous (in regards to spam)
the mail feature can be! I **highly** suggest that you *only* give
access to those you know are hams! Needless to say, I would *not*
turn access for this feature on for global access!!! Not only would
you upset many people who are against receiving junk emails, but you
could risk losing any and all internet connectivity from your ISP as
some are *very* picky about spam mail that's relayed! Working for ISPs
in the past, I can verify this :-)
8/4/2003 v0.5.6
Still cleaning up some displays...this will be a task as I go along.
One thing I'm not positive about is whether or not on multiple port
usage how some diplays will read since I only have a single ax0 port
I'm using.
Fixed some routines in the do_finger command and added user usage
messages. In some cases, routines were forced so that if certain
strings (even null) weren't set after the finger command, it
was programmed to force the user to finger the localhost whether
or not that was their intentions. Personally, I found it better
to push a usage message of one line to the user than to go ahead
and process an errant finger request to the localhost. I did
force finger to require an @ within the command... since you're
fingering something"@"somewhere. This is displayed in the usage
message to the end user whether or not the input string after
the command is null.
Mail checking still seems buggy, and the bug seems somehow (so far)
to be linked with the mailbox.c routines. This is also where the
do_sendmessage command is. Fixed some routines in the send command
where if the To: or Subject fields comtained an UPPERCASE
character, it could cause the node to segfault out and leave
the ipcs open. This is bad! More on this in the Known Bugs section.
10/4/2003 v0.5.7
Whew! After much hassle...FIXED the former (and I mean former hi!)
SEnd command. While I was at it I also renamed it from Send to
MEssage. I thought Mail and MEssage were similar in function so
I decided to keep them together on the prompt as well.
11/4/2003 v0.5.8
Found a bug in the MEssage command *sigh* more on this below.
Moved the location of the help files from /usr/lib/ax25/node/help/
to /var/ax25/node/help/ so that all created node files are together.
Changed/fixed some of the help files to reflect changed commands, etc.
Cleaned up more diplay text. (since I'm more a code hacker than a true
coder, this is what I do best hi!.. but I learn as I go.)
Edited the man pages and changed them from a text to a compressed format.
Changed the configure script to grab the server's hostname. If your
server's hostname is already an *.ampr.org host, then you should be
fine with everything. If your server's hostname is a commercial domain
based name, then you will have to edit config.h and insert the proper
your.ampr.org hostname inside, or if you wish replied mail to be auto
redirected to a NOS based node, enter in your NOS' ampr.org hostname.
Added a warning message in the ./configure script to alert the sysop
to check their config.h file for proper paths, etc. I was going to force
a load of vi, but now-a-day most people don't use vi from my discussions
but another editor such as ae, joe, pico, etc. Since the sysop will be
editing their config files anyway, I feel the sysop can take a minute to
verify paths and variables. Please pay close attention to any and all
comments within this file!
Added Makefile.in which is a 'generic' Makefile. Makefile is now created
when you run the configure script. Also added some other environment
grabber functions to the configure script which adds to the proper files
that requires them for you.
Added removal of Makefile in the command 'make distclean'.
Removed local echo of "To:" field when using the MEssage command. That was
for debugging purposes anyway.
12/4/2003 v0.5.9
Fixed the bug that drove me nuts with the mail command. Now the mail
command will reject/refuse a parameter. One more down off of the
hitlist of bugs :-) It was suggested by N1UAN to make a configure
script toggle for the MEssage command too. I may do that in the future.
Fixed a bug in the POrts output. Since I only have one port, this was
hard for me to test. N1UAN has multiple ports and using his node I was
able to see and fix this bug before it made it to the buglist.
12/4/2003 v0.5.10
Woops, fixed a bug in the Info command where there wasn't a line
feed after the compile date. Reported by N1UAN. I also found a bug
in the display of: Node Call|Alias where lines were grunging. I
*think* I fixed this. Unfortunately this is the result of me only
having one port to work with hi! I happened to find this myself
using the copy N1UAN is running. Hopefully I fixed this bug.
More of a maintenance release than anything else. Fixed a few tweeks
here and there, nothing worthwhile to mention. The key thing in this
version was to make it more customizable for the hard-set commands.
This was suggested by N1UAN to which I kind of agree. It is possible that
one could have a linux box on an amateur radio packet network but not wish
to have it connected to the ampr.org or any other TCP/IP network. Coding in
these commands would then become a bit of a tease to the end user who may
wish to use URONode as a 'NOS' substitute for outbound telnet links, etc.
Now hardcoded commands will be toggled on/off depending on how you answer
the configure script. Answering NO to ALL questions will enable ONLY the
following hardcoded commands:
?, Bye, Escape, Help, Info, Quit, Status.
Answering YES to AX.25 enables:
Connect, Desti, Ports, Links, SEssions, Users.
Answering YES to Email enables:
MEssage.
Answering NO to FlexNet:
Disables the Desti command and will NOT compile or install the flexd
daemon...however if you have a destinations file that is valid that
will allow users to connect to digipeated paths without having to
manually type a 'via' statement in.
Answering YES to FlexNet enables:
Desti.
Answering YES to MHEARD enables:
MHeard.
Answering YES to NETROM enables:
Nodes, Routes.
Answering YES to ROSE enables:
Rose based protocol strings within ax.25
Answering YES to TCP/IP enables:
Finger, HOst, Ping, Telnet
Answering YES to TALK enables:
TAlk.
I may move the users to the default hardcoded commands..but for now my
thinking at 5:00am on a saturday morning is, if you're not going to run
ax.25, then you probably aren't as concerned who's in the node :-) Also
the use of the linux netstat command will show you who's on. The commands
I'm considering moving to the default are the ax.25 related commands...
since after all, if you're on RF, you'll -need- ax.25 right?
The Mail and SYsop commands are flagged on|off by the node.user file.
14/4/2003 v.0.5.11
Another change to the configure script. This time it checks your local
hostname and requests that you verify it. If you see it's correct,
just hit enter. If not, change it. Now... and this is tricky...
*if* you do NOT wish to have users RECEIVE mail on the node but have another
smtp based server such as a NOS node in which you wish your users to receive
smtp mail, then what I suggest you do is set hostname to the hostname of
THAT server. What this will do is send mail from the user with a 'return'
path of your NOS server. For example;
On my system I have an MFNOS node which users may send and receive SMTP
based mail. It has a hostname of "n1uro.ampr.org". While users may have
permission to SEND mail from URONode "dx.n1uro.ampr.org", I wish them to
only receive their mail at n1uro.ampr.org, so in this case I would tell
the configure script my hostname is: n1uro.ampr.org. It's sort of a way
you can allow mail with some sort of anti-third-party protection. Its not
perfect, but it helps. The configure script *will* prompt you for this
whether or not you enable the Email feature.
I added two neat commands. One is the new Version command. This is set
as part of the default hardcoded commands. All it does is shows the
version information of the node. This same data is also shown in the
Users command to keep the node in line with the display parameters of
TheNet/X1J style nodes (as I like). The other is what I call a Whowas
command. I got the idea from being on IRC, and borrowed code from
PE1RJA's node. With the W command, this will show you when a callsign
was last on the node, and how that user connected... ie: which port,
ip address, etc. If the user connected multiple times within the scope
of the log rotation then a columnized listing of that user's information
will be displayed. My happy news is that the SSID stripper from the
user's connection in sending email is fixed. One bug down!
15/4/2003 v0.5-R1
WooHOO! MHeard table read/write of digipeated MHeard routing is FIXED!
What I had to do was get argv to parse up to two digipeaters and then
print to the device each in reverse order. Now since my RF digipeater
gateway is a direct flexnet neighbor on axip, this was all I had to
test with, your milage may vary. If the digipeated path is not yet in
the mheard table, then it will fail. Another bug off of the list!
*whew* I knew I was close <G>. Also found some more screen writes
to tighten up. As far as I know, I'm going to (for now) close this
chapter of my life's efforts and make a release. I"m happy with how
URONode is performing and my alpha tester N1UAN appears to be just
as pleased :)
Found a bug in the output of the Who command when *
was entered. While this didn't seem to affect me on a debian system,
it did seem to act funky on a SuSe system. Flexd needs NOT be edited
now. Cleaned up some time variables in the MHeard routine and added
a column for the port heard, and the frame (pid) type. Since the
users can now see the pid types, they'll have a hint as to how their
connect request will be handled.
Found two bugs in the finger routine, both which appear to be in ALL
flavors of "*node". The first one I fixed, and that was quite simple.
When fingering information, the [address] or [hostname] was omitted.
I don't know if this was intentional, but I fixed it anyway to match
that of standard 'finger' displays. The second appears to be that
on a long RF hop, or a socket that's become broke due to routing
being cut, etc... there's *no* escape. For now, I've omitted the
Escape: CTRL-* display in all routines. It will still work for
telnet, netrom, and other types of connects. Since the Escape
command is a seperate command at the moment, I think it's fine
for users to check|set their Escape sequence. Hopefully I'll be
able to figure out a routine to escape from a 'stuck finger' :-)
Also tweeked the output of the HOst command.
*Welp, further research shows that there is no "escape" in the
native linux finger command... as there is none with the ftp command.
Needless to say, the better 'fix' was to simply disable all 'trying' state
messages. Personally I find them to be excess traffic that's not needed as
either the node will tell you that it's connected or it will tell you that
it failed. I know flexnet will tell you that it's trying a link setup and
xnet will take that a step further and show you which port the link is being
setup on. I may add the set escape sequence in the login screen as default
prior to users attempting connections so that it'll be easier on them to
know that there is a way to break a connect if needed.
16/4/2003 v0.5-R2
Ok, well I did decide to add the CTRL-* message as part of the
initial user login screen. Also made some minor tweeks to the
telnet login where now it shows more of a 'linux' style login.
Did some more screens cleanups and stripped out a lot of the debugs
I had commented out of the code. Ok..enough for now...I'm considering
this version 'done' unless bugs are reported. :)
22/08/2003 - Bug/security report
Morgan sm6tky publically posed a security report with some PoC listed but
not all. While I was able to duplicate what he did submit for PoC, I
wasn't able to find others. I'm very greatful to Morgan for bringing such
information to my attention, I'm surprised that his first step was to post
it in a public email list and list that I didn't reply when I wasn't even
given the chance to... however with that being said, I still took his
notations to heart and put the project a bit on the back-burner until I
had time to do the fixes. I also offered Morgan a chance to submit code
fixes to which he failed to do such. I don't claim to be a coder but just
a hobbiest in regards to C and always welcome patches as I have with htppu
with patches submitted by Thomas dl9sau who's also released his own flavor
entitled SAUPP. Version 0.6.x will be in process as I have the time to do
such.
v0.6.0 - never happened. Just made the directory structure and took an
initial peek at Morgan's reports.
12/7/2005 v0.6.1
Security issues fixed/removed. Rather than fix the talk command I decided
to just eliminate it in favor of an external conversd command. I figure
there's plenty of channels and lord knows there's actually more convers
servers now than users to use them... why not just use that?
Another security issue was mail. Instead of having mail routines built
into the node itself, I figure a node sysop can grab my updated axmail
node plugin and use that. I've done some basic security tests and it
seems to be a better way to go.
12/7/2005 v0.6.2
Just a beta version, never released while working on more security
fixes... I think I'm getting close now!
Changed some code in the do_help routine in command.c where Morgan
reported the possibility of a buffer overflow.
Changed some code in the syslog routine in util.c hopefully fixing the
formatstring vulnerability in that routine.
Changed some code in gateway.c in hopes of fixing the reported buffer
overflow.
Found what I thought to be an open hole in ipc.c, should be fixed and
with any luck the ipcs build-up issues will vanish with it. Only time
and your debug reports will tell.
Fixed a bug in Makefile where the man pages weren't installed due to the
fact I gzipped them and didn't change this in Makefile.
Changed the ftp url path, listed below.
v0.6.3 - some cosmetic tweeks I can't recall what they were.
04/07/2006 v0.6.4
Found a bug where if a user's permissions were flagged for "no escape"
such as a xNOS, F6FBB BBS, etc, that the node tried to display an Esc-?
as part of the prompt/screens. Removed the Esc-? from displaying. That
simply annoyed me and I'm surprised it wasn't reported... after all if
there's no escape why show "?" as one since "?" can be used as an escape
character with CTRL.
Added an Email flag in node.conf. Simply add:
Email <your@node.ampr.org>
on a blank line within node.conf for it to get pulled into the node. If you
don't "(null)" will display. It won't prevent the node from functioning but
will show users how lazy you are hi! This allows a sysop to deny all users
connection access _unless_ they have a password, while at the same time
allowing the node sysop a means of displaying a point of contact so that
users wishing to use their node and it requires a password can send a
communication to gain access. I strongly suggest for any account that has
sysop privs on the node that you force a password on _all_ connects and
that you only grant access via internet/amprnet to those who request a
password for security reasons if anything at all. Because I feel this is
security related, I'm making this a release.
Fixed a bug in the install routine for the man pages. The default
install for man pages was /usr/man, now it's /usr/share/man. I also
updated the manpage for node.conf.5 and re-gzipped it.
24/10/2006 v0.6.5
After a nudge from Stefano in Italy, I reintroduced a method in which one
user on the node can send a brief "msg" to another. The command once was
"talk" and still is on node (or if you prefer linuxnode that Tomi has
set the standard for!). For the sender, they get a full status report
as to what happened to their "msg" once the "enter" key is hit. For
the receiver, if they're truely idle on the node, the message will pop up
on them and the prompt will not return until they acknowledge receipt
of the msg by hitting the "enter" key. Also note that a system bell
will return on both sides, or just the sender's side *if* the msg
wasn't delivered. Since this acts sort of similar to today's Instant
Messaging world... I figure "what the hay they play noises too". I still
stand on the theory that if one wishes to engage in keyboard chat, they
should make direct TNC<>TNC connects or use convers but Stefano
made me rethink this and I can see how it could be used for one user
to "ping" another user with a msg saying "hey meet me on conv channel
32767 and see if we can wake the sleeping sysops!" :-) Originally this
was part of Morgan's security report filed back in 2003 (what? me
procrastinate? LOL) so with convers so easily available to URONode as
a plugin I felt it just as simple and quicker a fix just to remove
"talk". I renamed the command to "msg" since you're really just sending
a message and not really "talking" to the remote end.
Fixed the help files a bit to move talk.hlp to msg.hlp, and edited the
content of such to fit the re-introduced command.
26/10/2006 v1.0.0
First off, many thanks to Stefano and Alessio for their interest and
contributions to URONode. They've inspired me to help improve this
spinoff of AWZNode (which is a spinoff of FlexNode which is a
spinoff of node which is a spinoff of.... :-} ) Stefano asked me a while
back about putting in compression for Telnet and Connect commands.
Considering so many have broadband now on their wired links, I somewhat felt
this to be unnecessary, and here in the U.S. ax25 based transmissions are
supposed to be in plain text... so between those two major reasons I had
thought it best to just eliminate this feature a while back... not to
mention security issues with zlib that were going on. Since those have
been cleared and in respect to the motivation Stefano and Alessio have
given me with their interest in this project I thought it only nice that
I try and fullfill their desires as best as I can. Recieving compressed
requests into URONode was always there but not an outgoing client... so
I spent a few moments and coded one back into the front end. Needless
to say, ZTelnet and ZConnect (as with node) are in URONode now as
client gateway commands.
You need to set up another inetd/xinetd instance on an unused port
that calls "node -c" to enable receiving compressed connections via
telnet. Make a new alias/ssid for ax25/netrom if you wish to support
ZConnect client requests. Failure to do such will result in the remote
end getting an error message.
27/12/2007 v1.0.1
After a heated discussion with w0rli (as if that has never happened
on packet before, and him accusing me of knowing nothing about packet
or it's protocols) I decided to keep him happy while working on a system
that's linked to one of his. Hank feels that by having a login screen this
makes a node an application. While I can understand how he determines this
in his one-sided point of view, I still disagree with it but can appreciate
his concerns. Apparently he has never logged into a backbone router at an
ISP and seen a cisco MOTD file... or is a backbone core or border router
not a node on a network? :) In any event, I decided that I'd make the whole
login sequence of displaying the node version and /etc/ax25/node.motd file
an option to the node sysop upon running the ./configure script. Along
with not displaying a MOTD file, the default FlexNet style prompt of
"=>" will also not display. This will make URONode act more like
Hank's snos and like TheNet X1J-4 (with the "welcome" message flagged
off upon connect). Thanks are given to w0rli for this idea.
I also added a flag for the "NODE} Goodbye." string so that if you
do not have a MOTD displayed, it will also halt the display of the
node front-end saying bye to the user.
01/01/2008 v1.0.1a
I decided that I'd go through the code and search for more cases that
if MOTD is *not* defined, to ignore any and all reconnect flags, whether or not
they're defined for external plugins (ie: axMail) or alias commands in the
/etc/ax25/node.conf file. If during configure you decided to add MOTD during
the option questions, then the node will infact act more like a user
application including allowing reconnects etc.
I had thought I fixed the man pages install, appearantly I never saved it.
This should now be fixed. My apologies.
* Author's Note: If you're linking the node to systems such as SNOS, or
you're on a very busy network, or if you forward with other BBS systems
who for whatever reason feel the need to connect to your node first
before connecting to the BBS (which I feel is unneccessary but happens), I
strongly suggest that you do NOT enable the MOTD which is the default option
now in the configure script.
*** Important: I just don't have the time to clean up all the gcc-3.x
compiler warnings however URONode compiles just fine under gcc-2.95
so I made a decision to force gcc-2.95 for compiling URONode under.
Configure was rewritten to check for this, and if it doesn't it will
instruct you on where you can get a copy. This will not interfere with
your installed copy of gcc-3.x if you so have it. I have verified that
URONode compiles quite cleanly under gcc-2.95 and I do have both
versions on my box:
root@schlitz:/usr/bin# ls -al gcc
lrwxrwxrwx 1 root root 7 Jun 25 00:00 gcc -> gcc-3.3
root@schlitz:/usr/bin# ls -al gcc-*
-rwxr-x--- 1 root root 69960 Mar 10 2004 gcc-2.95
-rwxr-x--- 1 root root 85196 May 24 2005 gcc-3.3
As you see above, gcc by itself is just a symlink to the latest
version of gcc-*. Ensure that gcc-2.95 is in your executable
path.
23-24/01/2008 v1.0.2
Huge news! I finally got off my duff and cleaned up compile warnings.
URONode will now compile fine on gcc-4.1 and under! This was just something
that was under my craw for a very long time, but not that critical enough
so you can really ignore the above notes in regards to GCC.
I ended up also making some modifications to the configure script, Makefile
and config.h. Part of cleaning up some of the compile errors was a dupe
conflict between library "log" routines and the internal node "log" routine.
URONode now has it's own node_log() routine as to keep it seperate from
library log routines. There's no change in it writing to syslog for you,
just the function was renamed to avoid compiler warnings. Many files were
updated due to this.
**Man file for uronode is now called "uronode", not "node". The binary made now
is also "uronode".** This is *very* important because when you run
"make install" or "make installbin", your inetd.conf/xinetd files will need
to be changed to spawn the new binary, and your config within
/etc/ax25/ax25d.conf will also need to be changed from calling "node" to
call "uronode" now!! If you do NOT do this, you will be stuck running either
an older compile or it won't launch at all. Please see the examples in the
INSTALL file for help on how to configure this properly. In the future
I may change the config files from node.* to uronode.* too. The advantage
of doing this would be tri fold:
1) it'd allow sysops to compare and test URONode side by side with another
package such as Tomi's LinuxNode
2) sysops could offer both flavors of a "node" to users if they so desired
to do such.
3) a sysop might prefer to have 2 compiles of URONode... one with full
MOTD compiled in, one without.
Those who know me, know I believe in allowing a sysop to have the freedom
to pick and choose just how they run their nodes... and this just adds
to their options. I do however discourage doing this unless it's for
testing reasons but c'est la vie.
**** Actually, I figured why wait to change files around, so I changed
all the config files from "node.*" to "uronode.*". Now if you're doing
an UPGRADE, you'll need to rename your config files in /etc/ax25/node.*
to /etc/ax25/uronode.* or else you'll have issues with some routines.
I also deleted the *.ex files and changed installconf so that the proper
files get copied into /etc/ax25 for new installs. I also changed all the
man page files that were node.* to uronode.*
As much as it sorta kinda but not really pained me to do this, I decided
that it may be cool to have *something* to let the user know that their
outbound ax25-type connect is via flexnet, so I added a routine in
gateway.c which checks the connect type and if the request is via FlexNet,
the user will see the standard "link setup..." message like they would on
a flexnet node, followed by "*** connected to <desti>". This MAY have an
adverse affect on FBB forwarding since FBB looks for "Connected..." instead
of "*** connected...", but there's ways around that in your FBB forward
file.
25/01/2008 v1.0.3
*Big News*
For Debian and (K)ubuntu users, I've decided to make a release of
uronode as a .deb package. This is my first time doing this and I'm really
not that comfortable with rolling it out officially since it's my first
pre-packaged binary so here's what I suggest you do if you decide to use it:
cd /etc and tar cvf ax25/* ax25files.tar
dpkg -i /path/to/uronode*.deb
tar xvf ax25files.tar
For now this will preserve your current config as the .deb package *will*
overwrite your current files in full including configs!
YOU HAVE BEEN WARNED!
Found a bug in the WHO command when MOTD was disabled. Currently if you
don't define that, then the WHO command is deactivated and not compiled
in. MH works fine and should be enough to be used to track recent connects
to your node.
Discovered a bug in the newly introduced FlexNet style cosmetics where
after "link setup..." if the connect request times out, error isn't printed
on a new line. I wrote a new string to push to the user so that if their
request does time out, it matches that of FlexNet's timeout string while
leaving vanilla ax25 and netrom timeout errors the same. Again, these
strings will inform end users the type of outgoing request was made
whether it was FlexNet or vanilla ax25.
While I was add it, I decided it would be helpful to end users who are
making FlexNet links to show which ax25 interface is being used for
connects similar to that of how Xnet shows connect requests. The interface
will be displayed in parentheses () such as: Link setup (ax0)...
so if the link fails, the user can see which interface to try a direct ax25
connect request out from.
I think I fixed a slight bug in flexd.c where if the LO.FPR and C.FPR
weren't formatted just right, it'd exit prematurely and issue a false
error. Apparantly the buffer was set a bit too high and captured too much
to parse, so I lowered "buffer" from 1024 to 512 and it now appears to be
fine.
A "bug" was reported about the config of the backend of URONode when infact
the bug was with ax25d.conf and nrports. Remember, when you configure your
node, ALL your SSIDs for ax25, netrom ports, and axports *MUST BE UNIQUE* if
you have RF links to native netrom nodes. Failure to do such will result in
some flooding issues because if an ssid in axports, ax25d.conf and nrports
is shared, an X1J node connecting into URONode will result in the ax25 link
layer being seen as a user and not a network socket. You'll ping-pong
the node with X1J in almost an endless loop. *You have been warned!*
22/02/2008 v1.0.4
I decided to make the node text more "technically correct" in it's display
of things... mainly in regards to "ports". We don't have "ports" per say
but we do have "interfaces". Needless to say, any reference to "port(s)"
has been changed to "interface(s)" including the former Ports command. This
has been replaced with the new INTerfaces command.
Users now will show the "interface" a user may be coming in on if it's ax25
or if inbound from FlexNet.
The PIng command has been shortened to Ping now with the refactor of the
"Ports" command. Ping now only requires "P" to ping another node.
*Note: this will be the last release for a while as I'm moving and won't
have a server or test bed to test with.
10/05/2008 v1.0.5r1
The move has completed and of course in my own sick and twisted mind, I have
decided to do a release that I call version 1.0.5 release candidate 1. This
is a minor release but it's something I despirately wanted to do for a while
and was just sitting like an itch under my skin to do, and sometimes you have
to just take a break from it <all> to clear the noggin and get the code the
way you want it. What was bothering me was the fact that not one flavor of
a linux-node complies with that of the Software 2000, inc specifications of
Net/Rom... and I desired to be the first to do such... yay me?
In any event I went through the code and made changes to the following files:
command.c, config.c, extcmd.c, gateway.c, node.c, node.h, and system.c.
What this does for you is makes your URONode behave more to the specifications
of Net/Rom regardless of how you define the MOTD flag. If you define the MOTD
flag, the node will continue to behave as it has <all> along, however it forces
it in "off" mode when the incoming connection is Net/Rom based. This is
extremely useful if a robot script (such as FBB forwarding) is used to
go through your node.
The decision of making this a release candidate was because I'm sure I may
have missed testing some of it's behavior and will have to do some cosmetic
and/or bug fixes.. so if you find any, please report them to me and I'll do
what I can to fix it.
Source, .deb, and .rpm packages are available at the typical location of
ftp://ftp.uroweb.net/pub/ax25/ ...enjoy for now!
12/05/2008 v1.0.5r2
I had this really irritating bug that appearantly I just never noticed
all this time when HAVEMOTD was undefined. Thanks to some assistance from
K2MF, I was able to identify and fix this bug. Inside the main loop statement
for the node, when a user disconnected, it was adding an extra frame to
the stream that contained only a line feed. Looking back at this, I did this
due to the fact that X1J handles it's output to the terminal differently than
does any other node that I'm aware of.
In any event, taking out this line feed somewhat caused other outputs of
text to lack a line feed when it needed it... so this meant changes in
command.c, extcmd.c, gateway.c, ipc.c, node.c, system.c, user.c and maybe
more that I can't quite recall as of this writing.
The good news is that I did fix 2 minor bugs that were under my skin!
One minor bug was that when a nodes or destis list ended with a row of
4, an extra line-feed was displayed. While this bug still exists under
certain conditions, it's no longer present during netrom connects.
Also during a netrom disconnect, an extra line-feed no longer sends to
the remote node thus making it more Software 2000, inc. compliant. I'll fix
the previous mentioned bug for release 1.0.6 sometime.
21/05/08 v1.0.5r3
Fixed some screen cosmetics that I introduced while making the node more
Software2000 compliant... I'm sure I missed a few more.
***Big News***
I've finally tracked down and fixed the remote escape bug (I think)!
What I saw was happening was that the SIGPIPE handler wasn't being
executed properly and it appeared to be waiting for more data which
it never received. I added a quit_handler routine in the main loop
which now will execute a node_logout(), flush out the IPCs,
log the event to syslog, and close out the application properly.
Due to this bug lingering in all flavors of *node for linux, and not
having the resources to fully stress-test this, I'm going to leave this
as release candidate 3 for now until (hopefully not!) someone reports
that this routine is causing ill-behavior.
26/05/08 v1.0.5r4
There was a LOT of cosmetic changes in this one which caused me to add
a LOT of conditional calls into the code, many of which I'm unsure whether
or not it'll fly properly under every condition so your milage will definately
vary depending on your specific setup! Since URONode has become very popular
within the EastNet packet system I decided to make the node appear for both
the ax25/FlexNet side or its NetRom side, dependant on how the user logs into
the node. Because of the massive changes in structures, rather than listing
them <all>, the above description should do.
**Note: you MUST add a new line in uronode.conf that defines
FlexId XX#XX-##
Either take yourcall-ssid from ax25d.conf OR if you're linked to a
node that does flexnet, use yourcall-ssid as it is on the remote flexnet
system. If you don't, and a user connects in via telnet or ax25/flex you'll
display (null) to them. Also: if you added a } after your NodeId
callsign-ssid, remove it. It's been hardcoded into URONode now.
I decided to mute the banner section of the login sequence however
it will still display your MOTD if it's defined during ./configure.
If there's a demand for it, I may add it as a configurable option.
Even though I put r4 out for download, I did find a couple minor bugs
which have since been fixed.
29/05/08 v1.0.5r5
In a nutshell, if the user connects to your URONode via NetRom, then
they will get standard NetRom prompts with "ALIAS:CALL-#} " as a result
header to all of your commands with the exception of FlexNet gateway
connects.
Now in uronode.conf, a *new* line _must_ be added for FlexId. The parameter
is:
FlexId <call-flexssid>
An example since my URONode is on FlexNet as ssid 3:
FlexId N1URO-3
Also note that the need to have a closed bracket "}" after your NodeId
now is not required and should be deleted. I finally got off my butt and
hard-coded it into the software.
The Version routine was also changed depending on how the user is connected
in. If the incoming connect is made using NetRom, then the standard prompt
is displayed. If the incoming connect is via any other type of link, then
a columnized display is made showing Software version, NodeId, and FlexId
in hopes of eliminating confusion to the end user.
While in the midst of all the above, I did find some cosmetics to fix.
Before I make this release candidate an official, I'm curious as to
whether or not anyone would object to me eliminating some of the
standards of the login banner of the node (non-NetRom displayed).
Please let me know and I'll make the necessary changes if need be.
-- actually I already decided to do this.
I added a new routine in util.c which now will give the end user
the type of prompt based upon the type of connection. The default
for ax25/FlexNet is: "=> " (note the space after > unlike Flex)
for NetRom is: "ALIAS:CALL-ID} "
for tcp/ip is: "usercall@hostname:/uronode$ "
With the new routine, I changed the main loop in node.c from defaulting to
Prompt simply to using node_prompt().
01/06/08 v 1.0.5
URONode version 1.0.5 is now considered to be "final". With the new month
is a new final release, and in this release it has more face-lifts than
Joan Rivers hihi!
I added a new routine in the configure script which will prompt you for
telnet colored routines... yes we have ANSI! Now, a couple things about
pushing ANSI code:
1 - consider network bandwidth if you have IP users via RF
2 - many windows apps such as WinPack do NOT support ansi. This is NOT
a fault of URONode, but that of the Windows application. If you
find you have trouble decoding ansi, try PuTTY or use HyperTerminal
in telnet mode. Ansi is hard disabled for ax25/Flex and NetRom connects.
I also added ansi codes for "Nodes" and for "Desti" lists commands if the
inbound connect is made via IP.
Added an "EXit" command for users in IP mode since you now feel like you're
in a bash shell... just a 'force of habit' thing. Bye still works.
Fixed a bug introduced with the new node_prompt changes to node.c. If
the user was required to enter a password outside of being on the localhost
or amprnet, the prompt displayed twice... this is now fixed. I also found
and fixed soem more cosmetics that I considered to be wrong. This bug was
driving me insane as to why it was doing this, but I finally tracked it
down.
Found and fixed another bug where if the user's permissions were set
to a perm "escape off", prompts didn't properly function.
Made a change to nodeusers where now if no one is on the node, it'll
say such instead of simply being blank.
A note about ansi:
linux shells will decode ansi pretty good as will old DOS based terminal
programs such as Qmodem, Telix, etc. If you use a raw terminal such as
xNOS, you'll need to insure you load ANSI.SYS in your C:\CONFIG.SYS file
and reboot so the terminal will decode ansi.
Windows telnet *will* decode ansi as well however since XP, local echoing
by default is set to OFF. You can CTRL-] and type: set localecho, then hit
enter twice and you can get echoing back on.
If you use something such as WinPack which doesn't decode ANSI, please do
NOT contact me! Contact the authors of WinPack and report the lack of
ansi as a bug.
I also am including a copy of axdigi from the original FlexNode package.
This is compiled as a static binary and a copy of axdigi.conf IS
also included in the source package, but I won't package it with the .deb
or .rpm packages... however I do reserve the right to change my mind :)
Static binary packages are compiled with the following options OFF:
Rose support
All other options are compiled in.
04/07/2008 v1.0.6
Found and fixed a bug in the Who routine where a netrom prompt was merging
with the last entry of a list even if the connect was not netrom. This change
was made in system.c.
Added some more ansi routines if #defined COLOR. Here's the schema:
Connects display in green as in "gateway go"
Reconnects display in red as in "gateway stop"
Commands display in bright white
Netrom Nodes (full list) in bold cyan
FlexNet destis (full list) in yellow
Current users in magenta
Aborts and timeouts blink bright red
Logouts in low cyan
I'm making the color schema a bit more consistant through out the application.
While doing such, I'm cleaning things up so that just the headers are in
color, not the actual results so that if one is NOT decoding in ansi (and
again if not that's a fault of the client NOT of the node) the node won't
appear as offensive.
Found a bug in the auto router where it wasn't parsing the digi path
from the mheard table, HUGE credit goes to Barry K2MF (of MFNOS fame) for
supplying the code that properly handles this. Fixed.
Did a lot of clean-up for how the node/shell responds dependant on how the
user connects in. Many changes done in gateway.c, extcmd.c and node.c.
Now made ANSI a flag in uronode.perm... I may change this later however
because of such, it forced me to have to make a new nuser_list routine
in command.c as well as move node_prompt from util.c elsewhere so
command.c seemed like the best choice. Setting the user bit +512 will
now grant them telnet ANSI color. Not giving them this will turn
it off. I'd like to make it an end-user toggle so that depending on
which client the user is coming in with they can choose online to get
color or not. The user perm flag replaces defining Color during the
configure script.
Defining MOTD now serves multiple functions:
1) Display of the MOTD screen/file
2) Display of prompts for all interfaces
3) Reconnect back to the node upon a gateway link out
I suggest compiling with MOTD on, which configured by default in the
.deb and .rpm packages.
Changed some of the technical correctness of the node in regards to IP
functions. Ping now returns ICMP Echo request/reply messages and IP based
connects out now show the service/port that the connection request is being
opened to.
Added color schemas to the NetRom and ax25/Flex interfaces if the user
requests it to be on. The same color schema is used on all 3 interfaces.
Fixed a very irritating bug that some folks have reported on which
when do_ports() was called, and the axport description was over 42
characters in length, do_ports() was *not* properly truncating the
additional characters, and making things looks a bit sloppy. A similar
bug exists in LinuxNode =< 0.3.2. Note: In your axports file, you *MUST*
have a tab after the window digit before writing your interface
description or else the parser will consider the spaces as just that...
empty spaces! You have been WARNED!
Updated uronode.conf and uronode.perms files to show examples of recently
added features.
Long overdue: Updated the MAN pages!! I'm so sorry for letting these slide!
It really is hard enough trying to keep track of things in this file, never
mind actually documenting it in a manual page or two hihi!
Found and fixed a bug in the logout routine where a false error was being
reported that the shared memory segment (IPC) couldn't close. Somehow this
was introduced by me duping the lines in the routines so that it was actually
trying to close the shared memory segment twice! I guess in reality, the
log error was indeed correct since there was no second segment to close hi!
Added a "make update" option to the Makefile. This option *must* be used
in version release sequential order or else it may fail!
Fixed a cosmetic bug in the way NetRom nodes introduced by me when I created
multiple interfaces. The word "NetRom" appeared twice in the header when
a user would request a Nodes list.
15/11/2008 v1.0.7
Made some cosmetic changes to text and ansi color displays, still a few
more to do but not critical so it gives me an excuse to do a maintenance
release one of these days hihi!
With the assistance of the great and mighty <all>, the <all> of c coding
knowledge, I was able to incorporate a loop detection system when making
FlexNet or ax25 connects... now if there's a loop in the outbound connect
request, the user will be informed of such which includes a system bell
(beep). I thought about adding a loop connect block such as with FlexNet
however in the case of axip/axudp links many links may share the same
interface which really would be unfair to the user trying to gateway out
that's also coming in from the same axip interface.
Now for the big news of this release: By request of Bob Anderson K2BJG,
I wrote a kluge for flexd.c which now requires 2 additional fields in
/etc/ax25/flexd.conf - MyGate and MyRange. Inside flexd.conf, MyGate
is your neighbor FlexNet gateway without ssid, and MyRange would be
the full ssid range of the FlexNet gateway you poll. This will add your
FlexNet gateway into your local desti table complete with SSID range and
give it a ttl of 0 since there's no true ttl polling going on... but there
is a catch to this: you MUST add each ssid of the remote FlexNet system
into uronode.routes as a direct link or else connect requests will fail
because the connect will try to digi off of the remote FlexNet system
to itself. I don't know if I agree with this yet or not as a local
FlexNet system never shows itself in it's desti table, and that's what
K2BJG has asked me to do with URONode. As I said, for now this is all
a kluge but it does appear to work if instructions are followed
verbatim.
Examples:
MyGate N1URO
MyRange 1-11
Made a change in the Makefile so that the axdigi module does NOT copy over
by default. Now you MUST do this manually and add it to your scripts. Not
everyone would wish to use this so why force more junk in a directory? :)
--------------------------------------------------------------------------
See CHANGES.2 for more notes in regards to changes.

637
CHANGES.2 Normal file
View File

@ -0,0 +1,637 @@
28/11/2008 v1.0.8
*notes lost, sorry.
27/05/2009 v1.0.9
**production copy stolen. See LICENSE for who did this and my response.
11/05/2013 v2.0
Clean up of some code... I had a copy of 1.0.8 from 2008 I recovered. I
did
have a version 1.0.9 in production but can't seem to locate it for some
reason so starting from memory using 1.0.8. Thanks to Brett WA7V for
supplying me with some teaser code :-)
Updated version! We're on 2.0... finally! (yea, big news right? Maybe
not!)
Moved the "Who" commmand to the list of basic internal node commands.
I can't recall why on earth I had it defined with MOTD. Perhaps it may
come to me later but for now I can't recall. I may have to move it
somewhere else, but I believe it has to do something with logging
features or something along those lines. For now, you need to define
MOTD as a compile selective to have the <Who (call)> defined.
Fixed the sysop shell warning, this needed to be a tad more specific
in my point of view... then again who am I? Also cleaned up the return
prompt as it could be confusing if the incoming connection was done via
NetRom. I removed the default FlexNet Identifier out. Now it just says:
"Welcome back.".
In regards to the "Who" command; I see what was going on here and where
I left off with it! Logging and the "Who" command pretty much go hand in
hand - so they're combined. The initial design of FlexNode was to have a
MOTD based off of the logging of when the user last was on, otherwise if
they did not exist, push the "new user" screen to them. The down and
dirty quick fix is to simply remove it from netrom connections into the
system! Who cares if you get a MOTD on a flex/ax25 or a telnet connect
into the system!
With the above said, I changed the sequence of "configure" to ask if the
sysop/admin wishes to log user connects into the system. In the future I
will either move this to be included with protocols or I may simply hard
code it in as a defaulted option, and move the "Who" command as being
defined into TCP/IP functions. For now, it's hard coded in as a selected
option but will NOT display for NetRom connects.
While I was at it, I changed some of the routines in the configure script.
Nothing major but did improve upon a few things. While doing this, and
running "make upgrade" I noticed that flexd.conf was being overwritten!
OUCH! I'm surprised this went on for as long as it did. I *think* I did
this to force people to add the new lines in flexd.conf that K2BJG/SK had
asked me to do.
Created a man page for flexd.conf(5)! I'm surprised no one asked me why this
was missing! It explains further how to create the file. Keep in mind, this
also works on Xnet as well as Flexnet. If this doesn't help you figure out
how to create this file or edit the sample one... I don't honestly know what
to tell you. In doing such, it also forced me to change the generated
Makefile so that "install upgrade" and "install man" installs it.
Changed the licensing! This is (I'll admit) very personal and _must_
remain as is! I could fill a TB hard disk with reasons and debates
as to why it's no longer GPL code. Please insure you are in an area
where you can use this code. Thank you.
Fixed an ANSI bug I had in the "Users" command which was driving me nuts!
On NetRom, it would change the prompt to magenta which it shouldn't. What
I did as a fix was to force a removal of ANSI on the prompt for NetRom
based connects... simple enough. There may be other ANSIs for me to fix
and I'll cross those bridges when I get to them. Found another in gateway.c
and fixed the netrom ANSI to properly reflect that once a connection was
made, it was "systems GO" (green) without changing the Node's ID string.
Created a COLORS file which somewhat explains the hows/whys of not only
how I came up with a schema, but when it should and should NOT be used.
It may also be used as a quick reference guide for the local sysop. It's
a nice little cheat sheet one may print and keep near their keyboard if
they want.
Added text to both the colors.hlp and help.hlp file for a users better
understanding of the color schema and how to gain colors to their terminal
if they so choose to have it. See my wishlist below for more information on
where I wish to go with this.
Added an item to the Wish List located further below in this file. With so
many spend-thrifty hams, do I really need to go through the code and match
it with the most up-to-date version(s) of GCC for compiling? I originally
developed the code using GCC version 2.95, now I'm compiling it on version
4.2.4 and it's not showing any errors during compile. If you have a specific
version of GCC you're using, please submit that and proper hardware for me
to run it on and I'll be more than happy to march forward :-)
Changed the inactivity timeout message so that it does NOT show
the FlexNet node call and gives a more specific message as to why the user
was disconnected. This was a call I originally edited and have now cleaned
up in node.c. There may be more of such messages. I can only test so much
and for so long :)
Made some more ANSI cleanups - in regards to Status and Users commands. I
had them as magenta and they should only be bright white as they don't
fit into any real category except for local system informations. For these
I had to make routine changes as well as ANSI changes in user.c and in
command.c. Also fixed the ANSI for version in NetRom. It currently had none.
This was done in command.c. Also cleaned up Links and Routes ANSI in command.c
and other places where needed. Originally I had the Routes as yellow which
even though it points the ax25-interface that NetRom is encapsulated under,
it's really more for NetRom "route"-ing... so changed it to cyan to keep with
the schema.
Found a disaster in ANSI routines for the Links command and the variant
switches along with it! The ANSI ran to the table which I did not want
to have happen and I believe I was very diligent in cleaning this up
in ver 1.0.8 or 1.0.9. In any event, I recall doing this and now I have
repeated my work... thus taken time away from more important tasks
*sigh*.
These were worked in router.c. I also cleaned up other places where ANSI
ran over other strings that it shouldn't, and where it may have engaged
prior to where it should. Such instances are when it would highlight over
the Node-ID string (ex: MYNODE:mycall-5}). This really made my skin crawl
and I *know* I fixed this before... who knows perhaps I made a cleaner
routine than I had.
I recall doing a LOT of code clean-up, and it appears I need to revisit this
again. When I'm done, hopefully I can get rid of a few hundred lines of code
that's simply commented out for testing purposes only. The sizes of your
binaries should not be affected by this and I believe I've been diligent
to clean up the configure script to somewhat automate this process for you.
This task will be excessively time consuming! If anything it'd be an excuse
for a maintenance release!
Fixed a minor routine in ipc.c in regards to the Msg command. I deliberately
did NOT add ANSI to this because in a way the Msg command I feel is a tad
intrusive such as with an instant message, however I did clean up how an
incoming message was handled to the recipient. It now (in my opinion)
shows a cleaner screen.
I found Craig Small's old axdigi code and made an elf compile. In layman's
terms, it's a static binary and should run as-is for you. This binary
claims to be fully automagic in regards to crossport digipeating unless you
make changes to your interfaces in which you should restart it. This binary
also should NOT require /etc/ax25/axdigi.conf anymore. I have the other
binary so if you think you need it, let me know.
Added an install for axdigi in Makefile.in under "install bin". Previously
this file was not included, now it is. I may write a shell script to launch
the daemons for you... keep an eye on this file for further info!
26/05/2013 v2.1
Fixed a bug in gateway.c where the finger "stop" ansi was white instead
of red (for stop). This was one I missed not having proper routing yet
to fully test. Thanks Brett WA7V for the link!!
Made another change in gateway.c in regards to the handling of the
flexnet destinations listing when using Flex/AX25 ONLY. There is a
reason for this (believe it or not) and that's in the shell and netrom
interfaces they both begin the destinations list with the string
"Flexnet Destinations:". This may cause neighbor URONode/AWZNode/etc
systems using flexd to improperly parse flexnet destinations from each
other. At the moment, I don't have the facilities to properly test this
but am hoping to work something out.
Thanks to Bob K2JJT, I added an include for socket.h in ipc.c. While I
never saw any errors here, I don't believe I've ever tested or compiled
on a Slackware system... Bob uses Slack. K2JJT reported adding this to
ipc.c helped him fix issues with his compile as it was griping about
AF_NETROM. Adding it here made no difference so since it helps Slackware
I'm all for being multi-distro compatable as much as humanly possible.
In reviewing 2.0 changes, it had me look more into the shell function
for sysops. I made a change that more defines which shell you may be
in when you do a 'w' or a 'who' in a linux shell via the node. This
was changed in system.c
Made a patch to node.c where if called from a shell, it would coredump.
Now, if it's called from a shell it simply exits back to the shell
prompt. I believe the same is in other "node" variants to which
the documentation directs the local sysop not to call the node from
a prompt, however KI6ZHD felt this was an issue. Being harmless in
nature to the function of my design I felt it wasn't harmful to add
it in. This patch was provided by David Ranch KI6ZHD. Thanks to him
for providing this, and eliminating any accidental core files on your
hard drives, and to Steven, K6SPI for coding the patch.
Thanks to David KI6ZHD for motivating me to do something I wanted to do
but put it way on the back burner, and to Barry K2MF for his elite C
skills. MHeard now will only print up to the 20 most recent heards. With
the initial routine, it would just dump either the global list heard
or if the user selected a specific interface the entire list for that
interface. At first, it worked fine for telnet and/or ax25/flex
connections but in NetRom it was double spacing. This was fixed by me. I
chose 20 to leave room for system headers and prompt returns. In a
standard 80x25 terminal screen, with a full listing, this should fill
the entire screen without a need for the end user to scroll up and
should help keep some traffic down on a busy network.
Made a change in gateway.c to eliminate the "trying state" message only
in NetRom when trying to connect to a remote NetRom node. This should
keep the node more in compliance with Software2000 specifications.
There was chatter within the BPQ32 user group on Yahoo that URONode was
not releasing any keep-alive timers. Please, this is NOT the duty of
a node Front End to control what the native protocol stack is designed
to do. This is totally sysop configurable. To flag this I strongly
suggest the following be added to your scripts:
echo "600000" > /proc/sys/net/ax25/ax0/idle_timeout
echo "600000" > /proc/sys/net/ax25/ax1/idle_timeout
echo "600000" > /proc/sys/net/ax25/ax2/idle_timeout
and so on... one line for each ax25 interface. This will break the
keep-alive virtual circuit Netrom AND IP will use for transport, and
thus break your IP as well. If you're running IP through an ax25
interface I suggest you leave this defaulted to 0 (disabled).
Rewrote the auto-find routine in gateway.c in do_connect so that first
order of preference for connects searches the destis table from flexd
BEFORE checking the netrom nodes and mheard tables, THEN it will search
for the destination in the netrom nodes if not found in the destis
table and prior to searching the mheard list. If you don't use flexnet,
then this shouldn't be an issue for you. As of this time, I'm unsure
if this would create any bugs if you don't define FlexNet during
the configure procedure. If it does, please file a report on the
online forum at https://www.n1uro.net/forum for me!
Made some changes in util.c and gateway.c in regards to duplicate ax25
route connection attempts. If you attempt to connect twice through the
same path, same call, etc, to clarify the error handling. This was
something I worked with K2MF on in regards to MFNOS. This does not mean
you can't make a connect on the same interface you came in on, you will
get a loop warning but the connect will attempt. If you connect from
the node, and try to connect to <callsign>, loop back into the node,
and try to connect to the same <callsign> again, you will NOT be allowed
to connect. URONode will tell you that a duplicate connection is not
allowed.
Cleaned up the do_routes routine in command.c. Shortened "Quality" to
"Qual" and renamed "Destinations" to "Nodes". After all, netrom doesn't
really use "Destinations", that's more a flexnet thing. Still more
cleanup to do in there *sigh*.
While I was at the do_routes, I noticed missing ansi in do_routes and
do_nodes. This has been fixed (and was previously in 1.0.10). I also
cleaned up the ansi routine in do_destinations in router.c to match
that of the netrom counterpart routines in command.c. Again, this was
done in 1.0.10 *double sigh*.
Rather than include an i686 elf of Craig Small's axdigi cross-port
digipeater which probably would NOT work on a Raspberry PI, I added
it into the Makefile by default. I also added an additional routine
in the configure script to check to insure that this file is made.
I also had to update axdigi.c so that it wouldn't error on the newer
(as if I run newer ha!) gcc. This was done for strcpy so that it
wouldn't produce errors as it does. I suspect in the "OLD" days of
linux/gcc it may have been OK as I consider Craig to be one of the
"village elders" of the packet system on linux.
Added a man page for axdigi. READ THIS VERY CAREFULLY!! To digi through
linux you *must* know some specific information and you might have to
educate your users on how exactly to cross-port digi through you if
they intend to do such. It's not something normally visible to them!
I may add a node-help file on digi...but for now please study the man
page on how. It works and works very slick as I've been testing it for
a couple of months. Mheard also will learn digi paths and use them to
connect to digipeated nodes if need be.
Cleaned up do_nodes in command.c. Shortened Quality to Qual, and the
equivilant of Obs. This will use less chars per line when doing a
node <node> or node * . I've been wanting to do this but saved
it for one of those rainy day things. Guess today was that rainy day?
Cleaned up more code and hope to have it finished before 2.1's final
release. So far I'm doing flexd.c at this point. FYI; code cleanup will
be a 2-fold process. First; I'll be formatting each file so it's at a
level of consistency. Second, things I have commented out for testing
that aren't needed may be permanently removed. I may leave a few things
in in case someone desires to say add a 'Welcome." message to netrom
(which is NOT Software2000 compliant!).
Speaking of which, I see I introduced a bug when ANSI is defined for
a specific user which violates Software2000 specs. I believe I did this
as a fail-safe in the prompt routine however now I see it's not needed
with all the other ANSI cleanups I've done. This change (deletion)
was done in node.c where I forced a shutoff of ANSI upon NetRom connects
only, as NetRom does not display the MOTD.
I rewrote a bit of the reconnect string. The "reconnect" in uronode.conf
should be set to OFF. All connections with the exception of NetRom WILL
reconnect. NetRom defaults to off, however with the {S|D} flags you may
manually request you stay connected. Eventually I will remove this flag
in the file so it will become moot. Please change it now to OFF! This
was done in gateway.c. Previously, these flags were moot in NetRom
connects. With the default to OFF, this keeps the NetRom in URONode
Software2000 compliant. A NetRom disconnect should *never* send any
text back whether it's a user or robot/script. Now a user can request
staying connected to URONode from a incoming NetRom connection. For
clarity sake, this only affects the user IF they connect INTO URONode
via NetRom. The "S" flag works for ax25/Flex/NetRom outbound connects.
A user connecting INTO URONode via ax25/Flex/IP will still automatically
be reconnected after an outbound connect.
N1UAN reports make install fails to install the config files. He's
correct. Changed Makefile.in so that "make install" also includes
make installconf which run by itself will install just the config
files for /etc/ax25.
I'm also working on changing the configure script to have some
"eye candy". This will be a continuing work in progress. You'll see it
as it comes. You will need the package "whiptail" in order to see this
new configuration routine. I don't know if this is standard amongst
ALL distributions, however I do know it comes default in debian and
debian based systems. If this *is* too much of an issue, I'll revert
back to the old method.
Almost forgot about an ANSI bug in extcmd.c where if you created an
external command in the node and the user was in via NetRom, when the
node issued "Welcome back." the ansi did NOT clear the color. I found
this in ver 2.0 and thought I fixed it, apparently not (age catching
up to me?) In any event, this is now fixed and working properly again.
Since most people don't use the +512 Color flags I'm sure it was missed.
Found a non-critical bug in cmdparse.s in regards to running external
commands - where it would automatically input a line feed before it
executed the command. This was the only routine which did this. A
routine like this really got under my skin and I was determined to find
and fix this finally... this was a routine I never changed, and that
was halted today (28 July 2013). Instead of totally removing this line
of code, I changed it to now display "Executing command... " and where
ANSI is defined, it is, naturally, green.
Found a non-critical bug in the Info command where it would show as
the first string to the user: "Help command for help" then it would push
the uronode.info file. This is very wrong. While the Info command does
use the routine of do_help in command.c, Info is an independent internal
command and this should not have occurred. This is now fixed with ANSI
if permissions display ANSI.
Updated the outdated INSTALL text document. It had some now misleading
pieces of information in it as some paths and make options have been
changed. Since no one has said anything to this, I'll assume no one
RTFM? (not surprised! email me and say in the subject line: surprise!
if you do!)
Went through the example config files and heavily commented them so for
new installs, it explains each line more specifically in hopes less
misconfigured systems will be created. I also found some typos as to
man page references - fixed. Also updated some of the help files in
regards to the new changes in relation to the "stay" sub command when
connecting out from URONode.
Note: in node.c I modified the pre-provided segfault patch to now
push text to the local console instructing the local sysop or user
what/how to properly execute the node. This will (I hope) force
some RTFM to occur. Syslog logging was also added in the event this
occurs. Actually, after thinking about this, I figured I'd dummy it up
a bit and have it launch a login anyway. This depends that the local
administrator/sysop -properly configures their box- and does the
following:
1 - add a line in /etc/services to point tcp/3694 to uronode
2 - add uronode as a service in inetd or xinetd
3 - insure you have a local telnet client on the box
4 - enjoy!
You will be reminded about this during the login, and syslog will
reflect a local console login as well.I strongly urge you not to open
2 shells and tail your syslog in one while you try to run URONode from
the console. Wink
Cleaned up a minor routine in do_nodes which lays in command.c where
under an incoming NetRom connect, a user who did "Nodes" received
an extra line feed if the columns were all equal at 4 per row. This
was a bit under my skin... fixed/changed. While I was at it, I changed
the output string when doing "Nodes *" from 'Nodes:' to "Detailed
nodes listing:' which actually makes more sense since it is a detailed
list.
Fixed a minor bug in the way the prompts were handled under certain
telnet clients. This was reported also by Marius Petrescu yo2loj. Under
telnet, I added a carriage return (/r) along with the line feed (/n).
Thank you Marius for the report.
Slightly rewrote the way meminfo() was being handled. While I may have
created a bug in 2.4 and lower kernels, this now should work in 2.6 and
higher kernels. I guess the phrase "if it's not broke don't fix it"
doesn't apply anymore?
FINALLY - split the CHANGES file into a new page!! This makes it easier
for me to input the change notes instead of having to scroll down for 30
seconds Smile Call me lazy but don't call me late for supper! <G>
04/09/2013 v2.2
Made multiple .c file edits to reflect the new libax25-devel .h files.
Currently these were pointing to the older kernel_*.h files and on newer
linux systems was preventing compile. Now URONode should work fine.
Added Marius Petrescu to the URONode team! With his c version of ripv2d,
Marius will (and already has) make a huge impact on the future of
URONode! Welcome Marius to the team! Made a reflection of this in the
configure script.
Marius brought to my attention the issue in the log timer routine where
it was forcing 32-bit. He supplied code to fix this in both system.c and
flexd.c.
While in discussions, Marius brought it to my attention that Ubuntu (and
this includes Mint and any other Ubuntu backed distributions) where they
run as he calls it a "fortified libc6" which segfaults on every (what it
thinks is suspicious) buffer accesseD to prevent overflows however this
libc6 itself causes buffer overflowing. Why on earth did the Ubuntu team
ever do this?? Anyway, we're investigating how we're going to handle
this issue. I personally have verified URONode to compile and work on
the new kernel 3.x series on Debian and Fedora.
In "fixing" the prompt bug earlier reported by Marius, I made an error in
the non-ANSI telnet prompt where the (/r) was also chopping off the first
letter of a callsign! OOPS! This was reported by Ted K1YON. Fixed.
** Key news of this release: ROSE is a LOT more user friendly, AND it also
has the ability to display color screens to the end user. This now means
that URONode is an 8-prompt system! 4 main prompts, and 4 color prompts.
The prompt system is designed to show the end user what protocol/method
they used to connect into URONode with. Also proper SSIDs are displayed
to match that of how the end user connected. I did this because seeing
other nodes, they don't and when (as a user) connect into, for example,
a NetRom node who's ssid is -12 and the node displays something
-=totally=- different, I often wonder if I connected to the proper node.
The new prompt schema is:
telnet : user@<sysop>.ampr.org:/uronode$
netrom : <none> - this keeps in spec with Software2000
flex/ax25: =>
rose : -=>
Each matches with its own colors as well if you run the ansi flag. The
goodbye message for rose is also different than it is for flex/ax25 and
telnet links. The new RoseID flag is used as a personalized message to
the remote user to say a nice goodbye, and to remind them of your Rose
information. The (V)ersion command also has a rose column added to show
the remote user your rose information. An example of this is included
in the uronode.conf.5 man page.
With such, a new uronode.conf file string called RoseID has been created.
Details are in the file. You must keep the single quotes ' ' around the
string for it to display properly. You have been warned. Also, I've added
a default ExtCmd called ROSe so those who connect remotely can get rose
addresses for now. I'm sure I'll be changing this in the future.
Also, I decided to eliminate the permissions flag for use of hidden interfaces.
Reason being is if a sysop flags an interface to be hidden, they did so for a
specific reason. With that, I moved the ANSI flag from 512 in it's place to
64. This was also changed in the man page uronode.perms.5.
In regards to PBBS forwarding, I -=URGE=- you to read BBS.txt. Since
there's no need for me to rewrite it, please heed my warning here. This
is not something critical, just informational to help you improve your
link with URONode systems.
Fixed a cosmetic bug in regards to windows->linux emulation where when
logging in, sentences were not getting properly wrapped. This was done
in node.c. Other emulations such as PuTTY do not give you in windows
full linux-type emulation. Higher profile programs such as SecureCRT
will. For a free/shareware program I suggest MobiXterm. This also
gives you a raw Xserver emulated screen. Of course, there are no issues
if you use a standard linux console.
Added a .pid file to flexd, code supplied by Jaroslav, OK2JRQ and other
patches such as installer edits, etc. The only patches he supplied that I
have yet to add is the install location patch, and one he feels is good
for non-interactive. Source installs need to be interactive, if not you
would not be compliling - just my honest opinion. I can see in the case
of a possible distro package this may not be desired. The distros for now
can hash that out on their own.
Many more cosmetic bugs fixed/changed. Moreso in ROSE but I did find a
few others in there which needed my attention. I have noticed windows terminal
based programs such as PuTTY have an issue determining \n based line feeds
vs \r carriage returns in C code. This mainly seems to affect the various
8 prompts. It seems if I put both in the code, Windows is happy but *nx
may issue an added line-feed. I had thought I cleaned these all up but
I introduced a couple old ones and some new ones with the ROSE work.
01/10/2014 -2.2 released!
02/10/2014 - 2.2.1
Improperly packaged an old flexd.c! This one should compile. This is NOT
the one I want, I've been fighting with flexd for a while now.
uronode.conf may not update. If it does, you will need to redo yours from
scratch. Look at the one in the etc/ directory in the source and add the
line for RoseId. This is required. Thanks for the above reports from
VE1JOT and SP2LOB.
Removed the need to have quotes around the RoseId string in URONode.conf. I
found it unneccessary to have to do this. Keep the string togther ex:
callsign-ssid@1000,200000 now is fine. I also find this cleaner.
12/10/2014 - v5.1
URONode release ver 51 is out!.. um.. I mean its main developer *sigh*
21/12/2014 - v2.3
Added Bob Tenty ve3tok to the development team and created a subversion
server. Please welcome Bob to the team!
Bob Tenty ve3tok reports when NOT using the official ax25 packages and
on Ubuntu, the node when compiled natively may buffer overflow. He made
changes to buffers in gateway.c, router.c, and flexd.c which prevent this.
I have incorporated these changes and there's no ill effect on non Ubuntu
distros.
Fixed a bug I introduced into the ROSE ansi prompt where it wasn't
executing a proper \n because I inadvertantly removed it. Restored.
Fixed a warning in the axdigi code. Now that I'm on a more modern system
I can fix these things as now I can see them better. This was also brought
to my attention by Tomasz SP2L... thanks Tomasz!
Figured out a way to compile and have it NOT segfault under Ubuntu. While
I'll admit for the time being it's somewhat of a hack, but it *does* work
for Ubuntu. There are warnings on Ubuntu compiles that don't exist on other
platforms - interesting to say the least - but I think I see a relation
between the warnings and the pervious Makefile. The prior statement is being
left in as a comment deliberately as I hope to try and revert back to
the previous method.
**IMPORTANT: Per distro downstreams, I've been asked to change the paths
of the URONode installs. Now your uronode and binaries will be placed in
/usr/local/sbin instead of /usr/sbin. Config files will be in
/usr/local/etc/ax25 instead of /usr/ax25/. Node files will now be in
/usr/local/var/ax25/node or flexd instead of /var/ax25/node or flexd.
If you're a thrifty ham such as myself, you'll already have symlinks created
for easier management, so that /etc/ax25 is symlinked into /usr/local/etc/ax25
and so forth. Local files I can think of that would need editing if you use
my standard config:
/usr/local/bin/ax25
/etc/xinetd.d/uronode
/etc/xinetd.d/telnet (?)
/etc/ax25/ax25d.conf
Added a compile flag to keep Ubuntu happy. This and other routines were at the
suggestions of YO2LOJ and VE3TOK.
SYSop command does NOT spawn a shell anymore. This is due to the changes
with the UNIX98 file system. I'm debating on whether or not I wish to
continue to keep this or possibly eliminate this (for possible security
reasons). I see both PROs and CONs with it. Note: this ONLY affects those
systems which force the use of /dev/ptmx in which one needs to use SOCAT
to create static /dev/tty*# and /dev/pty*# pipes. This only affects the
Kernel 3-series in which the older /dev/pty# system is no longer used and
a master ptyx is used.
I did notice UBUNTU made changes to their libraries last year (2013) in
which URONode compiled but failed to execute any direct disk read/write
routines. In any event, they fixed this bug late fall 2014 (at least in
12.0.4LTS). One of the nice things about Ubuntu doing this is that you
can add a line in your grub configuration to have the kernel create a
number of satic pseudo terminals upon boot. Debian, however, breaks this
ruleset. I contacted my downstream and he hasn't responded. This would
help a sysop gain a shell... however also creates a possible backdoor.
Edited gateway.c so that the callsign-ssid is force altered on outbound
ax25 connect requests regardless of how the inbound connect was initiated.
VE1JOT reports that when a user telnets in, and gateway ax25 connects out,
the callsign-0 is kept. This should be altered to a -15. This was always
true when inbound connects were ax25 and also outbound connects the same.
VE1JOT reports this is troublesome, and in some cases causing DM frames
to occur. While I tested this and found this not to be true on my own
system, I did make a code adjustment to handle this.
Fixed a bug in config.h which may cause flexd not to find the proper
config lines. When I changed file paths I missed a couple. Now the system as
a whole should be consistant in regards to config files.
Removed the need for MyGate and MyRange in flexd.conf! This was added by
the request of K2BJG/SK so that the flexgate itself would be listed. Actually
it is in the LINKS file. Unfortunately when trying to connect to a listed
flexgate, it would try to digi via itself! Not good. While I was at it, I
also increased the buffer from 512 to 1024. This may help with those gates
that insist on making L A R G E MOTDs.
14/02/2015 - v2.3.1
Happy Valentine's day to the one we all love: Our Compilers!
This is a critical security patch! I URGE you *all* to recompile.
If anything, hopefully you've all patched your systems against GHOST.
For those who wish to test their system I have a tool on my ftp site
which can do this for you.
Through Paul G4APL, Andy G0HXT reported a condition on Ubuntu-based
systems in which a user may enter a malformed NetRom connect string
into URONode and the node will buffer overflow. I fixed this in
gateway.c limiting the string for searching connects on the first parameter.
Also changed the error output to the user so that they may know the error
may be their own.
Made edits to all the man pages and the INSTALL file as suggested by Tomasz
SP2L. I also grepped for certain strings in other files and made a change
to the README file as well.
Changed the version in node.h to reflect this security patch.
Known NON-Critical Bugs:
Status memory/swap reporting fix
Wish-list:
Who file sorter
pactor - requested by sv1uy
-----------
Original Development Information (aka Disclaimer):
URONode was developed on an IBM eSeries 330 eServer with dual 1.2GHz CPUs
The OS is Debian Linux 4 using kernel 2.4.27, libax25 v0.0.11,
ax25-tools v0.0.8 and ax25-apps v0.0.6. This software comes with
absolutely NO guarantees so crash n burn at your own risk. We all may
be surprised and find out that it actually DOES something useful!
URONode may not run 100% depending on environmental conditions specific
to your system.
URONode is GLPv2 code, and tested by it's main author on the following
platforms: Raspberry Pi ver. B, Debian 7.7 on a Core-i3, Ubuntu 12.0.4LTS
on a Core-i3, Fedora ver. 19
------------
Comments/suggestions? email: n1uro@n1uro.ampr.org
Gripes??? cat gripes > /dev/null Smile just kidding!
This version will get you going for now. I'll post any changes to:
ftp://ftp.n1uro.net/packet
Join our support mail list graciously donated by TAPR!
http://www.tapr.org/mailman/listinfo/uronode
73 de Brian N1URO

25
COLORS Normal file
View File

@ -0,0 +1,25 @@
Incase you're wondering about the method behind the madness in my color
schema it's very simple. Picture yourself with 3 vehicles to drive on
different roads with; a scooter, a compact car, and an SUV. Each vehicle
(or protocol) has it's own color. Each vehicle follows the same rules
of the road (green for go, red for stop, blinking red for alarms). When
you command URONode to go somewhere, you get green. When you return and
the process has completed it's red. Ax25/Flex is Yellow, NetRom is Cyan,
and IP/System messages are Magenta.
It's VERY IMPORTANT that you program any automated scripts that connect
to URONode that they do NOT use colors! Simply remove 512 from their
permissions. If you do NOT do this, the robot script may attempt to
decipher ANSI code and it may cause it to hang. YOU HAVE BEEN WARNED!
Here's the schema:
Connects display in green as in "gateway go"
Reconnects display in red as in "gateway stop"
IP based information is in magenta
Netrom Nodes (full list) in bold cyan
FlexNet destis (full list) in yellow
System info in bright white
Aborts and timeouts blink bright red
Logouts in low cyan

339
COPYING Normal file
View File

@ -0,0 +1,339 @@
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.

35
FAQ Normal file
View File

@ -0,0 +1,35 @@
Welcome to the official FAQ file for URONode.
The purpose of this file is to help explain better about URONode and what
the various features were designed for. Since this file will be maintained
via URONode Sysop reports, I'll consider this file a constant 'work in
progress' type file.
When using URONode or really any other linux node flavor, keep in mind
that the actual node program itself is only a front-end for the users
to do various functions your linux server may have to provide. Node really
doesn't do any sort of control features whatsoever, it merely acts as a
sort of proxy to your linux daemons. Those features are toggled on/off at
compile time by the operator of the node. I've taken time to rework the
configure script to give the node ops more flexibility in what they wish
to service their end users with. Nothing about URONode was ever designed
as a 'replacement' for any existing services such as email and convers.
I'm not even going to suggest one chooses to run URONode as a replacement
for LinuxNode by Tomi, AWZNode, or even FlexNode. The goals I set when
starting this project were moreso to custom fit my unique setup and its
something I can share with the amateur community at the same time.
URONode is NOT:
A replacement for *NOS
A replacement for Email
A replacement for PBBS
A replacement for convers
A FlexNet router
URONode IS:
A user front-end with some additional features to help compliment those
existing features an end user may need but for whatever reason doesn't
have access to at the moment, while allowing links to various entities
such as AX.25 links, Net/Rom routing, FlexNet destinations, general and
amprnet TCP/IP services.

79
INSTALL Normal file
View File

@ -0,0 +1,79 @@
1. COMPILING and INSTALLING
To compile and run URONode you will need to have libax25-0.0.4 or newer
installed on your system. It should work on any platform where libax25 can
be compiled and installed.
Note however that it will NOT work with 2.0.x kernels.
To install you should first run:
./configure
and answer to the questions it makes.
** IF ** this is an ** UPGRADE **:
and if you said no to configure running a "make", just type:
make; make upgrade
This will *not* overwrite your config files, and will freshen up
your binaries only. If you told the configure script to make, then
all you need to type to upgrade is: make upgrade.
** IF ** this is a new install:
If all files needed are present everything should work. Next:
make (if you said "no" to the configure script launching it for you)
make install
make installhelp
Optionally you may want to run also:
make installconf
to install the default configuration files.
Note however this copy example files in /usr/local/etc/ax25 but with ".ex".
You should rename it by removing ".ex" at the end of filenames.
After that you need to edit the configuration files to suit your system.
The manual pages for uronode.conf(5) and uronode.perms(5) should give
an idea of what to put into these files. The AX25-HOWTO is a must read also.
2. RUNNING
URONode is intended to be called from ax25d or inetd. It doesn't need
any command line arguments. See the uronode(8) manual page.
To run URONode from ax25d, /usr/local/etc/ax25/ax25d.conf should have something
like this in it:
# AX25 Port ax0
# Belows SSID can not be the same as your netrom node SSID!
[N1URO-2 VIA ax0]
default * * * * * * - root /usr/local/sbin/uronode uronode
# NETROM Port
<nr0>
default * * * * * * - root /usr/local/sbin/uronode uronode
add uronode as a service in /etc/services:
uronode 3694/tcp # Node/URONode packet
if you use inetd -
/etc/inetd.conf could have something like this in it:
# Listen at telnet port -> URONode
uronode stream tcp nowait nobody /usr/local/sbin/uronode uronode
if you use xinetd -
/etc/xinetd.d/uronode should look like this:
service uronode
{
disable = no
socket_type = stream
protocol = tcp
user = nobody
server = /usr/local/sbin/uronode
wait = no
instances = 20
}

100
Makefile.in Normal file
View File

@ -0,0 +1,100 @@
all: nodeusers uronode axdigi @FLEXNET@
CC = gcc
LD = gcc
# CFLAGS = -O2 -g -s -Wstrict-prototypes
CFLAGS = -O2 -g -Wno-unused-result -Wstrict-prototypes
LDFLAGS =
LIBS = -lax25 -lax25io
include Makefile.include
COMMON_SRC = user.c util.c
NODE_SRC = node.c cmdparse.c config.c command.c mheard.c axcalluser.c \
gateway.c extcmd.c procinfo.c router.c system.c sysinfo.c ipc.c
NODEUSERS_SRC = nodeusers.c
FLEXD_SRC = flexd.c procinfo.c
DIGI_SRC = axdigi.c
COMMON_OBJS = $(COMMON_SRC:.c=.o)
NODE_OBJS = $(NODE_SRC:.c=.o)
NODEUSERS_OBJS = $(NODEUSERS_SRC:.c=.o)
FLEXD_OBJS = $(FLEXD_SRC:.c=.o)
DIGI_OBJS = $(DIGI_SRC:.c=.o)
.c.o:
$(CC) $(CFLAGS) -c $<
install: installbin installman installhelp installconf
install -m 755 -D -d $(VAR_DIR)
install -m 755 -D -d $(VAR_DIR)/node
install -m 644 -p etc/loggedin $(VAR_DIR)/node
install -m 644 -p etc/lastlog $(VAR_DIR)/node
install -m 755 -D -d $(VAR_DIR)/flex
install -m 644 -p etc/gateways $(VAR_DIR)/flex
installbin: all
install -m 755 -s -p uronode $(SBIN_DIR)
install -m 755 -s -p nodeusers $(SBIN_DIR)
install -m 755 -s -p axdigi $(SBIN_DIR)
@IN@ install -m 755 -s -p flexd $(SBIN_DIR)
installhelp:
install -m 755 -D -d $(VAR_DIR)
install -m 755 -D -d $(VAR_DIR)/node/help
install -m 644 -p etc/help/*.hlp $(VAR_DIR)/node/help
installconf: installhelp
install -m 755 -D -d $(ETC_DIR)
install -m 600 -p etc/uronode.conf $(ETC_DIR)
install -m 600 -p etc/uronode.perms $(ETC_DIR)
install -m 600 -p etc/uronode.info $(ETC_DIR)
install -m 600 -p etc/uronode.motd $(ETC_DIR)
install -m 600 -p etc/uronode.users $(ETC_DIR)
install -m 600 -p etc/uronode.routes $(ETC_DIR)
install -m 600 -p etc/flexd.conf $(ETC_DIR)
installman:
install -m 755 -D -d $(MAN_DIR)/man1 $(MAN_DIR)/man5 $(MAN_DIR)/man8
install -m 644 -p man/nodeusers.1.gz $(MAN_DIR)/man1
install -m 644 -p man/uronode.conf.5.gz $(MAN_DIR)/man5
install -m 644 -p man/uronode.perms.5.gz $(MAN_DIR)/man5
install -m 644 -p man/flexd.conf.5.gz $(MAN_DIR)/man5
install -m 644 -p man/uronode.8.gz $(MAN_DIR)/man8
install -m 644 -p man/axdigi.8.gz $(MAN_DIR)/man8
upgrade: installman
install -m 755 -p uronode $(SBIN_DIR)
install -m 755 -p nodeusers $(SBIN_DIR)
install -m 755 -p flexd $(SBIN_DIR)
install -m 755 -p axdigi $(SBIN_DIR)
install -m 644 -p uronode.conf $(ETC_DIR)
install -m 644 -p uronode.perms $(ETC_DIR)
clean:
rm -f *.o *~ *.bak *.orig make.debug nodeusers uronode flexd axdigi
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 uronode nodeusers axdigi @FLEXNET@
rm -f Makefile make.debug
depend:
$(CC) $(CFLAGS) -M $(COMMON_SRC) $(NODE_SRC) $(NODEUSERS_SRC) $(FLEXD_SRC) > .depend
uronode: $(COMMON_OBJS) $(NODE_OBJS)
$(LD) $(LDFLAGS) -o uronode $(COMMON_OBJS) $(NODE_OBJS) $(LIBS) $(ZLIB)
nodeusers: $(COMMON_OBJS) $(NODEUSERS_OBJS)
$(LD) $(LDFLAGS) -o nodeusers $(COMMON_OBJS) $(NODEUSERS_OBJS) $(LIBS) $(ZLIB)
flexd: $(FLEXD_OBJS)
$(LD) $(LDFLAGS) -o flexd $(FLEXD_OBJS) $(LIBS) $(ZLIB)
axdigi: $(DIGI_OBJS)
$(LD) $(LDFLAGS) -o axdigi $(DIGI_OBJS)
ifeq (.depend,$(wildcard .depend))
include .depend
endif

13
Makefile.include.in Normal file
View File

@ -0,0 +1,13 @@
# Processor architecture
ARCH = @ARCH@
# Paths
ETC_DIR = @ETC_DIR@
SBIN_DIR = @SBIN_DIR@
BIN_DIR = @BIN_DIR@
LIB_DIR = @LIB_DIR@
MAN_DIR = @MAN_DIR@
VAR_DIR = @VAR_DIR@
# Is Zlib available?
ZLIB = @ZLIB@

95
README Normal file
View File

@ -0,0 +1,95 @@
Please check out the file INSTALL to compile and install URONode.
Also please read the CHANGES.* file for all version history changes.URONode README file September 09, 2013
Note: Please read the CHANGES file for detailed information
about the changes from AWZNode to URONode and what I've
done with it... along with current version info! - Brian N1URO
Hi linuxers!
First all, I thanks PE1RJA and OH2BNS for their very great job!
*****************************************************************************
The v0.5.x release is a temporary version of URONode running and compiling
under linux 2.4.x, with glibc 6 and new ax25 and ax25io libraries. v0.0.11
*****************************************************************************
UROnode is based on AWZ|LinuxNode by Tomi Manninen OH2BNS and FlexNode
by Roy PE1RJA. It was born initially for the aripisa.ampr.org system
by Stefano Noferi IZ5AWZ of ARI Ham Radio Association of Pisa (ITALY).
Users in URONode can connect all ham packet world: all AX25, NETROM, ROSE,
FLEXNET, ITANET, TCP/IP nodes in the world are now near.
Comment from Stefano:
I have a "packet" dream: all the packet networks can interchange connections.
My version of node software for Linux is an attempt to realize this idea
and I hope it can help the ham radio digital world to come back one. ;)
I thanks ARI association of Pisa and Alex Del Chicca IK5PWJ,
for their trust and supports.
This README file, the documentation etc. are very incomplete!
Sorry, but my free time is very very very... very little.. :)
If you decide to use URONode, send me a mail.
Routing features include: (in order preferance)
- netrom routing
- fixed routes
Create and/or modify /usr/local/etc/ax25/uronode.routes, the format of
this file is in the example file uronode.route.ex.
Now fixed link nodes in this file have an alias and 3 connection
modes, can be queried using the Links command and can be
connected directly using: Connect <call>|<alias> (ie. without
specifying the downlink port)
- flexnet destination lists
A separate daemon (flexd) queries a neighbouring flexnet node for its
reachable destinations, these destinations are stored on the local
disk and can be queried using the Dest command and can be connected
directly using: Connect <destination>
Config file: flexd.conf:
MyCall <call> # the callsign used during the connection
PollInterval <interval> # how often the destinations are downloaded
FlexGate <call> # the neighbouring flexnet node
The pollinterval is specified in seconds and the callsign after
flexgate must be defined in uronode.routes !!
- mheard based routing
When users are using your node the mheard tables are filled with
callsigns, callsigns heard on ports can be connected directly with
the Connect <call> command, without specifying the downlink port.
Other features:
- local users of the linux machine can be granted access to the mailreader
and optionally to the shell. Config file: /etc/ax25/node.users
<call>:<password>:<username>:[mail][,shell]
call : the callsign of the user that is allowed to access special features
password : a string pasword
username : the (real)-username on the linux side
options : mail - the user has permission to access his or her mailbox
shell - the user has permission to access the shell
Users with the mail option enabled will receive messages like "New mail
has arrived", mostly when the stated condition is met ;-)
- all users can send messages to a callsign associated in the kernel table
with a linux username ("send" command).
- now the sysop can modified the node prompt and password prompt
- "!" command show system statistics
- old "SEssions" command is now "MSessions"
- now "MHeard" command can be used without port specification
- changed the output of several query programs (like ports/routes etc.) also
included more netrom specific output in these commands
- included a lastlog, which shows the time, date and port of your previous
session, if this is your first connect, you are requested to read the
info text
The official FTP Site of URONode is:
https://sourceforge.net/projects/uronode/?source=directory
ftp://ftp.n1uro.net/packet/
The official Forums site is:
http://www.tapr.org/mailman/listinfo/uronode
URONode is also a part of Fedora 20 and higher.
"yum install uronode" to install the .rpm package.
Please check out the file INSTALL to compile and install URONode.
Also please read the CHANGES.* file for all version history changes.

49
URONode.his Normal file
View File

@ -0,0 +1,49 @@
** Note: this file is depreciated, refer to CHANGES.*
URONode was spawned off of the original linuxnode by Tomi Manninen OH2BNS
Before URONode was FlexNode by Roy PE1RJA, and then by Stefano Noferi IZ5AWZ
who called it AWZNode. I took over the code willingly and on my own mainly
as a project I could do under C program coding in April 2003 after it
appeared that AWZNode was no longer being developed.
My first goal was to make it appear and act more like TheNet X1J and spent
most of my time configuring the node to behave as such which I felt I did
quite successfully. While doing that I thought I'd try to add in email
features by using the old PMS system written by Alan Cox, who has a lot
of code in the main linux kernel for it's IP stack (most of which is taken
directly out of KA9Q nos). While I was successful in doing that, Morgan
SM6TKY reported that the code was old and exploitable... unfortunately I had
a period where I couldn't devote the time into getting it repaired quickly
and URONode sat and suffered with a note explaining that certain features
should not be used or enabled. As a quick fix, I simply commented out the
found exploits and did some more cosmetics to the code and released a patch.
Still with users wanting EMAIL as a feature to the software, this inspired me
to pick up with the dropped axMail code and bring that more up to date. axMail
was originally started by Heikki Hannikainen, and then mailbox routines were
added by Marius Petrescu, however system configs were lacking. I took the
code and added in the routines which are in there now so that new users
are properly created within the basic linux filesystem schema, and passwords
can be created (optional) so that a web front-end such as NeoMail can be
used in conjunction with axMail giving users the choice of the web or RF
packet to do their SMTP based EMAIL with. It was and always will be an optional
add-on module for URONode, and other flavors of *node for linux.
These two packages together, along with F6FBB make for one heck of a feature
packed system a sysop can piece together on one server. Because of such,
URONode has become very popular in the NorthEast USA and in Central East
Florida within the EastNet FlexNet network and with the Florida MARS
networks. With this, I've taken the look and feel of URONode to try and
match that of a FlexNet interface.
The latest version of URONode under-went many face lifts! The node not only
auto-senses the incoming connection but delivers an interface which clones
that of the type of system they're connecting in from. A user connecting
in via IP will actually get a prompt that looks and acts similar to a
Unix bash prompt with custom aliased commands!.. and to top that all off
I've added an ansi schema to the IP interface!!
URONode is used world-wide in Europe, Africa, Asia, and in North America.
A web bbs is available at https://www.n1uro.net/forum where release notes
for URONode are posted. If the functionality of URONode isn't enough to
get interest in packet growing, the stability of URONode should!

77
axcalluser.c Normal file
View File

@ -0,0 +1,77 @@
/* axcalluser.c - determine username corresponding to callsign */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include "config.h"
#include "axcalluser.h"
int axcalluserid(char *call)
{
char callsign[10];
char username[80];
int id;
int userid = -1;
FILE *f = fopen(PROC_AX25_CALLS_FILE,"r");
if (f) { /* VE3TOK, 18Nov2014, return value usage */
if (fgets(username,79,f) == NULL) {
syslog(LOG_DEBUG, "Can't get username: %s", strerror(errno));
return 1;
}
while (fscanf(f," %d %9s",&id,callsign) != EOF) {
char *a,*b;
for (a=call,b=callsign;
*a && *b && toupper(*a)==toupper(*b) && *b!='-';
a++,b++) ;
if (!isalnum(*a) && !isalnum(*b)) {
userid = id;
}
}
}
fclose(f);
return userid;
}
char *getusername(int userid)
{
int colons;
int c,i;
char token[80];
static char name[80];
char *retval = NULL;
FILE *f;
f = fopen("/etc/passwd","r");
if (f) {
i = 0;
colons = 0;
while ((c = getc(f)) != EOF) {
switch (c) {
case ':':
token[i] = '\0';
colons++;
if (colons == 3) {
if (userid == atoi(token)) {
retval = name;
goto endloop;
}
} else if (colons == 1) {
strcpy(name,token);
}
i = 0;
break;
case '\n':
colons = 0;
i = 0;
break;
default:
token[i++] = c;
break;
}
}
endloop:
fclose(f);
}
return retval;
}

16
axcalluser.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef AXCALLUSER_H
#define AXCALLUSER_H
/* Simple functions to return userid of a callsign, and */
/* username of a userid, by reading appropriate files. */
/* Surely there's a better way to do 'getusername', but */
/* this works. */
/* Dave Brown N2RJT 5/5/96 */
/* return userid of given callsign, or -1 if not found */
int axcalluserid(char *callsign);
/* return username of given userid, or NULL if not found */
char *getusername(int userid);
#endif

255
axdigi.c Normal file
View File

@ -0,0 +1,255 @@
/*
* axdigi: Cross and straight port digipeater program
* Copyright (C) 1995 Craig Small VK2XLZ
*
* 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.
*
* JSN - Small tweaks to ensure compilation and execution under Linux 2.1.x.
* 12th June 1997.
*/
#include </usr/include/net/if.h>
#include <linux/if_ether.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
/* below added by N1URO */
#include <string.h>
#include <unistd.h>
#include <linux/ax25.h>
int recv_packet(unsigned char *buf, int size, unsigned char *port);
void print_call(unsigned char *buf);
unsigned char *find_call(char *port);
void add_port(char *call, char *port);
void get_interfaces(int skt);
/*
* The defines we use
*/
#define AXALEN 7
#define E_BIT 0x01 /* Address extension bit */
#define REPEATED 0x80 /* Has-been-repeated bit */
#define MAX_PORTS 16
#define VERSION "0.2"
int port_count = 0;
unsigned char portname[MAX_PORTS][20];
unsigned char portcall[MAX_PORTS][8];
int main(int argc, char *argv[])
{
int skt;
int size, rt;
unsigned char buf[4096];
struct sockaddr sa;
int asize;
/* Check our huge range of flags */
if (argc > 1)
{
if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "-h") ==0)
{
printf("axdigi version %s. Copyright (C) 1995 Craig Small VK2XLZ\n\n", VERSION);
printf("axdigi comes with ABSOLUTELY NO WARRANTY.\n");
printf("This is free software, and you are welcome to redistribute it\n");
printf("under the terms of GNU General Public Licence as published\n");
printf("by Free Software Foundation; either version 2 of the License, or\n");
printf("(at your option) any later version.\n");
return 0;
}
}
/* Change to keep code more modern - N1URO */
if ((skt = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_AX25))) == -1)
{
perror("socket");
return(1);
}
get_interfaces(skt);
while(1)
{
asize = sizeof(sa);
if ((size = recvfrom(skt, buf, sizeof(buf), 0, &sa, &asize)) == -1)
{
perror("recv");
exit(1);
}
if ((rt = recv_packet(buf, size, sa.sa_data)) >= 0)
{
if (rt < port_count)
{
asize = sizeof(sa);
strcpy(sa.sa_data, portname[rt]);
if (sendto(skt, buf, size, 0, &sa, asize) == -1)
perror("sendto");
continue;
}
/* printf("Unknown port %s\n", sa.sa_data);*/
} /* recv_packet true */
} /* while(1) */
close(skt);
}
int recv_packet(unsigned char *buf, int size, unsigned char *port)
{
unsigned char *bptr;
int count, i;
unsigned char *call;
/* printf("Got packet size %d\n", size);*/
/*
* Decode the AX.25 Packet
*/
/* Find packet, skip over flag */
bptr = buf+1;
/* Now at destination address */
/* print_call(bptr);
printf("<-");*/
bptr += AXALEN;
/* Now at source address */
/* print_call(bptr);*/
if (bptr[6] & E_BIT)
{
/* printf("\n");*/
return -1; /* No digis, we're not interested */
}
/* printf(" ");*/
bptr += AXALEN;
/* Now at digipeaters */
count = 0;
while( count < AX25_MAX_DIGIS && ( (bptr - buf) < size))
{
/* print_call(bptr);
printf(", ");*/
if (bptr[6] & REPEATED)
{
/* This one has been repeated, move to next one */
bptr += AXALEN;
count++;
continue;
}
/* Check to see if callsign is one of ours */
for (i = 0; i < port_count; i++)
{
/* printf("compare ");
print_call(bptr);
printf(" ");
print_call(portcall[i]);
printf("\n");*/
if ( (bcmp(bptr, portcall[i], AXALEN-1) == 0) && ((bptr[6] & 0x1e) == portcall[i][6]))
{
/* Copy new address over and turn on repeated bit*/
call = find_call(port);
if (call == NULL)
return -1;
bcopy(call, bptr, AXALEN-1);
bptr[6] = (bptr[6] & ~0x1e) | call[6];
bptr[6] |= REPEATED;
return i;
}
} /* for */
return -1;
}
return -1;
}
void print_call(unsigned char *bptr)
{
printf("%c%c%c%c%c%c-%d", bptr[0] >> 1, bptr[1] >> 1,
bptr[2] >> 1, bptr[3] >> 1, bptr[4] >> 1, bptr[5] >> 1,
(bptr[6] >> 1) & 0xf);
}
void add_port(char *call, char *port)
{
unsigned char *s;
int n;
if (port_count == MAX_PORTS)
return;
s = portcall[port_count];
while( (*call != '-') && ( (int)(s - portcall[port_count])< 6))
*s++ = (*call++) << 1;
call++; /* skip over dash */
n = atoi(call);
*s = n << 1;
strcpy(portname[port_count], port);
port_count++;
}
unsigned char *find_call(char *port)
{
static unsigned char callsign[8];
int i;
for(i = 0; i < port_count; i++)
{
if (strcmp(port, portname[i]) == 0)
{
bcopy(portcall[i], callsign, 7);
return callsign;
}
}
return (char*)NULL;
}
void get_interfaces(int skt)
{
char buf[1024];
struct ifconf ifc;
struct ifreq *ifr;
int i;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl(skt, SIOCGIFCONF, &ifc) < 0)
{
perror("ioctl");
exit(1);
}
ifr = ifc.ifc_req;
for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
{
if (ioctl(skt, SIOCGIFHWADDR, ifr) < 0)
continue;
if (ifr->ifr_hwaddr.sa_family == AF_AX25)
{
/* AX25 port, add to list */
if (port_count < MAX_PORTS)
{
bcopy(ifr->ifr_hwaddr.sa_data, portcall[port_count], 7);
strcpy(portname[port_count], ifr->ifr_name);
port_count++;
}
}
} /* for */
}

300
cmdparse.c Normal file
View File

@ -0,0 +1,300 @@
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <netax25/ax25.h>
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include "node.h"
static void expand_string(char *dest, char *src, int argc, char **argv)
{
char tmpbuf[64], def[64];
char *p1, *p2, *cp;
int n, skip, nocopy;
if (strchr(src, '%') == NULL) {
strcpy(dest, src);
return;
}
p1 = src;
p2 = dest;
while (*p1) {
if (*p1 == '%') {
nocopy=1;
p1++;
skip = 1;
def[0] = 0;
if (*p1 == '{') {
p1++;
if ((cp = strchr(p1, '}')) != NULL) {
skip = cp - p1 + 1;
cp = p1;
if (*++cp == ':') {
cp++;
n = min(skip - 3, 63);
strncpy(def, cp, n);
def[n] = 0;
}
}
}
switch (*p1) {
case 'u':
case 'U':
strcpy(tmpbuf, User.call);
if ((cp = strrchr(tmpbuf, '-'))) *cp = 0;
break;
case 's':
case 'S':
strcpy(tmpbuf, User.call);
break;
case 'p':
case 'P':
strcpy(tmpbuf, User.ul_name);
if ((cp = strrchr(tmpbuf, '-'))) *cp = 0;
break;
case 'r':
case 'R':
strcpy(tmpbuf, User.ul_name);
break;
case 't':
case 'T':
switch (User.ul_type) {
case AF_FLEXNET:
strcpy(tmpbuf, "flexnet");
break;
case AF_AX25:
strcpy(tmpbuf, "ax25");
break;
case AF_NETROM:
strcpy(tmpbuf, "netrom");
break;
#ifdef HAVE_ROSE
case AF_ROSE:
strcpy(tmpbuf, "rose");
break;
#endif
case AF_INET:
strcpy(tmpbuf, "inet");
break;
case AF_UNSPEC:
strcpy(tmpbuf, "host");
break;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = *p1 - '0';
if (n < argc) strcpy(tmpbuf, argv[n]);
else strcpy(tmpbuf, def);
break;
case '*':
nocopy=0;
for(n=2;n<argc;n++) {
if (argv[n]==NULL) break;
strcpy(tmpbuf, argv[n]);
if (isalpha(*p1)) {
if (isupper(*p1)) strupr(tmpbuf);
else strlwr(tmpbuf);
}
strcpy(p2, tmpbuf);
p2 += strlen(tmpbuf);
}
break;
default:
strcpy(tmpbuf, "%");
break;
}
if (nocopy==1) {
if (isalpha(*p1)) {
if (isupper(*p1)) strupr(tmpbuf);
else strlwr(tmpbuf);
}
strcpy(p2, tmpbuf);
p2 += strlen(tmpbuf);
}
p1 += skip;
} else
*p2++ = *p1++;
}
*p2 = 0;
return;
}
/* This function is straight from *NOS */
static char *parse_string(char *str)
{
char *cp = str;
unsigned long num;
while (*str != '\0' && *str != '\"') {
if (*str == '\\') {
str++;
switch (*str++) {
case 'n': *cp++ = '\n'; break;
case 't': *cp++ = '\t'; break;
case 'v': *cp++ = '\v'; break;
case 'b': *cp++ = '\b'; break;
case 'r': *cp++ = '\r'; break;
case 'f': *cp++ = '\f'; break;
case 'a': *cp++ = '\007'; break;
case '\\': *cp++ = '\\'; break;
case '\"': *cp++ = '\"'; break;
case 'x':
num = strtoul(--str, &str, 16);
*cp++ = (char) num;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
num = strtoul(--str, &str, 8);
*cp++ = (char) num;
break;
case '\0':
return NULL;
default:
*cp++ = *(str - 1);
break;
};
} else {
*cp++ = *str++;
}
}
if (*str == '\"') str++; /* skip final quote */
*cp = '\0'; /* terminate string */
return str;
}
int parse_args(char **argv, char *cmd)
{
int ct = 0;
int quoted;
while (ct < 31) {
quoted = 0;
while (*cmd && isspace(*cmd)) cmd++;
if (*cmd == 0) break;
if (*cmd == '"') {
quoted++;
cmd++;
}
argv[ct++] = cmd;
if (quoted) {
if ((cmd = parse_string(cmd)) == NULL)
return 0;
} else {
while (*cmd && !isspace(*cmd)) cmd++;
}
if (*cmd) *cmd++ = 0;
}
argv[ct] = NULL;
return ct;
}
int cmdparse(struct cmd *list, char *cmdline)
{
struct cmd *cmdp;
int argc;
char *argv[32];
static char cmdbuf[1024];
/* convert cmdline to argc,argv[] if '#' or empty: return */
if ((argc = parse_args(argv, cmdline)) == 0 || *argv[0] == '#') return 2;
/* check if the command in argv[0] is in the list */
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) return -1;
strlwr(argv[0]);
switch (cmdp->type) {
case CMD_INTERNAL: /* execute internal command */
return (*cmdp->function)(argc, argv);
case CMD_ALIAS:
/* evaluate arguments */
expand_string(cmdbuf, cmdp->command, argc, argv);
aliascmd=1;
/* re-execute the command */
return cmdparse(list, cmdbuf);
case CMD_EXTERNAL:
/* evaluate arguments */
expand_string(cmdbuf, cmdp->command, argc, argv);
/* convert the cmdline to argc,argv[] */
argc = parse_args(argv, cmdbuf);
/* execute an external command */
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} ", NodeId);
}
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;32mExecuting command...\e[0m\n");
} else {
axio_puts("Executing command... \n", NodeIo);
}
return extcmd(cmdp, argv);
}
return -1;
}
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;
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);
}
}

1058
command.c Normal file

File diff suppressed because it is too large Load Diff

485
config.c Normal file
View File

@ -0,0 +1,485 @@
#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 <netax25/ax25.h> /* axutils.h needs this... */
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include "node.h"
long IdleTimeout = 360L; /* default to 6 mins */
long ConnTimeout = 300L; /* default to 5 mins */
int ReConnectTo = 0;
int LogLevel = LOGLVL_ERROR;
int EscChar = 20; /* CTRL-T */
char *Email = NULL;
char *HostName = NULL;
char *NodeId = NULL;
char *NrPort = NULL; /* first netrom port */
char *FlexId = NULL;
char *RoseId = NULL;
#ifdef HAVEMOTD
char *Prompt = "\n=> "; /* Prompt by IZ5AWZ */
#else
char *Prompt = "\n";
#endif
char *PassPrompt = "\nPassword >"; /* Prompt Password by IZ5AWZ */
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;
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;
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");
node_log(LOGLVL_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_FLEXNET:
if (!strcmp(argv[1], "*"))
break;
if (!strcasecmp(argv[1], "flexnet"))
break;
continue;
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;
#ifdef HAVE_ROSE
case AF_ROSE:
if (!strcmp(argv[1], "*"))
break;
if (!strcasecmp(argv[1], "rose"))
break;
continue;
#endif
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)
return NULL;
else
return strdup(argv[3]);
}
return NULL;
}
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");
node_log(LOGLVL_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)
{
#ifdef HAVEMOTD
if (argc < 2)
return -1;
if (!strcasecmp(argv[1], "on"))
ReConnectTo = 1;
else
#endif
ReConnectTo = 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");
node_log(LOGLVL_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");
node_log(LOGLVL_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++) {
sprintf(&buf[len], "\"%s\" ", argv[i + 5]);
len = strlen(buf);
}
new->command = strdup(buf);
new->type = CMD_EXTERNAL;
insert_cmd(&Nodecmds, new);
return 0;
}
static int do_nodeid(int argc, char **argv)
{
if (User.ul_type == AF_NETROM) {
if (argc < 2)
return -1;
NodeId = strdup(argv[1]);
} else if (User.ul_type != AF_NETROM) {
NodeId = strdup(argv[1]);
}
return 0;
}
static int do_flexid(int argc, char **argv)
{
if (argc < 2 )
return -1;
FlexId = ("%s ;" , strdup(argv[1]));
return 0;
}
static int do_roseid(int argc, char **argv)
{
if (argc < 2 )
return -1;
RoseId = ("%s ;" , strdup(argv[1]));
return 0;
}
static int do_prompt(int argc, char **argv)
{
if ((User.ul_type != AF_NETROM) || (User.ul_type != AF_INET)) {
if (argc < 2) {
return -1;
Prompt = strdup(argv[1]);
return 0;
}
}
}
static int do_passprompt(int argc, char **argv)
{
if (User.ul_type != AF_NETROM) {
if (argc < 2)
return -1;
PassPrompt = strdup(argv[1]);
return 0;
}
}
static int do_nrport(int argc, char **argv)
{
if (argc < 2)
return -1;
NrPort = strdup(argv[1]);
return 0;
}
static int do_email(int argc, char **argv)
{
if (argc < 2)
return -1;
Email = 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", 5, do_alias);
add_internal_cmd(&cfg_cmds, "conntimeout", 11, do_conntimeout);
add_internal_cmd(&cfg_cmds, "email", 5, do_email);
add_internal_cmd(&cfg_cmds, "escapechar", 10, do_escapechar);
add_internal_cmd(&cfg_cmds, "extcmd", 6, do_extcmd);
add_internal_cmd(&cfg_cmds, "hiddenports", 11, do_hiddenports);
add_internal_cmd(&cfg_cmds, "hostname", 8, do_hostname);
add_internal_cmd(&cfg_cmds, "idletimeout", 11, do_idletimeout);
add_internal_cmd(&cfg_cmds, "localnet", 8, do_localnet);
add_internal_cmd(&cfg_cmds, "loglevel", 8, do_loglevel);
add_internal_cmd(&cfg_cmds, "nodeid", 6, do_nodeid);
add_internal_cmd(&cfg_cmds, "flexid", 6, do_flexid);
add_internal_cmd(&cfg_cmds, "roseid", 6, do_roseid);
add_internal_cmd(&cfg_cmds, "prompt", 6, do_prompt);
add_internal_cmd(&cfg_cmds, "nrport", 6, do_nrport);
add_internal_cmd(&cfg_cmds, "reconnect", 8, do_reconnect);
add_internal_cmd(&cfg_cmds, "passprompt", 6, do_passprompt);
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");
node_log(LOGLVL_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;
}

36
config.h.in Normal file
View File

@ -0,0 +1,36 @@
#ifndef CONFIG_H
#define CONFIG_H
/*
* Some global #defines for programmers to use for conditional compilation
*/
@HAVEAX25@
@HAVEFLEX@
@HAVEROSE@
@HAVENETROM@
@HAVEZLIB@
@HAVEMHEARD@
@HAVETCPIP@
#define PROC_AX25_CALLS_FILE "/proc/net/ax25_calls"
/*
* node specific
*/
#define CONF_NODE_FILE "@ETC_DIR@/uronode.conf"
#define CONF_NODE_PERMS_FILE "@ETC_DIR@/uronode.perms"
@HAVEMOTD@ @MOTDPATH@
#define CONF_NODE_INFO_FILE "@ETC_DIR@/uronode.info"
#define AX_ROUTES_FILE "@ETC_DIR@/uronode.routes"
#define CONF_USERS_FILE "@ETC_DIR@/uronode.users"
#define FLEXD_CONF_FILE "@ETC_DIR@/flexd.conf"
#define FLEXD_TEMP_PATH "@VAR_DIR@/flex/"
#define FLEXD_PID_FILE "/var/run/flexd.pid"
#define FLEX_GT_FILE "@VAR_DIR@/flex/gateways"
#define FLEX_DST_FILE "@VAR_DIR@/flex/destinations"
#define DATA_MHEARD_FILE "@VAR_DIR@/mheard/mheard.dat"
#define DATA_NODE_LOGIN_FILE "@VAR_DIR@/node/loggedin"
#define DATA_NODE_HELP_DIR "@VAR_DIR@/node/help/"
#define DATA_NODE_LAST_FILE "@VAR_DIR@/node/lastlog"
#define DATA_NODE_IP_FILE "@VAR_DIR@/node/iplog"
#endif

303
configure vendored Executable file
View File

@ -0,0 +1,303 @@
#!/bin/sh
_sleep()
{
[ "$NON_INTERACTIVE" = 1 ] || sleep "$@"
}
_whiptail()
{
[ "$NON_INTERACTIVE" = 1 ] || whiptail "$@"
}
echo "Cleaning the directory for a fresh configuration..."
_sleep 2
make distclean > make.debug
ETC_DIR=/usr/local/etc/ax25
SBIN_DIR=/usr/local/sbin
BIN_DIR=/usr/local/bin
LIB_DIR=/usr/local/lib
MAN_DIR=/usr/local/share/man
VAR_DIR=/usr/local/var/ax25
echo "Welcome to the configuration utility for URONode. This configure script"
echo "will very simply and easily guide you into installling URONode with as"
echo "very little trouble as possible. All you need to really do is simply"
echo "answer the following questions below properly. If you make a mistake"
echo "just break out of it (ctrl+c) and rerun ./configure. Let's get started!"
_sleep 1
echo " "
_sleep 1
echo -n "you need gcc to build URONode: "
GCC=`which gcc`
_sleep 2
if [ -e "$GCC" ]
then
echo -n "saw $GCC... "
_sleep 1
echo "GCC found! Congratulations!!"
else
echo "gcc not found!"
echo " "
echo "You need this compiler to build URONode."
echo "Please install gcc, and rerun this ./configure script."
echo "If you have a copy of gcc installed, please insure you have a"
echo "symlink by typing as root: ln -s /usr/bin/gcc-#.## /usr/bin/gcc"
echo "and rerun ./configure to continue."
exit 1
fi
echo -n "Your machine architecture is: "
_sleep 1
ARCH=`uname -m`
echo $ARCH
_sleep 1
echo -n "Checking for the existence of the Zlib headers... "
ZLIB=""
HAVEZLIB="#undef HAVE_ZLIB"
for zlibdir in /usr/include /usr/local/include
do
if [ -f $zlibdir/zlib.h ]
then
echo $zlibdir/zlib.h
ZLIB="-lz"
HAVEZLIB="#define HAVE_ZLIB 1"
fi
done
if [ -z "$ZLIB" ]
then
echo "not found."
echo " Without Zlib Node will lack compression support"
echo " See INSTALL for more information."
echo
fi
# Global protocol definition symbols for programmers that want to conditionally
# compile
HAVEAX25="#undef HAVE_AX25"
HAVEFLEX="#undef HAVE_FLEX"
FLEXNET=" "
IN="#"
HAVENETROM="#undef HAVE_NETROM"
HAVEROSE="#undef HAVE_ROSE"
HAVEMHEARD="#undef HAVE_MHEARD"
HAVETCPIP="#undef HAVE_TCPIP"
HAVEMOTD="#undef HAVE_MOTD"
MOTDPATH=
# echo -n "Include support for the AX.25 protocol ? [Y/n]: "; read answer
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
if [ "$NON_INTERACTIVE" = 1 ]
then
echo "$@" | grep -vqe "--without-ax25"
else
whiptail --title "URONode Options:" --yesno "Support AX25?" 7 22
fi
if [ $? -ne 1 ]
then
HAVEAX25="#define HAVE_AX25 1"
fi
#
# echo -n "Include support for the FlexNet protocol ? [Y/n]: "; read answer
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
if [ "$NON_INTERACTIVE" = 1 ]
then
echo "$@" | grep -vqe "--without-flexnet"
else
whiptail --title "URONode Options:" --yesno "Support FlexNet?" 7 22
fi
if [ $? -ne 1 ]
then
HAVEAX25="#define HAVE_AX25 1"
HAVEFLEX="#define HAVE_FLEX 1"
FLEXNET="flexd"
IN=""
fi
#
# echo -n "Include support for the NetRom protocol ? [Y/n]: "; read answer
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
if [ "$NON_INTERACTIVE" = 1 ]
then
echo "$@" | grep -vqe "--without-netrom"
else
whiptail --title "URONode Options:" --yesno "Support NetRom?" 7 22
fi
if [ $? -ne 1 ]
then
HAVEAX25="#define HAVE_AX25 1"
HAVENETROM="#define HAVE_NETROM 1"
fi
#
# echo -n "Include support for the Rose protocol ? [Y/n]: "; read answer
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
if [ "$NON_INTERACTIVE" = 1 ]
then
echo "$@" | grep -vqe "--without-rose"
else
whiptail --title "URONode Options:" --yesno "Support ROSE?" 7 22
fi
if [ $? -ne 1 ]
then
HAVEAX25="#define HAVE_AX25 1"
HAVEROSE="#define HAVE_ROSE 1"
fi
#
# echo -n "Include support for MHeard ports listen ? [Y/n]: "; read answer
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
if [ "$NON_INTERACTIVE" = 1 ]
then
echo "$@" | grep -vqe "--without-mheard"
else
whiptail --title "URONode Options:" --yesno "Support MHeard?" 7 22
fi
if [ $? -ne 1 ]
then
HAVEAX25="#define HAVE_AX25 1"
HAVEMHEARD="#define HAVE_MHEARD 1"
fi
#
# echo -n "Include support for TCP/IP functions ? [Y/n]: "; read answer
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
if [ "$NON_INTERACTIVE" = 1 ]
then
echo "$@" | grep -vqe "--without-tcpip"
else
whiptail --title "URONode Options:" --yesno "Support TCP/IP?" 7 22
fi
if [ $? -ne 1 ]
then
HAVETCPIP="#define HAVE_TCPIP 1"
HAVEMOTD="#define HAVEMOTD"
MOTDPATH='"/etc/ax25/uronode.motd"'
fi
echo "Creating Makefile"
sed -e "s~@FLEXNET@~$FLEXNET~g; \
s~@IN@~$IN~g" <Makefile.in > Makefile
echo "Creating Makefile.include"
sed -e "s~@ARCH@~$ARCH~g; \
s~@ETC_DIR@~$ETC_DIR~g; \
s~@LIB_DIR@~$LIB_DIR~g; \
s~@SBIN_DIR@~$SBIN_DIR~g; \
s~@BIN_DIR@~$BIN_DIR~g; \
s~@VAR_DIR@~$VAR_DIR~g; \
s~@MAN_DIR@~$MAN_DIR~g; \
s~@ZLIB@~$ZLIB~g" <Makefile.include.in >Makefile.include
echo "Creating config.h"
sed -e "s~@ETC_DIR@~$ETC_DIR~g; \
s~@LIB_DIR@~$LIB_DIR~g; \
s~@SBIN_DIR@~$SBIN_DIR~g; \
s~@BIN_DIR@~$BIN_DIR~g; \
s~@VAR_DIR@~$VAR_DIR~g; \
s~@MAN_DIR@~$MAN_DIR~g; \
s~@HAVEAX25@~$HAVEAX25~g; \
s~@HAVEFLEX@~$HAVEFLEX~g; \
s~@HAVENETROM@~$HAVENETROM~g; \
s~@HAVEROSE@~$HAVEROSE~g; \
s~@HAVEMHEARD@~$HAVEMHEARD~g; \
s~@HAVETCPIP@~$HAVETCPIP~g; \
s~@HAVEMOTD@~$HAVEMOTD~g; \
s~@MOTDPATH@~$MOTDPATH~g; \
s~@HAVEZLIB@~$HAVEZLIB~g" <config.h.in >config.h
echo "Creating dependancy files..."
make depend > /dev/null 2>&1
echo "Configuration successful!!"
_sleep 1
echo "about the authors..."
_sleep 3
echo "URONode is a combined effort of years worth of work. Those who's code"
echo "is included in this flavor of a linux based node are:"
_sleep 1
echo "Brian Rogers N1URO (current maintainer), "
_sleep 1
echo "Marius Petrescu YO2LOJ (current team member),"
_sleep 1
echo "Bob Tenty VE3TOK (current team member),"
_sleep 1
echo "Stefano Noferi IZ5AWZ (AWZNode)"
_sleep 1
echo -n "Tomi Manninen OH2BNS, "
_sleep 1
echo -n "Alan Cox GW4PTS, "
_sleep 1
echo "and Roy Van Zundert PE1RJA"
echo ""
_sleep 1
echo "Special thanks to: Morgan, sm6tky for his security report"
echo "and Barry K2MF for his input on some of my routines and supplying"
echo "some source code."
_sleep 1
echo ""
#echo -n "Shall I run the make command for you ? [Y/n]: "
_whiptail --title "Shall I make URONode?" --yesno "Yes to make or No to exit" 7 30
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
if [ "$NON_INTERACTIVE" != 1 -a $? -ne 1 ]
then
# echo "Making URONode! Please be patient."
# _sleep 1
# echo "compile errors will be in make.debug."
# echo ""
# _sleep 1
# echo "You may not see anything until the process is complete..."
_whiptail --title "Making URONODE..." --msgbox "Making. Check make.debug for errors. Hit OK to continue. You may not see anything for a minute..." 10 45
make >> make.debug
echo "let's check for binary errors..."
_sleep 1
echo -n "nodeusers: "
_sleep 1
if [ -x ./nodeusers ]; then
echo "SUCCESS!"
else
echo "FAILED!"
fi
_sleep 1
echo -n "uronode: "
_sleep 1
if [ -x ./uronode ]; then
echo "SUCCESS!"
else
echo "FAILED!"
fi
_sleep 1
echo -n "axdigi: "
_sleep 1
if [ -x ./axdigi ]; then
echo "SUCCESS!"
fi
_sleep 1
echo -n "flexd: "
_sleep 1
if [ -x ./flexd ]; then
echo "SUCCESS!"
_sleep 1
else
echo "FAILED! - perhaps you didn't want flexnet?"
echo "This is not an error if you chose NO to flexnet."
echo "This only means the flexnet daemon binary was not found."
echo ""
echo "Process complete!"
echo ""
fi
_sleep 1
_whiptail --title "URONode" --msgbox "Check the file make.debug if you had errors. If no errors, type: make install (new install) or make upgrade (existing install) and edit your files in /usr/local/etc/ax25/\n\n**WARNING: if you haven't already, add the following to your startup scripts:\n/usr/local/sbin/axdigi & \nto insure cross-port digipeating.\n\nFor help and release news join the forum at\nhttps://www.n1uro.net/forum\n\nEnjoy URONode - 73 de Brian N1URO" 20 50
# echo "Check the file make.debug if you had errors."
# echo "If no errors, type: make install or make upgrade"
# echo "and edit your files in /etc/ax25/"
# echo "**WARNING: if you haven't already, add the following to your"
# echo "startup scripts:"
# echo "/usr/sbin/axdigi &"
# echo "to insure cross-port digipeating."
# echo ""
# echo "For support and release news join the forum"
# echo "at https://www.n1uro.net/forum"
# echo ""
# echo "Enjoy URONode! 73 de N1URO."
fi
exit 0

20
etc/axdigi.conf Normal file
View File

@ -0,0 +1,20 @@
# URONode axdigi module
# load using /usr/sbin/axdigi &
#
#print debuginfo on/off
Debug off
#
#The digi call
MyCall xx0xx
#
# on use ssid 0-15 for digicall ,off use only ssid of mycall
IgnoreSSID on
#
#number of entrys for autorouting
lookupsize 100
#
#timeout auto routing data in sec.
TIMEOUT 3600
#
DefaultPort ln.tue
#

14
etc/flexd.conf Normal file
View File

@ -0,0 +1,14 @@
# /etc/ax25/flexd.conf URONode example configuration file
# see man flexd.conf
# The callsign-ssid you wish to poll your flex neighbor with:
MyCall xx0xx
# How often do we poll our flex neighbor (in seconds):
PollInterval 300
# The FlexNet node we're to poll:
FlexGate xx0xx-#

0
etc/gateways Normal file
View File

6
etc/help/bye.hlp Normal file
View File

@ -0,0 +1,6 @@
USAGE
Bye
DESCRIPTION
Disconnects you from this node.

18
etc/help/color.hlp Normal file
View File

@ -0,0 +1,18 @@
USAGE
<none>
DESCRIPTION
Adds ANSI color to the system for you. Send a message to
the sysop and request that they add 512 to your permissions
flag for the interface(s) you connect in from to get the
color schema. You *must* use an ANSI compliant terminal such
as Qmodem, Telix, telnet, etc.
Interfaces available: Schema:
ax25 ax25 - yellow
netrom netrom - cyan
internet internet- magenta
amprnet system - white
localhost starts - green
stops - red
alarms - flashing red

25
etc/help/connect.hlp Normal file
View File

@ -0,0 +1,25 @@
USAGE
Connect <call | alias> [s|d] For NET/ROM or Links
Connect <intf> <call> [via <digi1> ...] [s|d] For AX25
Connect <call> <address> [<digi>] [d|s] For ROSE
Connect <destination> [s|d] For FlexNet
DESCRIPTION
Initiates an AX25, NET/ROM, ROSE or Flexnet 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 AX25 is used
to make the connection via that port. If only one parameter
is given the connection is made searching for the callsign
in NET/ROM nodes, in AX25 Fixed links, in FlexNet destinations
and last in Mheard database in this order.
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 depends
on how the user connects in:
NetRom - defaults to disconnect
all others - defaults to reconnect

14
etc/help/desti.hlp Normal file
View File

@ -0,0 +1,14 @@
USAGE
Dest [*|<nodecall>]
DESCRIPTION
Shows the FlexNet destination table of the local node. The
destinations 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
ssid mask, the round-trip-time and the path used to reach each
node. You can also specify a node callsign to get the verbose
information for a single node.

16
etc/help/escape.hlp Normal file
View File

@ -0,0 +1,16 @@
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!)
-1 to disable this feature

13
etc/help/finger.hlp Normal file
View File

@ -0,0 +1,13 @@
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 @aripisa.ampr.org
finger iz5awz@aripisa.ampr.org
finger iz5awz

10
etc/help/help.hlp Normal file
View File

@ -0,0 +1,10 @@
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,
except for the COLOR command which you need to contact your
sysop to add. "Help color" to see about the color schema.

11
etc/help/host.hlp Normal file
View File

@ -0,0 +1,11 @@
USAGE
Host <hostname>|<ip address>
DESCRIPTION
Tells information about an Internet host. The host can be identified
using a host name (for example, aripisa.ampr.org) or an IP
address (for example, 44.134.208.29).
Returns the host name, IP addresses and known aliases for the host.
The information is gathered from the DNS (domain name service).

8
etc/help/info.hlp Normal file
View File

@ -0,0 +1,8 @@
USAGE
Info
DESCRIPTION
Displays the version information and the contents of the
/etc/ax25/uronode.info file, which describes those aspects of
the system that the sysop likes to brag about.

16
etc/help/links.hlp Normal file
View File

@ -0,0 +1,16 @@
USAGE
Links [ d | n | v | <call>]
DESCRIPTION
Shows the AX25 link table of the local node. The destinations
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 d show the AX25 nodes directly linked.
The optional parameter n show the AX25 nodes linked connecting
another node and passing a string type "C XX0XX".
The optional parameter v show the AX25 links via digipeaters.
You can also specify a destination callsign to get the verbose
information for a single destination.

12
etc/help/mail.hlp Normal file
View File

@ -0,0 +1,12 @@
USAGE
Mail
DESCRIPTION
Access your mailbox and send mail to other users
if you have mail waiting.
(only available for sysops and some users).
Note: this feature is initially disabled, contact the sysop
if you like to have it enabled.

14
etc/help/message.hlp Normal file
View File

@ -0,0 +1,14 @@
USAGE
MEssage <callsign or user@domain>
DESCRIPTION
Send email to users (now only available for messages to sysop).
Note: sysop has to enable your mail flag for you to be able to
receive mail, otherwise you may only send from here.
*Sysop Note: use your adduser or userconf program and create
the users account as well as adding the mail flag to the
configuration file. Select: /bin/false for a shell.

8
etc/help/mheard.hlp Normal file
View File

@ -0,0 +1,8 @@
USAGE
Mheard [<port>]
DESCRIPTION
Gives a list of heard AX25 stations on all ports and, if
specified, on the specified port.
Use the "Ports" command to get a list of available ports.

15
etc/help/msg.hlp Normal file
View File

@ -0,0 +1,15 @@
USAGE
MSg <call> <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
msg k2mf Hello, Bawee!

7
etc/help/netstat.hlp Normal file
View File

@ -0,0 +1,7 @@
USAGE
NEtstat
DESCRIPTION
Gives a list of active TCP/IP connections to and from the local
host.

15
etc/help/nodes.hlp Normal file
View File

@ -0,0 +1,15 @@
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.

15
etc/help/ping.hlp Normal file
View File

@ -0,0 +1,15 @@
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 aripisa.ampr.org

12
etc/help/ports.hlp Normal file
View File

@ -0,0 +1,12 @@
USAGE
Ports
DESCRIPTION
Shows the available AX25 ports. Shown are the port name, a short
description for the port, the number of sessions via the port (qso)
and the number received and transmitted packets via the port.
The port name is used when using the Connect command to connect
to an user or service not running NET/ROM or FlexNet (eg. not visible
in the Nodes and Destinations lists). The port name is also visible
in the Route, MHeard and MSession lists.

6
etc/help/quit.hlp Normal file
View File

@ -0,0 +1,6 @@
USAGE
Quit
DESCRIPTION
Disconnects you from this node.

2
etc/help/rose.hlp Normal file
View File

@ -0,0 +1,2 @@
<enter your rose routes here. Ex:>
c n1uro-8 3100860906

16
etc/help/routes.hlp Normal file
View File

@ -0,0 +1,16 @@
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 AX25 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
QSO - Number of NET/ROM session enties

10
etc/help/sessions.hlp Normal file
View File

@ -0,0 +1,10 @@
USAGE
SEssions [* | <call>]
DESCRIPTION
Gives a list of active AX25 and NET/ROM connections to and
from the local host. With an asterisk (*) as an argument
shows also AX25 and NET/ROM sockets in listening state. With
a callsign as an argument gives a list of all connections with
either source or destination callsign <call>.

14
etc/help/status.hlp Normal file
View File

@ -0,0 +1,14 @@
USAGE
STatus
DESCRIPTION
Returns information about the status of the Linux system which this
URONode 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.

26
etc/help/telnet.hlp Normal file
View File

@ -0,0 +1,26 @@
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.
This is only valid if the user connects into your node via
NetRom, otherwise the user is automatically reconnected to
the node.
EXAMPLES
telnet aripisa.ampr.org
telnet aripisa.ampr.org 1024
telnet 44.134.208.29 s
telnet 44.88.0.9 23 s

8
etc/help/users.hlp Normal file
View File

@ -0,0 +1,8 @@
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.

6
etc/help/version.hlp Normal file
View File

@ -0,0 +1,6 @@
USAGE
Version
DESCRIPTION
Displays the software version information,

8
etc/help/who.hlp Normal file
View File

@ -0,0 +1,8 @@
USAGE
Who (<call> | *)
DESCRIPTION
Shows a list when the user with the callsign <call> last
connected to this node. Use the asterisk to print out
the entire log table.

23
etc/help/zconnect.hlp Normal file
View File

@ -0,0 +1,23 @@
USAGE
ZConnect <call | alias> [s|d] For NET/ROM or Links
ZConnect <port> <call> [via <digi1> ...] [s|d] For AX25
ZConnect <call> <address> [<digi>] [d|s] For ROSE
ZConnect <destination> [s|d] For FlexNet
DESCRIPTION
Compresses an AX25, NET/ROM, ROSE or Flexnet 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 AX25 is used
to make the connection via that port. If only one parameter
is given the connection is made searching for the callsign
in NET/ROM nodes, in AX25 Fixed links, in FlexNet destinations
and last in Mheard database in this order.
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.

25
etc/help/ztelnet.hlp Normal file
View File

@ -0,0 +1,25 @@
USAGE
ZTelnet <host> [<port>] [s|d]
DESCRIPTION
Compresses 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
ztelnet aripisa.ampr.org
ztelnet aripisa.ampr.org 1024
ztelnet 44.134.208.29

0
etc/lastlog Normal file
View File

0
etc/loggedin Normal file
View File

89
etc/uronode.conf Normal file
View File

@ -0,0 +1,89 @@
# /etc/ax25/uronode.conf - URONode example configuration file
#
# see uronode.conf(5)
# Idle timeout (seconds).
# This is how long we hold onto a dead link. 0 disables (this is NOT
# recommended! Time is in seconds.
IdleTimeout 900
# Timeout when gatewaying (seconds).
# This (in seconds) is a keep-alive for dead connects out of the node.
ConnTimeout 600
# Visible hostname. Will be shown at telnet login.
# set this to your ampr.org hostname.
HostName xx#xx.ampr.org
# SysOp email address
# Set this to your email address - preferred to use an ampr.org email.
Email <your@email.ampr.org>
# "Local" network.
# This is your local amprnet subnet in full. Do NOT use 44.0.0.0/8!
LocalNet 44.0.0.0/32
# Command aliases. See uronode.conf(5) for the meaning of the uppercase
# letters in the name of the alias. Examples below:
Alias CAllbook "telnet %{3:144.167.99.66} 2000 %1 s"
Alias CONVers "telnet %{2:44.88.0.9} 3600 \"/n %u %{1:1}\""
Alias DXCluster "connect dxnet"
Alias Quit "bye"
Alias WX "telnet %{3:38.102.137.140} %1 s"
# Hidden ports.
# List interfaces you wish not to display. Not suggested.
#HiddenPorts inet
# External commands. See uronode.conf(5) for the meaning of the uppercase
# letters in the name of the extcmd.
#
# Flags: 1 Run command through pipe
# 2 Reconnected flag
# 3 Run through pipe and reconnect
#
ExtCmd NEstat 1 nobody /bin/netstat netstat --inet
#ExtCmd PMS 1 root /usr/sbin/pms pms -u %U -o XX0XX
# Node ID.
# This displays before all output texts when the user connects into
# your node via NetRom. Set to "" to leave blank.
# Note: This -must- be defined or will display as "(null)". A space
# is hardcoded in. Example: UROHUB:N1URO-2 do NOT add the bracket
# afterwards "}" this is predefined in URONode.
#
NodeId XXXXXX:XX#XX-#
# Ax25/Flex ID.
# This displays before some strings and at logout to the end user when
# they connect in via ax25 as defined in your ax25d.conf file. If
# you don't define this "(null)" will be presented to the end user. Its
# suggested you take this from your ax25d config which either faces a
# flexnet system OR your 2-meter user interface. Note: do NOT make this
# ssid the same as your NetRom SSID here or in ax25d.conf.
FlexId XX#XX-#
# ROSE ssid@network - if none, enter in: none.
RoseId XX#XX-#@####,######
# Netrom port name. This port is used for outgoing netrom connects.
NrPort nr0
# Syslog Logging level - suggest leaving this at 3 for debugging. 0
# halts logging.
LogLevel 3
# The default escape character (CTRL-T)
#
EscapeChar ^T

3
etc/uronode.info Normal file
View File

@ -0,0 +1,3 @@
This is a new system running URONode.
*** please edit /etc/ax25/uronode.info to change this text to display
information about your system.

4
etc/uronode.motd Normal file
View File

@ -0,0 +1,4 @@
This is copy of URONode is located in <town>,
<county>, <state/province> [XX##xx] (grid)
Type "?" for commands or H <command> for more detailed help on a command.
*** please edit /etc/ax25/uronode.motd to change this text

26
etc/uronode.perms Normal file
View File

@ -0,0 +1,26 @@
# /etc/ax25/uronode.perms - URONode example permissions file
#
# see uronode.perms(5)
#
# Note: The flags have been changed as of 2014/08/23
#
# user type port passwd perms
# User oh2bns can login without password from anywhere else but 'inet'.
#
#xx0xx inet * qwerty 95
#xx0xx * * * 95
n1uro * * * 255
# OH2RBI is a bbs so it needs escape disabled.
#
#xx0xx * * * 287
# Default permissions per connection type.
#
* ax25 * * 31
* netrom * * 31
* local * * 31
* ampr * * 31
* inet * * 0
* host * * 31

21
etc/uronode.routes Normal file
View File

@ -0,0 +1,21 @@
# /etc/ax25/uronode.routes URONode example configuration file
# This is used for quick ax25 connects so users need not add an interface
# when making a connect. You also need a statement in here for flexd to
# poll your flexnet neighbor.
# URONode shows links with this order. Examples below:
# Direct Routing
# route <call> <alias> <port> d 'description'
#
#route n1uro-1 fxuro ax0 d 'N1URO FlexNet Hub'
# Routing across another node with sending a string "C <call>"
# route <call> <alias> <port> n 'description' <node>
#
#route n1uro-14 WMASS ax0 n 'N1URO-NOS' n1uro-1
# Routing via digipeaters
# route <call> <alias> <port> v 'description' <digipeaters>
#
#route n1uro-9 MACTFX ax0 v 'N1URO Xnet' n1uro-1

6
etc/uronode.users Normal file
View File

@ -0,0 +1,6 @@
# /etc/ax25/uronode.users URONode example configuration file
# Shell access for Sysop users
# callsign:password:local linux username:shell
# xx#xx:password:xx#xx:shell
# yy#yy:password:thomas:shell

203
extcmd.c Normal file
View File

@ -0,0 +1,203 @@
#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 <netax25/ax25.h>
#include <netrose/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 */
#ifdef HAVEMOTD
#define ECMD_RECONN 2 /* */
#endif
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);
}
#ifdef HAVEMOTD
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} ", NodeId);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;31mWelcome back.\e[0m");
} else {
axio_printf(NodeIo, "Welcome back.");
}
} else if (User.ul_type == AF_INET) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[01;31m");
}
axio_printf(NodeIo, "Returning you to the shell... ");
} else if (User.ul_type == AF_AX25) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;31m");
}
axio_printf(NodeIo,"Welcome back to %s.", FlexId);
} else if (User.ul_type == AF_ROSE) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;31m");
}
axio_printf(NodeIo,"Back to %s", RoseId);
}
#endif
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);
#ifdef HAVEMOTD
if (cmdp->flags & ECMD_RECONN) {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} Welcome back.", NodeId);
}
}
else if (User.ul_type == AF_AX25) {
/* axio_printf(NodeIo, "Welcome back to %s.", FlexId); */
}
if (User.ul_type == AF_NETROM) {
node_msg("");
}
#else
if (cmdp->flags)
node_logout("");
#endif
return ret;
}

431
flexd.c Normal file
View File

@ -0,0 +1,431 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netax25/ax25.h>
#include <netrose/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 <netax25/daemon.h>
#include "config.h"
#include "procinfo.h"
#define DEFAULT_POLL_TIME 600
#define MINIMUM_POLL_TIME 300
int poll_time=DEFAULT_POLL_TIME;
char flexgate[10]="\0";
char mycall[10]="\0";
struct ax_routes *gw;
int s;
void (*sigterm_defhnd)(int);
void read_conf(void)
{
FILE *fp, *fgt;
char buf[1024], line[1024], *cp;
int i=0,k;
char digipath[AX25_MAX_DIGIS*10];
if ((fp=fopen(FLEXD_CONF_FILE, "r")) == NULL) {
fprintf(stderr, "flexd config: Cannot open config file: %s\n", FLEXD_CONF_FILE);
exit(1);
}
if ((fgt=fopen(FLEX_GT_FILE, "w")) == NULL) {
fprintf(stderr, "flexd config: Cannot open flexnet gateways file: %s\n", FLEX_GT_FILE);
fclose(fp);
exit(1);
}
fputs("addr callsign dev digipeaters\n", fgt);
while(fgets(buf, sizeof(buf), fp)) {
if(*buf=='#' || *buf==' ') continue; /* comment line/empty line */
cp=strchr(buf, '#');
if (cp) *cp='\0';
cp=strtok(buf, " \t\n\r");
if(cp==NULL) continue; /* empty line */
if(strcasecmp(cp,"pollinterval")==0) { /* set poll interval */
cp=strtok(NULL, " \t\n\r");
if(cp==NULL) {
fprintf(stderr, "flexd config: PollInterval needs an argument\n");
fclose(fp);
fclose(fgt);
exit(1);
}
poll_time=safe_atoi(cp);
if (poll_time<MINIMUM_POLL_TIME) poll_time=MINIMUM_POLL_TIME;
}
if(strcasecmp(cp,"mycall")==0) { /* set connect call for download */
cp=strtok(NULL, " \t\n\r");
if(cp==NULL) {
fprintf(stderr, "flexd config: MyCall needs an argument\n");
fclose(fp);
fclose(fgt);
exit(1);
}
safe_strncpy(mycall, cp, 9);
}
if(strcasecmp(cp,"flexgate")==0) { /* set flexnet gateway */
cp=strtok(NULL, " \t\n\r");
if(cp==NULL) {
fprintf(stderr, "flexd config: FlexGate needs an argument\n");
fclose(fp);
fclose(fgt);
exit(1);
}
safe_strncpy(flexgate, cp, 9);
gw=find_route(flexgate, NULL);
if (gw==NULL) {
fprintf(stderr, "flexd config: FlexGate %s not found in route file: %s\n", flexgate, AX_ROUTES_FILE);
fclose(fp);
fclose(fgt);
exit(1);
} else {
*digipath='\0';
for(k=0;k<AX25_MAX_DIGIS;k++) {
if (gw->digis[k]==NULL) break;
strcat(digipath," ");
strcat(digipath, gw->digis[k]);
}
sprintf(line, "%05d %-8s %4s %s\n", i++, gw->dest_call, ax25_config_get_dev(gw->dev), digipath);
fputs(line, fgt);
}
}
}
fclose(fgt);
fclose(fp);
}
int download_dest(char *gateway, char *fname)
{
FILE *tmp;
char buffer[1024], port[14], path[AX25_MAX_DIGIS*10];
char *addr, *commands[10], *dlist[9]; /* Destination + 8 digipeaters */
fd_set read_fd;
int n, addrlen, cmd_send=0, cmd_ack=0, c, k;
struct full_sockaddr_ax25 axbind, axconnect;
struct timeval tv;
gw=find_route(gateway, NULL);
if (gw==NULL) {
fprintf(stderr, "flexd connect: FlexGate %s not found in route file: %s\n", gateway, AX_ROUTES_FILE);
return 1;
} else {
*path='\0';
for(k=0;k<AX25_MAX_DIGIS;k++) {
if (gw->digis[k][0]=='\0') dlist[k+1]=NULL;
else dlist[k+1]=gw->digis[k];
}
dlist[0]=gw->dest_call;
strcpy(port,gw->dev);
}
if ((addr = ax25_config_get_addr(port)) == NULL) {
sprintf(buffer, "flexd connect: invalid AX.25 port name - %s\r\n", port);
write(STDOUT_FILENO, buffer, strlen(buffer));
return 1;
}
/*
* Open the socket into the kernel.
*/
if ((s = socket(AF_AX25, SOCK_SEQPACKET, 0)) < 0) {
sprintf(buffer, "flexd connect: cannot open AX.25 socket, %s\r\n", strerror(errno));
write(STDOUT_FILENO, buffer, strlen(buffer));
return 1;
}
/*
* Set our AX.25 callsign and AX.25 port callsign accordingly.
*/
if (*mycall=='\0') sprintf(buffer, "%s %s", addr, addr);
else sprintf(buffer, "%s %s", mycall, addr);
ax25_aton(buffer, &axbind);
axbind.fsa_ax25.sax25_family = AF_AX25;
addrlen=sizeof(struct full_sockaddr_ax25);
if (bind(s, (struct sockaddr *)&axbind, addrlen) != 0) {
sprintf(buffer, "flexd connect: cannot bind AX.25 socket, %s\r\n", strerror(errno));
write(STDOUT_FILENO, buffer, strlen(buffer));
close(s);
return 1;
}
/*
* Lets try and connect to the far end.
*/
addrlen=sizeof(struct full_sockaddr_ax25);
axconnect.fsa_ax25.sax25_family = AF_AX25;
if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
sprintf(buffer, "flexd connect: fcntl on socket: %s\r\n", strerror(errno));
write(STDOUT_FILENO, buffer, strlen(buffer));
close(s);
return 1;
}
if (ax25_aton_arglist((const char **)dlist, &axconnect) == -1) {
sprintf(buffer, "flexd connect: invalid destination callsign or digipeater\r\n");
write(STDOUT_FILENO, buffer, strlen(buffer));
close(s);
return 1;
}
if (connect(s, (struct sockaddr *)&axconnect, addrlen) == -1 && errno != EINPROGRESS) {
switch (errno) {
case ECONNREFUSED:
strcpy(buffer, "*** Connection refused - aborting\r\n");
break;
case ENETUNREACH:
strcpy(buffer, "*** No known route - aborting\r\n");
break;
case EINTR:
strcpy(buffer, "*** Connection timed out - aborting\r\n");
break;
default:
sprintf(buffer, "*** Cannot connect, %s\r\n", strerror(errno));
break;
}
write(STDOUT_FILENO, buffer, strlen(buffer));
close(s);
return 1;
}
while (1) {
FD_ZERO(&read_fd);
FD_SET(s, &read_fd);
tv.tv_sec=180;
tv.tv_usec=0;
k=select(s + 3, &read_fd, NULL, 0, &tv);
if (k<1) { /* error or timeout */
break;
}
if (FD_ISSET(s, &read_fd)) {
int ret, retlen;
char *cp;
/* See if we got connected or if this was an error */
getsockopt(s, SOL_SOCKET, SO_ERROR, &ret, &retlen);
if (ret != 0) {
cp = strdup(strerror(ret));
strlwr(cp);
sprintf(buffer, "flexd connect: Failure with %s: %sr\r\n", gateway, cp);
write(STDOUT_FILENO, buffer, strlen(buffer));
free(cp);
close(s);
return 1;
}
break;
}
}
commands[0]="d\r\n";
commands[1]="q\r\n";
commands[2]=NULL;
/*
* Loop until one end of the connection goes away.
*/
if ((tmp=fopen(fname, "w")) == NULL) {
fprintf(stderr, "flexd connect: Cannot open temporary file: %s\n", fname);
close(s);
return 1;
}
for (;;) {
FD_ZERO(&read_fd);
FD_SET(s, &read_fd);
tv.tv_sec=180;
tv.tv_usec=0;
k=select(s + 1, &read_fd, NULL, NULL, &tv);
if (k<1) { /* error or timeout */
break;
}
if (FD_ISSET(s, &read_fd)) {
if ((n = read(s, buffer, 512)) == -1) break;
for(c=0;c<n;c++) {
if (buffer[c]=='\r') buffer[c]='\n';
if (buffer[c]=='=' && c<n-1 && buffer[c+1]=='>') {
/* fprintf(stderr, "flex interact: ack[%d]\n", cmd_ack); */
cmd_ack++;
}
}
fwrite(buffer, sizeof(char), n, tmp);
}
if (cmd_ack!=0) {
if (commands[cmd_send]!=NULL) {
write(s, commands[cmd_send], 2);
/* fprintf(stderr, "flexd interact: send[%d]: %s\n", cmd_send, commands[cmd_send]); */
cmd_send++;
}
cmd_ack=0;
}
}
close(s);
fputs("\n",tmp);
fclose(tmp);
return 0;
}
int parse_dest(char *gateway, char *fname)
{
FILE *fdst, *tmp;
char *call, *ssid, *rtt, *cp, buf[1024], line[1024], ax[10];
int i=0;
if ((tmp=fopen(fname, "r")) == NULL) {
fprintf(stderr, "flexd update: Cannot open temporary file: %s\n", fname);
return 1;
}
if ((fdst=fopen(FLEX_DST_FILE, "w")) == NULL) {
fprintf(stderr, "flexd update: Cannot open flexnet destinations file: %s\n", FLEX_DST_FILE);
fclose(tmp);
return 1;
}
fputs("callsign ssid rtt gateway\n", fdst);
/* fprintf(fdst, "%s %s 0 00000\n", mygate, myrange); */
while(fgets(buf, sizeof(buf), tmp)) {
cp=strtok(buf, " \t\n\r");
if(cp==NULL) continue; /* empty line */
if(strstr(cp,"=>")) i++; /* system prompt */
if(i==0) continue; /* skip connect text */
if(*cp=='#' || *cp=='=' || *cp==' ' || *cp=='*' || *cp=='-' || *cp==':') continue; /* comment line/system prompt */
if(strncmp(cp,"73!",3)==0) continue; /* End greeting */
/* CALL SSID-ESID RTT */
do {
call=cp;
if (call==NULL) break;
if (strlen(call)>6) break;
if (strchr(call,'-')) break;
if (ax25_aton_entry(call,ax)!=0) break;
if (!ax25_validate(ax)) break;
ssid=strtok(NULL, " \t\n\r");
if (ssid==NULL) break;
if (!strchr(ssid,'-')) break;
rtt=strtok(NULL, " \t\n\r");
if (rtt==NULL) break;
if (atoi(rtt)==0) break;
sprintf(line, "%-8s %-5s %6d %05d\n", call, ssid, safe_atoi(rtt), 0);
fputs(line, fdst);
cp=strtok(NULL, " \t\n\r");
} while(cp!=NULL);
}
fclose(fdst);
fclose(tmp);
return 0;
}
int update_flex(void)
{
char fname[80];
sprintf(fname, "%s/.session.%s", FLEXD_TEMP_PATH, flexgate);
if (download_dest(flexgate, fname)==0) parse_dest(flexgate, fname);
remove(fname);
return 0;
}
void hup_handler(int sig)
{
signal(SIGHUP, SIG_IGN);
read_conf();
signal(SIGHUP, hup_handler); /* Restore hangup handler */
}
void alarm_handler(int sig)
{
signal(SIGALRM, SIG_IGN);
update_flex();
signal(SIGALRM, alarm_handler); /* Restore alarm handler */
alarm(poll_time);
}
void quit_handler(int sig)
{
signal(SIGTERM, SIG_IGN);
unlink(FLEXD_PID_FILE);
signal(SIGTERM, sigterm_defhnd);
raise(SIGTERM);
}
int main(int argc, char *argv[])
{
FILE *pidfile;
signal(SIGPIPE, SIG_IGN);
if (ax25_config_load_ports() == 0) {
fprintf(stderr, "flexd error: No AX25 port data configured\n");
return 1;
}
read_conf();
if (!daemon_start(TRUE)) {
fprintf(stderr, "flexd: cannot become a daemon\n");
return 1;
}
signal(SIGTERM, quit_handler);
pidfile = fopen(FLEXD_PID_FILE, "w");
fprintf(pidfile, "%d\n", (int)getpid());
fclose(pidfile);
update_flex();
signal(SIGHUP, hup_handler);
signal(SIGALRM, alarm_handler);
sigterm_defhnd = signal(SIGTERM, quit_handler);
if (sigterm_defhnd == SIG_ERR)
sigterm_defhnd = SIG_DFL;
alarm(poll_time);
for(;;) pause();
return 0;
}

1131
gateway.c Normal file

File diff suppressed because it is too large Load Diff

193
ipc.c Normal file
View File

@ -0,0 +1,193 @@
/* oringinal by Heikki Hannikainen, modified by Brian Rogers */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <netax25/ax25.h>
#include <netrose/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"
#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("%s", buf.mtext);
if (User.ul_type != AF_NETROM) {
node_prompt();
}
if (User.ul_type == AF_NETROM) {
node_msg("");
}
axio_flush(NodeIo);
} else
node_log(LOGLVL_ERROR, "usr2_handler: Caught 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, S_IRWXU)) == -1) {
node_perror("ipc_send: Could not get transmit channel", errno);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
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);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return -1;
}
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
int ipc_open(void)
{
key_t key = FIRST_KEY;
do {
key++;
ipc_id = msgget(key, S_IRWXU | 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) {
node_log(LOGLVL_ERROR, "ipc_close: Could not remove IPC channel: %s", strerror(errno));
return -1;
} else {
node_log(LOGLVL_ERROR, "ipc_close: Removing IPC channel for %s", User.call);
}
return 0;
}
int do_msg(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: msg <call> <your text msg>");
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
return 0;
}
sprintf(mtext, "\n*** Msg from %s:\n\a", 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*** End of msg.", M_LEN - strlen(mtext));
mtext[M_LEN - 1] = 0;
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) {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} ", NodeId);
}
axio_printf(NodeIo, "%s is not on the node now.\a", call);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
} else if (sent == 0) {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} ", NodeId);
}
axio_printf(NodeIo, "%s is busy and not accepting msgs now.\a", call);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
} else if (sent != 0) {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} ", NodeId);
}
axio_printf(NodeIo, "Msg sent to %s.\a", call);
}
if (User.ul_type == AF_NETROM) {
node_msg("");
}
axio_flush(NodeIo);
return 0;
}

BIN
man/axdigi.8.gz Normal file

Binary file not shown.

BIN
man/flexd.conf.5.gz Normal file

Binary file not shown.

BIN
man/nodeusers.1.gz Normal file

Binary file not shown.

BIN
man/uronode.8.gz Normal file

Binary file not shown.

BIN
man/uronode.conf.5.gz Normal file

Binary file not shown.

BIN
man/uronode.perms.5.gz Normal file

Binary file not shown.

151
mheard.c Normal file
View File

@ -0,0 +1,151 @@
/* Routine rewritten mainly by Barry K2MF (Mr. MFNOS) and Brian N1URO */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netax25/ax25.h>
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include <netax25/mheard.h>
#include "config.h" /* Bob VE3TOK 30Nov2014 */
#include "procinfo.h"
#include "node.h"
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 = NULL, *new, *tmp, *p;
char *s, *t, *u;
int mhcount = 0;
axio_puts("",NodeIo);
if(User.ul_type == AF_NETROM)
axio_printf(NodeIo,"%s} ",NodeId);
if(argc > 1) {
if(ax25_config_get_dev(argv[1]) == NULL
|| (check_perms(PERM_HIDDEN, 0) == -1
&& is_hidden(argv[1]))) {
axio_printf(NodeIo,"Invalid port: %s",argv[1]);
if(User.ul_type == AF_NETROM)
node_msg("");
return 0;
}
}
if((fp = fopen(DATA_MHEARD_FILE,"r")) == NULL) {
node_perror(DATA_MHEARD_FILE,errno);
return 0;
}
while(mhcount < 20 && fread(&mh,sizeof(struct mheard_struct),1,fp)
== 1) {
if(argc > 1) {
if(strcmp(argv[1],mh.portname))
continue;
}
if(check_perms(PERM_HIDDEN,0) == -1 && is_hidden(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;
} 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;
mhcount++;
}
fclose(fp);
if(check_perms(PERM_ANSI,0L) != -1)
axio_printf(NodeIo,"\e[01;33m");
node_msg("MHeard list:");
if(check_perms(PERM_ANSI,0L) != -1)
axio_printf(NodeIo,"\e[0;m");
axio_printf(NodeIo,"Callsign Device Packets Date & Time Frame Type(s)\n");
axio_printf(NodeIo,"--------- ------ -------- --------------- -------------");
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';
axio_printf(NodeIo,"\n%-9s %-6s %-8d %s",t,list->data.portname,list->data.count,s);
if(list->data.mode & MHEARD_MODE_ARP)
axio_printf(NodeIo," ARP");
if(list->data.mode & MHEARD_MODE_FLEXNET)
axio_printf(NodeIo," FlexNet");
if(list->data.mode & MHEARD_MODE_IP_DG)
axio_printf(NodeIo," IP-DG");
if(list->data.mode & MHEARD_MODE_IP_VC)
axio_printf(NodeIo," IP-VC");
if(list->data.mode & MHEARD_MODE_NETROM)
axio_printf(NodeIo," NetRom");
if(list->data.mode & MHEARD_MODE_ROSE)
axio_printf(NodeIo," Rose");
if(list->data.mode & MHEARD_MODE_SEGMENT)
axio_printf(NodeIo," Segment");
if(list->data.mode & MHEARD_MODE_TEXNET)
axio_printf(NodeIo," TexNet");
if(list->data.mode & MHEARD_MODE_TEXT)
axio_printf(NodeIo," Text");
if(list->data.mode & MHEARD_MODE_PSATFT)
axio_printf(NodeIo," PacsatFT");
if(list->data.mode & MHEARD_MODE_PSATPB)
axio_printf(NodeIo," PacsatPB");
if(list->data.mode & MHEARD_MODE_UNKNOWN)
axio_printf(NodeIo," Unknown");
tmp = list;
list = list->next;
free(tmp);
}
if(User.ul_type == AF_NETROM)
node_msg("");
return 0;
}

419
node.c Normal file
View File

@ -0,0 +1,419 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.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 <netax25/ax25.h>
#include <netrose/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;
int aliascmd = 0;
/*
* 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 alarm_handler(int sig)
{
axio_eolmode(NodeIo, EOLMODE_TEXT);
axio_puts("\n",NodeIo);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[05;31m");
}
if (User.ul_type == AF_NETROM) {
node_msg("%s} Inactivity timeout! Closing circuit... ", NodeId);
}
if ((User.ul_type == AF_AX25) || (User.ul_type == AF_ROSE)) {
node_msg("Inactivity timeout! Disconnecting you... ");
}
if (User.ul_type == AF_INET) {
node_msg("Inactivity timeout! Disconnecting you...");
}
if (User.ul_type == AF_INET) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[0;m");
}
}
node_logout("User timed out");
}
static void term_handler(int sig)
{
axio_eolmode(NodeIo, EOLMODE_TEXT);
if (User.ul_type == AF_NETROM) {
node_msg("%s} Termination received!", NodeId);
} else {
node_msg("%s - System going down! Disconnecting...", FlexId);
}
node_logout("SIGTERM");
}
static void quit_handler(int sig)
{
axio_eolmode(NodeIo, EOLMODE_TEXT);
node_logout("User terminated at remote");
}
int main(int argc, char *argv[])
{
union {
struct full_sockaddr_ax25 sax;
#ifdef HAVE_ROSE
struct sockaddr_rose srose;
#endif
struct sockaddr_in sin;
} saddr;
int i, slen = sizeof(saddr);
#ifdef HAVEMOTD
char *p, buf[256], *pw;
#else
char *p, *pw;
#endif
int paclen;
#ifdef HAVEMOTD
FILE *fp;
#endif
int invalid_cmds = 0;
int no_password = 2;
int first_time = 1;
signal(SIGALRM, alarm_handler);
signal(SIGTERM, term_handler);
signal(SIGPIPE, quit_handler);
signal(SIGQUIT, quit_handler);
#ifdef HAVE_AX25
if (ax25_config_load_ports() == 0) {
node_log(LOGLVL_ERROR, "No AX.25 port data configured");
return 1;
}
#endif
#ifdef HAVE_NETROM
nr_config_load_ports();
#endif
#ifdef HAVE_ROSE
rs_config_load_ports();
#endif
if (getpeername(STDOUT_FILENO, (struct sockaddr *)&saddr, &slen) == -1) {
if (errno != ENOTSOCK) {
node_log(LOGLVL_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_FLEXNET:
case AF_AX25:
strcpy(User.call, ax25_ntoa(&saddr.sax.fsa_ax25.sax25_call));
if (getsockname(STDOUT_FILENO, (struct sockaddr *)&saddr.sax, &slen) == -1) {
node_log(LOGLVL_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) {
node_log(LOGLVL_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;
#ifdef HAVE_ROSE
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;
#endif
case AF_INET:
case AF_INET6:
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) {
node_log(LOGLVL_ERROR, "No uid->callsign association found", -1);
printf("Launching: telnet localhost 3694 ...\n");
printf("if this fails please RTFM to see how to properly configure it.\n - 73 de N1URO\a\n");
node_log(LOGLVL_ERROR, "Tool ran me from the console so I'm forcing", -1);
node_log(LOGLVL_ERROR, "a telnet session to port 3694/tcp on them.", -1);
/* axio_flush(NodeIo); */
if(NodeIo!=NULL)
axio_flush(NodeIo);
if (system("telnet 127.0.0.1 3694") < 0 ) { /* VE3TOK - 18Nov2014, return value */
syslog(LOG_DEBUG, "Can't \"execute telnet 127.0.0.1 3694\"");
return 1;
}
node_log(LOGLVL_ERROR,"Closing console telnet session.", -1);
return -1;
}
strcpy(User.call, p);
paclen = 1024;
p = UNSPEC_EOL;
break;
default:
node_log(LOGLVL_ERROR, "Unsupported address family %d", User.ul_type);
return 1;
}
NodeIo = axio_init(STDIN_FILENO, STDOUT_FILENO, paclen, p);
if (NodeIo == NULL) {
node_log(LOGLVL_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;
}
for(i=1;i<argc;i++) {
if (strcmp(argv[i],"--delay")==0) {
axio_flush(NodeIo);
p = axio_getline(NodeIo);
}
}
User.state = STATE_LOGIN;
login_user();
if (User.call[0] == 0) {
axio_printf(NodeIo,"(%s:uronode) login: ", HostName);
axio_flush(NodeIo);
alarm(60L); /* 1 min timeout */
if ((p = axio_getline(NodeIo)) == NULL)
node_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("%s - Invalid callsign", FlexId);
node_log(LOGLVL_LOGIN, "Invalid callsign %s @ %s", User.call, User.ul_name);
node_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.");
node_log(LOGLVL_LOGIN, "Login denied for %s @ %s", User.call, User.ul_name);
node_logout("Login denied");
} else if (strcmp(pw, "*") != 0) {
node_msg("*** Password required! If you don't have a password please email\r\n%s for a password you wish to use.", Email);
axio_printf(NodeIo,"\rPassword: ");
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);
/* axio_puts("\n",NodeIo); */
}
if (p == NULL || strcmp(p, pw) != 0) {
axio_printf(NodeIo, "\n");
if (User.ul_type == AF_NETROM) {
node_msg("%s} Invalid or incorrect password...", NodeId);
} else {
node_msg("%s Invalid or incorrect password...", FlexId);
}
node_log(LOGLVL_LOGIN, "Login failed for %s @ %s", User.call, User.ul_name);
node_logout("Login failed");
}
no_password = 0;
};
free(pw);
examine_user();
ipc_open();
node_log(LOGLVL_LOGIN, "%s @ %s logged in", User.call, User.ul_name);
#ifdef HAVEMOTD
if (User.ul_type == AF_NETROM) {
/* axio_printf(NodeIo, "%s} Welcome.\n", NodeId); */
} else
if (User.ul_type == AF_INET) {
if (check_perms(PERM_ANSI, 0L) != -1) {
node_msg("\n\e[01;34m[\e[01;37m%s\e[01;34m]\e[0m\nWelcome %s to the %s packet shell.", VERSION, User.call, HostName);
} else if (check_perms(PERM_ANSI, 0L) == -1) {
node_msg("\n[%s]\nWelcome %s to the %s packet shell.", VERSION, User.call, HostName);
}
if ((fp = fopen(HAVEMOTD, "r")) != NULL) {
while (fgets(buf,256, fp) != NULL) axio_puts(buf,NodeIo);
axio_printf (NodeIo, "\n");
axio_flush(NodeIo);
}
} else if (User.ul_type == AF_AX25) {
if (check_perms(PERM_ANSI, 0L) != -1) {
node_msg("\e[01;34m[\e[01;37m%s\e[01;34m]\e[0m - Welcome to %s", VERSION, FlexId);
} else
node_msg("%s - Welcome to %s", VERSION, FlexId);
if ((fp = fopen(HAVEMOTD, "r")) != NULL) {
while (fgets(buf, 256, fp) != NULL) axio_puts(buf,NodeIo);
axio_puts ("\n",NodeIo);
axio_flush(NodeIo);
}
} else if (User.ul_type == AF_ROSE) {
node_msg("%s - Welcome to %s", VERSION, RoseId);
if ((fp = fopen(HAVEMOTD, "r")) != NULL) {
while (fgets(buf, 256, fp) != NULL) axio_puts(buf,NodeIo);
axio_puts ("\n",NodeIo);
axio_flush(NodeIo);
}
}
lastlog();
#endif
axio_flush(NodeIo);
while (1) { if (User.ul_type != AF_NETROM) {
axio_flush(NodeIo);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;34");
}
if (no_password == 2) {
node_prompt();
}
if (no_password == 1) {
node_prompt();
no_password = 2;
}
if (no_password == 0)
{
if (first_time == 1)
{
first_time = 0;
if (User.ul_type != AF_NETROM) {
/* node_prompt("3"); */
if ((User.ul_type == AF_AX25) || (User.ul_type == AF_ROSE)) {
node_prompt();
}
}
}
else if ((User.ul_type != AF_NETROM) && (User.ul_type != AF_ROSE)) {
node_prompt();
} else if ((User.ul_type == AF_NETROM) || (User.ul_type == AF_ROSE)) {
axio_printf(NodeIo,"\n");
}
}
}
if (check_perms(PERM_ANSI, 0L) != -1) {
/* Not needed from what I see so far. */
if (User.ul_type == AF_AX25) {
axio_printf(NodeIo,"\e[0m");
}
}
axio_flush(NodeIo);
User.state = STATE_IDLE;
time(&User.cmdtime);
update_user();
alarm(IdleTimeout);
errno = 0;
if ((p = axio_getline(NodeIo)) == NULL) {
if (errno == EINTR)
continue;
node_logout("User disconnected");
};
alarm(IdleTimeout);
errno = 0;
time(&User.cmdtime);
update_user();
aliascmd = 0;
switch (cmdparse(Nodecmds, p))
{
case -1:
if (++invalid_cmds < 3) {
/* node_msg("%s Unknown command. Type ? for a list", NodeId); */
if (User.ul_type == AF_NETROM) {
node_msg("What?\007");
} else if (User.ul_type == AF_ROSE) {
axio_printf(NodeIo,"Que?\007");
} else if (User.ul_type == AF_INET) {
axio_printf(NodeIo, "Huh?\007");
} else {
axio_printf(NodeIo,"Eh?\007");
}
node_log(LOGLVL_ERROR,"%s Tool tried bogus command", NodeId);
}
else {
if (User.ul_type == AF_NETROM) {
node_msg("%s Too many invalid commands. Disconnecting...", NodeId);
node_logout("Too many invalid commands");
} else {
node_msg("Too many invalid commands, disconnecting you...");
node_logout("Too many invalid commands");
}
}
break;
case 0:
invalid_cmds = 0;
/* axio_puts ("\n",NodeIo); */
break;
case 1:
invalid_cmds = 0;
break;
case 2:
invalid_cmds = 0;
break;
}
}
node_logout("Out of main loop !?!?!?");
}

172
node.h Normal file
View File

@ -0,0 +1,172 @@
#define VERSION "URONode v2.3.1"
#define COMPILING "February 14, 2015"
#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 STATE_QUIT 6
#define LOGLVL_NONE 0
#define LOGLVL_ERROR 1
#define LOGLVL_LOGIN 2
#define LOGLVL_GW 3
#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_ANSI 64 /* Ansi Color graphics */
#define PERM_ROSE 128 /* ROSE gatewaying */
#define PERM_NOESC 256 /* No escape character */
#define PERM_HIDDEN 512 /* Use hidden ports - to be removed */
#define PERM_TELNET (PERM_TELNET_LOCAL & PERM_TELNET_AMPR & PERM_TELNET_INET)
/* Fake id for Flexnet */
#define AF_FLEXNET 128
#include <sys/types.h>
#include <sys/ipc.h> /* for key_t */
#include <errno.h>
#include <netax25/ax25io.h>
#include "config.h"
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;
extern long IdleTimeout;
extern long ConnTimeout;
extern int ReConnectTo;
extern int LogLevel;
extern int EscChar;
extern int aliascmd;
extern char *Email;
extern char *HostName;
extern char *NodeId;
extern char *FlexId;
extern char *RoseId;
extern char *NrPort;
extern char *Prompt;
extern char *PassPrompt;
#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 void node_msg(const char *fmt, ...);
extern void node_perror(char *str, int err);
extern char *print_node(const char *alias, const char *call);
extern void node_log(int, const char *, ...);
/* in user.c */
extern void login_user(void);
extern void logout_user(void);
extern void update_user(void);
extern int user_list(int argc, char **argv);
extern int user_count(void);
extern int system_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 node_logout(char *reason);
extern int nuser_list(int argc, char **argv);
extern int do_bye(int argc, char **argv);
extern int do_escape(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_sessions(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);
extern int do_version(int argc, char **argv);
extern int do_last(int argc, char **last);
/* 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 router.c */
extern int do_links(int argc, char **argv);
extern int do_dest(int argc, char **argv);
/* in ipc.c */
extern int ipc_open(void);
extern int ipc_close(void);
extern int do_msg(int argc, char **argv);
/* in extcmd.c */
extern int extcmd(struct cmd *cmdp, char **argv);
/* in system.c */
extern int do_system(int argc, char **argv);
extern int examine_user(void);
extern void newmail(void);
extern void mailcheck(void);
extern void lastlog(void);
/* in mheard.c */
extern int do_mheard(int argc, char **argv);

82
nodeusers.c Normal file
View File

@ -0,0 +1,82 @@
#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 <netax25/ax25.h>
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include <netax25/procutils.h>
#include "node.h"
#include "config.h"
char *NodeId = "Nodeusers:";
int LogLevel = LOGLVL_NONE;
ax25io *NodeIo = NULL;
static void pipe_handler(int sig)
{
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;
int logging = 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 failes\r\n");
return 1;
}
if (inet && axio_getline(NodeIo) == NULL) {
if (logging)
syslog(LOG_ERR, "axio_getline: %m");
axio_printf(NodeIo,"\n");
axio_end(NodeIo);
return 1;
}
n = user_count();
axio_printf(NodeIo,"\n%s (%s), %d user%s.\n",
VERSION, COMPILING, n, n == 1 ? "" : "s");
user_list(0, NULL);
if (n > 0)
axio_printf(NodeIo,"\n");
if (axio_flush(NodeIo) == -1 && logging)
syslog(LOG_ERR, "axio_flush: %m");
axio_end(NodeIo);
usleep(500000L);
closelog();
return 0;
}

358
procinfo.c Normal file
View File

@ -0,0 +1,358 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netax25/ax25.h>
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include <netax25/mheard.h>
#include "procinfo.h"
#include "node.h"
/*
* Version of atoi() that returns zero if s == NULL.
*/
int safe_atoi(const char *s)
{
return (s == NULL) ? 0 : atoi(s);
}
/*
* Version of strncpy() that returns NULL if either src or dest is NULL
* and also makes sure destination string is always terminated.
*/
char *safe_strncpy(char *dest, char *src, int n)
{
if (dest == NULL || src == NULL) return NULL;
dest[n] = 0;
return strncpy(dest, src, n);
}
struct proc_dev *read_proc_dev(void)
{
FILE *fp;
char buffer[256];
struct proc_dev *p;
struct proc_dev *list = NULL;
int i = 0;
errno = 0;
if ((fp = fopen(PROC_DEV_FILE, "r")) == NULL) return NULL;
while (fgets(buffer, 256, fp) != NULL) {
if (i++<2) continue;
if ((p = calloc(1, sizeof(struct proc_dev))) == NULL) break;
safe_strncpy(p->interface, strtok(buffer, ":\n\r"), 6);
while (*p->interface==' ') strcpy(p->interface, p->interface+1);
p->rx_bytes = safe_atoi(strtok(NULL, " \t\n\r"));
p->rx_packets = safe_atoi(strtok(NULL, " \t\n\r"));
p->rx_errs = safe_atoi(strtok(NULL, " \t\n\r"));
p->rx_drop = safe_atoi(strtok(NULL, " \t\n\r"));
p->rx_fifo = safe_atoi(strtok(NULL, " \t\n\r"));
p->rx_frame = safe_atoi(strtok(NULL, " \t\n\r"));
p->rx_compressed = safe_atoi(strtok(NULL, " \t\n\r"));
p->rx_multicast = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_bytes = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_packets = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_errs = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_drop = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_fifo = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_colls = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_carrier = safe_atoi(strtok(NULL, " \t\n\r"));
p->tx_compressed = safe_atoi(strtok(NULL, " \t\n\r"));
p->next = list;
list = p;
}
fclose(fp);
return list;
}
void free_proc_dev(struct proc_dev *ap)
{
struct proc_dev *p;
while (ap != NULL) {
p = ap->next;
free(ap);
ap = p;
}
}
struct flex_gt *read_flex_gt(void)
{
FILE *fp;
char buffer[256], *cp;
struct flex_gt *p=NULL, *list = NULL, *new_el;
int i = 0, k;
errno = 0;
if ((fp = fopen(FLEX_GT_FILE, "r")) == NULL) return NULL;
while (fgets(buffer, 256, fp) != NULL) {
if (i++<1) continue;
if ((new_el = calloc(1, sizeof(struct flex_gt))) == NULL) break;
new_el->addr = safe_atoi(strtok(buffer, " \t\n\r"));
safe_strncpy(new_el->call, strtok(NULL, " \t\n\r"), 9);
safe_strncpy(new_el->dev, strtok(NULL, " \t\n\r"), 4);
k=0;
while((cp=strtok(NULL, " \t\n\r"))!=NULL&&k<AX25_MAX_DIGIS) safe_strncpy(new_el->digis[k++],cp,9);
while(k<AX25_MAX_DIGIS) strcpy(new_el->digis[k++],"\0");
if(list==NULL) {
list=new_el;
p=list;
} else {
p->next = new_el;
p=p->next;
}
}
fclose(fp);
return list;
}
void free_flex_gt(struct flex_gt *fp)
{
struct flex_gt *p;
while (fp != NULL) {
p = fp->next;
free(fp);
fp = p;
}
}
struct flex_dst *read_flex_dst(void)
{
FILE *fp;
char buffer[256];
struct flex_dst *p=NULL, *list = NULL, *new_el;
int i = 0;
errno = 0;
if ((fp = fopen(FLEX_DST_FILE, "r")) == NULL) return NULL;
while (fgets(buffer, 256, fp) != NULL) {
if (i++<1) continue;
if ((new_el = calloc(1, sizeof(struct flex_dst))) == NULL) break;
safe_strncpy(new_el->dest_call, strtok(buffer, " \t\n\r"), 9);
new_el->ssida = safe_atoi(strtok(NULL, " -\t\n\r"));
new_el->sside = safe_atoi(strtok(NULL, " -\t\n\r"));
new_el->rtt = safe_atoi(strtok(NULL, " \t\n\r"));
new_el->addr = safe_atoi(strtok(NULL, " \t\n\r"));
if(list==NULL) {
list=new_el;
p=list;
} else {
p->next = new_el;
p=p->next;
}
}
fclose(fp);
return list;
}
void free_flex_dst(struct flex_dst *fp)
{
struct flex_dst *p;
while (fp != NULL) {
p = fp->next;
free(fp);
fp = p;
}
}
struct ax_routes *read_ax_routes(void)
{
FILE *fp;
char buffer[256], *cp, *cmd;
struct ax_routes *p=NULL, *list = NULL, *new_el;
int i = 0, k;
errno = 0;
if ((fp = fopen(AX_ROUTES_FILE, "r")) == NULL) return NULL;
while (fgets(buffer, 256, fp) != NULL) {
if (i++<1) continue;
if(*buffer=='#' || *buffer==' ' ) continue; /* commented line */
cp=strchr(buffer, '#'); /* ignore comments */
if (cp) *cp='\0';
cmd=strtok(buffer, " \t\n\r");
if(cmd==NULL) continue; /* empty line */
if (strcasecmp(cmd,"route")==0) { /* add route */
if ((new_el = calloc(1, sizeof(struct ax_routes))) == NULL) break;
safe_strncpy(new_el->dest_call, strupr(strtok(NULL, " \t\n\r")), 9);
safe_strncpy(new_el->alias, strupr(strtok(NULL, " \t\n\r")), 9);
safe_strncpy(new_el->dev, strtok(NULL, " \t\n\r"), 13);
safe_strncpy(new_el->conn_type, strupr(strtok(NULL, " \t\n\r")), 1);
safe_strncpy(new_el->description, strtok(NULL, "'\t\n\r"), 50);
if (new_el->description==NULL) strcpy(new_el->description," ");
switch(*new_el->conn_type) {
case CONN_TYPE_DIRECT:
{
break;
}
case CONN_TYPE_NODE:
{
safe_strncpy(new_el->digis[0], strupr(strtok(NULL, " \t\n\r")), 9);
break;
}
case CONN_TYPE_DIGI:
{
k=0;
while((cp=strtok(NULL, " \t\n\r"))!=NULL&&k<AX25_MAX_DIGIS)
safe_strncpy(new_el->digis[k++],strupr(cp),9);
while(k<AX25_MAX_DIGIS) strcpy(new_el->digis[k++],"\0");
break;
}
default:
{
return NULL;
break;
}
}
if(list==NULL) {
list=new_el;
p=list;
} else {
p->next = new_el;
p=p->next;
}
}
}
fclose(fp);
return list;
}
void free_ax_routes(struct ax_routes *ap)
{
struct ax_routes *p;
while (ap != NULL) {
p = ap->next;
free(ap);
ap = p;
}
}
struct ax_routes *find_route(char *dest_call, struct ax_routes *list)
{
static struct ax_routes a;
struct ax_routes *axrt=NULL, *p;
char *cp, call[10];
safe_strncpy(call,dest_call,9);
if ((cp = strchr(call, '-')) != NULL && *(cp + 1) == '0') *cp = 0;
axrt=list?list:read_ax_routes();
for (p=axrt;p!=NULL;p=p->next) {
if (!strcasecmp(call, p->dest_call)) {
a = *p;
a.next = NULL;
p = &a;
break;
}
if (!strcasecmp(call, p->alias)) {
a = *p;
a.next = NULL;
p = &a;
break;
}
}
if (list==NULL) free_ax_routes(axrt);
return p;
}
struct flex_dst *find_dest(char *dest_call, struct flex_dst *list)
{
static struct flex_dst f;
struct flex_dst *fdst=NULL, *p;
char *cp, call[10];
int ssid;
safe_strncpy(call, dest_call, 9);
cp=strchr(call,'-');
if (cp==NULL) ssid=0;
else {
ssid=safe_atoi(cp+1);
*cp='\0';
}
fdst=list?list:read_flex_dst();
for (p=fdst;p!=NULL;p=p->next) {
if (!strcasecmp(call, p->dest_call) && (ssid>=p->ssida && ssid<=p->sside)) {
f = *p;
f.next = NULL;
p = &f;
break;
}
}
if (list==NULL) free_flex_dst(fdst);
return p;
}
struct flex_gt *find_gateway(int addr, struct flex_gt *list)
{
static struct flex_gt f;
struct flex_gt *flgt=NULL, *p;
flgt=list?list:read_flex_gt();
for (p=flgt;p!=NULL;p=p->next) {
if (addr==p->addr) {
f = *p;
f.next = NULL;
p = &f;
break;
}
}
if (list==NULL) free_flex_gt(flgt);
return p;
}
struct ax_routes *find_mheard(char *dest_call)
{
FILE *fp;
static struct ax_routes a;
struct mheard_struct mh;
char call[12];
char *cp;
int k;
if ((fp = fopen(DATA_MHEARD_FILE, "r")) == NULL) {
return NULL;
}
safe_strncpy(call,dest_call,9);
cp=strchr(call, '-');
if (cp==NULL) strcat(call,"-0");
while (fread(&mh, sizeof(struct mheard_struct), 1, fp) == 1) {
if (strcasecmp(call, ax25_ntoa(&mh.from_call))==0) {
fclose(fp);
safe_strncpy(a.dest_call, ax25_ntoa(&mh.from_call), 9);
safe_strncpy(a.dev, mh.portname, 13);
for(k=0;k<AX25_MAX_DIGIS;k++) {
if (k<=mh.ndigis) safe_strncpy(a.digis[k],ax25_ntoa(&mh.digis[k]),9);
else strcpy(a.digis[k],"\0");
}
return &a;
}
}
fclose(fp);
return NULL;
}

99
procinfo.h Normal file
View File

@ -0,0 +1,99 @@
#ifndef _PROCINFO_H
#define _PROCINFO_H
#define PROC_NR_FILE "/proc/net/nr"
#define PROC_DEV_FILE "/proc/net/dev"
/* VE3TOK 30Nov2014 - A number of defines moved to config.h */
#define CONN_TYPE_DIRECT 'D'
#define CONN_TYPE_NODE 'N'
#define CONN_TYPE_DIGI 'V'
struct proc_dev {
char interface[6];
int rx_bytes;
int rx_packets;
int rx_errs;
int rx_drop;
int rx_fifo;
int rx_frame;
int rx_compressed;
int rx_multicast;
int tx_bytes;
int tx_packets;
int tx_errs;
int tx_drop;
int tx_fifo;
int tx_colls;
int tx_carrier;
int tx_compressed;
struct proc_dev *next;
};
/*
* /var/ax25/flex/gateways: (example)
* addr callsign dev dest digipeaters
* 00001 PI4TUE ax1 935
*/
struct flex_gt {
int addr;
char call[10];
char dev[14];
char digis[AX25_MAX_DIGIS][10];
struct flex_gt *next;
};
/*
* /usr/local/var/ax25/flex/destinations: (example)
* callsign ssid rtt gateway
* 9A0XZG 0-15 2575 00001
* DB0AAA 0-0 63 00001
*/
struct flex_dst {
char dest_call[10];
unsigned short ssida;
unsigned short sside;
unsigned long rtt;
int addr;
struct flex_dst *next;
};
struct ax_routes {
char dest_call[10];
char alias[10];
char dev[14];
char conn_type[1];
char description[50];
char digis[AX25_MAX_DIGIS][10];
struct ax_routes *next;
};
extern int safe_atoi(const char *s);
extern char *safe_strncpy(char *dest, char *src, int n);
extern struct proc_dev *read_proc_dev(void);
extern void free_proc_dev(struct proc_dev *ap);
extern struct flex_gt *read_flex_gt(void);
extern void free_flex_gt(struct flex_gt *fp);
extern struct flex_dst *read_flex_dst(void);
extern void free_flex_dst(struct flex_dst *fp);
extern struct ax_routes *read_ax_routes(void);
extern void free_ax_routes(struct ax_routes *ap);
extern struct ax_routes *find_route(char *dest_call, struct ax_routes *list);
extern struct flex_dst *find_dest(char *dest_call, struct flex_dst *list);
extern struct flex_gt *find_gateway(int addr, struct flex_gt *list);
extern struct ax_routes *find_mheard(char *dest_call);
#endif /* _PROCINFO_H */

261
router.c Normal file
View File

@ -0,0 +1,261 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netax25/ax25.h>
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include "procinfo.h"
#include "node.h"
int do_links(int argc, char **argv)
{
struct ax_routes *axrt, *p;
char digipath[AX25_MAX_DIGIS*10];
char tipoconn[9];
int i=0;
axio_puts("",NodeIo);
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
if ((axrt=read_ax_routes()) == NULL) {
if (errno) node_perror("do_links: read_ax_routes", errno);
else axio_printf(NodeIo,"No known links");
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "links" */
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[01;33m");
}
if (argc == 1) {
node_msg("AX25 Links:");
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
axio_printf(NodeIo,"Call Alias Description\n");
axio_printf(NodeIo,"--------- --------- -----------");
for(p=axrt;p!=NULL;p=p->next)
axio_printf(NodeIo,"\n%-9s %-9s %s", p->dest_call, p->alias, p->description);
free_ax_routes(axrt);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "links d" */
if ((*argv[1]=='d') && (strlen(argv[1])==1)) {
node_msg("AX25 Direct Links:");
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
axio_printf(NodeIo,"Call Alias Interf Description\n");
axio_printf(NodeIo,"--------- --------- ------- -----------");
for(p=axrt;p!=NULL;p=p->next)
{ if (*p->conn_type==CONN_TYPE_DIRECT) axio_printf(NodeIo,"\n%-9s %-9s %-7s %s", p->dest_call, p->alias, p->dev, p->description); }
free_ax_routes(axrt);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "links n" */
if ((*argv[1]=='n') && (strlen(argv[1])==1)) {
node_msg("AX25 Links via other nodes:");
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
axio_printf(NodeIo,"Call Alias Interf Routing Description\n");
axio_printf(NodeIo,"--------- --------- ------- --------- -----------");
for(p=axrt;p!=NULL;p=p->next)
{ if (*p->conn_type==CONN_TYPE_NODE) axio_printf(NodeIo,"\n%-9s %-9s %-7s %-9s %s", p->dest_call, p->alias, p->dev, p->digis[0], p->description); }
free_ax_routes(axrt);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "links v" */
if ((*argv[1]=='v') && (strlen(argv[1])==1)) {
node_msg("AX25 Links via digipeaters:");
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
axio_printf(NodeIo,"Call Alias Interf Digipeaters\n");
axio_printf(NodeIo,"--------- --------- ------- -----------");
for(p=axrt;p!=NULL;p=p->next) {
*digipath='\0';
for(i=0;i<AX25_MAX_DIGIS;i++) {
if (p->digis[i]==NULL) break;
if (i!=0) strcat(digipath," ");
strcat(digipath, p->digis[i]);
}
if (*p->conn_type==CONN_TYPE_DIGI) axio_printf(NodeIo,"\n%-9s %-9s %-7s %s", p->dest_call, p->alias, p->dev, digipath);
}
free_ax_routes(axrt);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "links <call>" */
p=find_route(argv[1], axrt);
if(p!=NULL) {
node_msg("AX25 Link to %s:", p->dest_call);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
axio_printf(NodeIo,"Call Alias Interf Type Description\n");
axio_printf(NodeIo,"--------- --------- ------- -------- -----------");
switch(*p->conn_type) {
case CONN_TYPE_DIRECT:
{ strcpy(tipoconn,"Direct"); break; }
case CONN_TYPE_NODE:
{ strcpy(tipoconn,"Via Node"); break; }
case CONN_TYPE_DIGI:
{ strcpy(tipoconn,"Via Digi"); break; }
}
axio_printf(NodeIo,"\n%-9s %-9s %-7s %-10s %s", p->dest_call, p->alias, p->dev, tipoconn, p->description);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
} else {
axio_printf(NodeIo,"No such link");
if (User.ul_type == AF_NETROM) {
node_msg("");
}
}
free_ax_routes(axrt);
return 0;
}
/* ssid buffer increased by 1 by VE3TOK */
int do_dest(int argc, char **argv)
{
struct flex_dst *fdst, *p;
struct flex_gt *flgt, *q;
char ssid[6];
int i=0;
axio_puts("",NodeIo);
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
if ((fdst=read_flex_dst()) == NULL) {
axio_printf(NodeIo,"No known destinations");
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "dest" */
if (argc == 1) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;33m");
}
if (User.ul_type != AF_AX25) {
axio_printf(NodeIo,"FlexNet Destinations:\n");
}
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
for (p=fdst;p!=NULL;p=p->next) {
sprintf(ssid, "%d-%d", p->ssida, p->sside);
axio_printf(NodeIo,"%-7s %-5s %4ld%s",p->dest_call,ssid,p->rtt,(++i % 4) ? " " : "\n");
}
if ((i % 4) != 0) axio_printf(NodeIo,"");
free_flex_dst(fdst);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
if ((flgt=read_flex_gt()) == NULL) {
node_perror("do_dest: read_flex_gt", errno);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "dest *" */
if (*argv[1]=='*') {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;33m");
}
node_msg("FlexNet Destinations:");
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
axio_printf(NodeIo,"Dest SSID RTT Gateway\n");
axio_printf(NodeIo,"-------- ----- ----- --------");
for(p=fdst;p!=NULL;p=p->next) {
sprintf(ssid, "%d-%d", p->ssida, p->sside);
q=find_gateway(p->addr,flgt);
axio_printf(NodeIo,"\n%-8s %-5s %5ld %-8s", p->dest_call, ssid,
p->rtt, q!=NULL?q->call:"?");
}
free_flex_dst(fdst);
free_flex_gt(flgt);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
/* "dest <call>" */
p=find_dest(argv[1], fdst);
if(p!=NULL) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;33m");
}
node_msg("FlexNet Destination %s:", p->dest_call);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0;m");
}
axio_printf(NodeIo,"Dest SSID RTT Gateway\n");
axio_printf(NodeIo,"-------- ----- ----- -------");
sprintf(ssid, "%d-%d", p->ssida, p->sside);
q=find_gateway(p->addr,flgt);
axio_printf(NodeIo,"\n%-8s %-5s %5ld %-8s", p->dest_call, ssid, p->rtt, q!=NULL?q->call:"?");
if (User.ul_type == AF_NETROM) {
node_msg("");
}
} else {
axio_printf(NodeIo,"No such destination");
if (User.ul_type == AF_NETROM) {
node_msg("");
}
}
free_flex_dst(fdst);
free_flex_gt(flgt);
return 0;
}

243
sysinfo.c Normal file
View File

@ -0,0 +1,243 @@
/*
* This code is slightly modified from the procps package.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <utmp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include "node.h"
#include "sysinfo.h"
char *xmalloc(size_t);
char *fixup_null_alloc(size_t);
int read_utmp(char *);
int list_entries(int);
int who(void);
#define UPTIME_FILE "/proc/uptime"
#define LOADAVG_FILE "/proc/loadavg"
#define MEMINFO_FILE "/proc/meminfo"
#define STRUCT_UTMP struct utmp
static STRUCT_UTMP *utmp_contents;
#ifndef UTMP_FILE
#define UTMP_FILE "/var/run/utmp"
#endif
#ifndef EMAILLEN
#define EMAILLEN 64
#endif
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
#ifndef S_IWGRP
#define S_IWGRP 020
#endif
static char buf[300];
/* 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) { \
close(fd); \
return 0; \
} \
lseek(fd, 0L, SEEK_SET); \
if ((n = read(fd, buf, sizeof buf - 1)) < 0) { \
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) {
printf("Bad data in %s\n", 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) {
printf("Bad data in %s\n", LOADAVG_FILE );
return 0;
}
SET_IF_DESIRED(av1, avg_1);
SET_IF_DESIRED(av5, avg_5);
SET_IF_DESIRED(av15, avg_15);
return 1;
}
/* The following /proc/meminfo parsing routine assumes the following format:
[ <label> ... ] # header lines
[ <label> ] <num> [ <num> ... ] # table rows
[ repeats of above line ]
Any lines with fewer <num>s than <label>s get trailing <num>s set to zero.
The return value is a NULL terminated unsigned** which is the table of
numbers without labels. Convenient enumeration constants for the major and
minor dimensions are available in the header file. Note that this version
requires that labels do not contain digits. It is readily extensible to
labels which do not *begin* with digits, though.
*/
#define MAX_ROW 27 /* these are a little liberal for flexibility */
#define MAX_COL 2
unsigned** meminfo(void) {
static unsigned *row[MAX_ROW + 1]; /* row pointers */
static unsigned num[MAX_ROW * MAX_COL]; /* number storage */
char *p;
int i, j, k, l;
FILE_TO_BUF(MEMINFO_FILE)
if (!row[0]) /* init ptrs 1st time through */
for (i=0; i < MAX_ROW; i++) /* std column major order: */
row[i] = num + MAX_COL*i; /* A[i][j] = A + COLS*i + j */
p = buf;
for (i=0; i < MAX_ROW; i++) /* zero unassigned fields */
for (j=0; j < MAX_COL; j++)
row[i][j] = 0;
for (i=0; i < MAX_ROW && *p; i++) { /* loop over rows */
while(*p && !isdigit(*p)) p++; /* skip chars until a digit */
for (j=0; j < MAX_COL && *p; j++) { /* scanf column-by-column */
l = sscanf(p, "%u%n", row[i] + j, &k);
p += k; /* step over used buffer */
if (*p == '\n' || l < 1) /* end of line/buffer */
break;
}
}
/* row[i+1] = NULL; terminate the row list, currently unnecessary */
return row; /* NULL return ==> error */
}
int system_user_count(void)
{
int users;
users=who();
return users;
}
int who(void)
{
int users;
users=read_utmp(UTMP_FILE);
return list_entries(users);
}
int read_utmp (filename)
char *filename;
{
FILE *utmp;
struct stat file_stats;
int n_read;
size_t size;
utmp = fopen (filename, "r");
if (utmp == NULL) return 0;
fstat (fileno (utmp), &file_stats);
size = file_stats.st_size;
if (size > 0)
utmp_contents = (STRUCT_UTMP *) xmalloc (size);
else
{
fclose (utmp);
return 0;
}
/* Use < instead of != in case the utmp just grew. */
n_read = fread (utmp_contents, 1, size, utmp);
if (ferror (utmp) || fclose (utmp) == EOF || n_read < size) return 0;
return size / sizeof (STRUCT_UTMP);
}
int list_entries (n)
int n;
{
register STRUCT_UTMP *this = utmp_contents;
register int entries = 0;
while (n--)
{
if (this->ut_name[0]
#ifdef USER_PROCESS
&& this->ut_type == USER_PROCESS
#endif
)
{
char trimmed_name[sizeof (this->ut_name) + 1];
int i;
strncpy (trimmed_name, this->ut_name, sizeof (this->ut_name));
trimmed_name[sizeof (this->ut_name)] = ' ';
for (i = 0; i <= sizeof (this->ut_name); i++)
{
if (trimmed_name[i] == ' ')
break;
}
trimmed_name[i] = '\0';
/* tprintf("%s ", trimmed_name); */
entries++;
}
this++;
}
return entries;
}
char *fixup_null_alloc (n)
size_t n;
{
char *p;
p = 0;
if (n == 0)
p = malloc ((size_t) 1);
if (p == 0) return NULL;
return p;
}
/* Allocate N bytes of memory dynamically, with error checking. */
char *xmalloc (n)
size_t n;
{
char *p;
p = malloc (n);
if (p == 0)
p = fixup_null_alloc (n);
return p;
}

26
sysinfo.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef SYSINFO_H
#define SYSINFO_H
int loadavg(double *av1, double *av5, double *av15);
int uptime (double *uptime_secs, double *idle_secs);
unsigned** meminfo(void);
enum meminfo_row { meminfo_main = 0, meminfo_free, meminfo_buffers,
meminfo_cached, meminfo_scached, meminfo_active,
meminfo_inactive, meminfo_htotal, meminfo_hfree,
meminfo_ltotal, meminfo_lfree, meminfo_stotal,
meminfo_sfree, meminfo_dirty, meminfo_writeback,
meminfo_anonpages, meminfo_mapped, meminfo_slab,
meminfo_sreclaim, meminfo_sunreclaim, meminfo_pagetables,
meminfo_nfs_unstab, meminfo_bounce, meminfo_climit,
meminfo_cas, meminfo_vmtotal, meminfo_vmused,
meminfo_vmchunk
};
enum meminfo_col { meminfo_total = 0
};
unsigned read_total_main(void);
#endif /* SYSINFO_H */

632
system.c Normal file
View File

@ -0,0 +1,632 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <fcntl.h>
#include <ctype.h>
#include <signal.h>
#include <paths.h>
#include <pwd.h>
#include <utmp.h>
#include <time.h>
#include <termios.h>
#include <unistd.h>
#include <netax25/ax25.h>
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include "node.h"
#include "procinfo.h"
#include "config.h" /* VE3TOK - Dec20, 2014 */
#define USER_NOBODY "nobody"
#define NUMPTY 176
#define SYSTEM_TIMEOUT 7200
#define LAST_DATA_SIZE 120
int shell=0;
char *envp[16], *argp[16], mbox[40];
char other_id[20];
int in_queue=0;
int pid=-1;
char ptyname[80], Password[256];
int ptyfd;
/*---------------------------------------------------------------------------*/
int cusgets(char *buf, int buflen, ax25io *iop)
{
int c, len = 0;
while (len < (buflen - 1)) {
c = axio_getc(iop);
if (c == -1) {
if (len > 0) {
buf[len] = 0;
return (len);
} else return -1;
}
/* NULL also interpreted as EOL */
if (c == '\n' || c == '\r' || c == 0) {
buf[len++] = c;
buf[len] = 0;
return (len);
}
buf[len++] = c;
}
buf[buflen - 1] = 0;
return (buflen-1);
}
/*---------------------------------------------------------------------------*/
int find_pty(char *ptyname)
{
char master[80];
int fd;
int num;
static int lastnum = -1;
for(num = lastnum + 1; ; num++) {
if (num >= NUMPTY) num = 0;
sprintf(master, "/dev/pty%c%x", 'p' + (num >> 4), num & 0xf);
/* sprintf(master, "/dev/pts/%x", num & 0xf); */
if ((fd = open(master, O_RDWR | O_NONBLOCK, 0600)) >= 0) {
sprintf(ptyname, "/dev/tty%c%x", 'p' + (num >> 4), num & 0xf);
/* sprintf(ptyname, "/dev/pts/%x", num & 0xf); */
lastnum = num;
return fd;
}
if (num == lastnum) break;
}
return -1;
}
/*---------------------------------------------------------------------------*/
void login_close(void)
{
struct utmp utmpbuf, *ut;
FILE *fp;
if (ptyfd > 0) {
chown(ptyname, 0, 0);
chmod(ptyname, 0666);
ioctl(ptyfd, TCFLSH, 2);
close(ptyfd);
}
if (pid>0) {
kill(pid, SIGHUP);
pid=0;
}
memset(&utmpbuf, 0, sizeof(utmpbuf));
setutent();
utmpbuf.ut_type=LOGIN_PROCESS;
strcpy(utmpbuf.ut_line, ptyname+5);
strcpy(utmpbuf.ut_id, ptyname+strlen(ptyname)-2);
ut=getutid(&utmpbuf);
ut->ut_type=DEAD_PROCESS;
memset(ut->ut_host,0,UT_HOSTSIZE);
memset(ut->ut_user,0,UT_NAMESIZE);
time(&ut->ut_time);
/* ut->ut_xtime = (unsigned int)time(NULL); */
pututline(ut);
endutent();
if ((fp = fopen(_PATH_WTMP, "r+")) != NULL) {
fseek(fp, 0L, SEEK_END);
fwrite(ut, sizeof(utmpbuf), 1, fp);
fclose(fp);
}
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} Welcome back.\n", NodeId);
} else {
axio_printf(NodeIo,"Welcome back.");
}
}
/*---------------------------------------------------------------------------*/
int login_open(struct passwd *pw, char *command)
{
if ((ptyfd=find_pty(ptyname)) < 0) {
syslog(LOG_ERR, "Error opening pseudo terminal for %s", pw->pw_name);
return -1;
}
syslog(LOG_INFO, "Opened pseudo terminal (%s) for %s", ptyname, pw->pw_name);
pid=fork();
if (pid==-1) {
syslog(LOG_ERR, "Cannot fork for %s", pw->pw_name);
return -1;
}
if (pid==0) { /* child */
struct termios termios;
struct utmp utmpbuf;
int i;
for(i=0;i<FD_SETSIZE;i++) close(i);
setsid();
open(ptyname, O_RDWR, 0666);
dup(0);
dup(0);
chmod(ptyname, 0622);
ioctl(0, TIOCSCTTY, 0);
memset(&termios, 0 , sizeof(termios));
termios.c_iflag = ICRNL | IXOFF;
termios.c_oflag = OPOST | ONLCR | TAB3;
termios.c_cflag = CS8 | CREAD | CLOCAL;
termios.c_lflag = ISIG | ICANON;
termios.c_cc[VINTR] = 127;
termios.c_cc[VQUIT] = 28;
termios.c_cc[VERASE] = 8;
termios.c_cc[VKILL] = 24;
termios.c_cc[VEOF] = 4;
cfsetispeed(&termios, B38400);
cfsetospeed(&termios, B38400);
tcsetattr(0, TCSANOW, &termios);
memset(&utmpbuf, 0, sizeof(utmpbuf));
utmpbuf.ut_type=USER_PROCESS; /* Type of login */
utmpbuf.ut_pid=getpid(); /* Pid of login process */
strcpy(utmpbuf.ut_line, ptyname+5); /* Devicename of tty */
strcpy(utmpbuf.ut_id, ptyname+strlen(ptyname)-2); /* Inittab id */
strcpy(utmpbuf.ut_user, pw->pw_name); /* Username */
strcpy(utmpbuf.ut_host, "local:uronode");
utmpbuf.ut_addr=0x7f000000;
time(&utmpbuf.ut_time); /* Time entry was made */
/* utmpbuf.ut_xtime = (unsigned int)time(NULL); */
setutent();
pututline(&utmpbuf);
endutent();
setgid(pw->pw_gid);
setuid(pw->pw_uid);
execve(command, argp, envp);
exit(1);
}
if (pid!=0) {
int k, cnt;
fd_set fds_read, fds_err;
struct timeval tv;
char buf[1500];
while(1) {
FD_ZERO(&fds_read);
FD_ZERO(&fds_err);
FD_SET(STDIN_FILENO, &fds_read);
/* FD_SET(User.fd, &fds_err); */
FD_SET(ptyfd, &fds_read);
/* FD_SET(ptyfd, &fds_err); */
if (User.ul_type==AF_INET) {
tv.tv_usec=25;
tv.tv_sec=0;
} else {
tv.tv_usec=750;
tv.tv_sec=0;
}
if (in_queue>0) k=select(ptyfd+1, &fds_read, NULL, &fds_err, &tv);
else k=select(ptyfd+1, &fds_read, NULL, &fds_err, NULL);
if (k == -1) {
if (errno!=EINTR) {
syslog(LOG_DEBUG,"I/O select");
break;
}
}
if (k == 0) {
if (in_queue>0) {
axio_flush(NodeIo);
in_queue=0;
}
}
/* if (FD_ISSET(User.fd, &fds_err)) {
syslog(LOG_DEBUG,"I/O end: error channel, user");
break;
}
if (FD_ISSET(ptyfd, &fds_err)) {
syslog(LOG_DEBUG,"I/O end: error channel, application");
break;
} */
if (FD_ISSET(STDIN_FILENO, &fds_read)) {
alarm(SYSTEM_TIMEOUT);
cnt=cusgets(buf, sizeof(buf), NodeIo);
if (cnt < 0)
{
syslog(LOG_DEBUG,"I/O end: stdio channel, user");
break;
} else {
write(ptyfd, buf, cnt);
}
}
if (FD_ISSET(ptyfd, &fds_read)) {
alarm(SYSTEM_TIMEOUT);
cnt = read(ptyfd, buf, sizeof(buf));
if (cnt < 0) {
syslog(LOG_DEBUG,"I/O end: stdio channel, application");
break;
}
for(k = 0 ; k < cnt ; k++) {
if (buf[k]=='\n' && (User.ul_type==AF_AX25 || User.ul_type==AF_FLEXNET || User.ul_type==AF_NETROM)) continue;
axio_putc(buf[k], NodeIo);
}
in_queue+=cnt;
}
}
login_close();
}
return 0;
}
/*---------------------------------------------------------------------------*/
int check_passwd(void)
{
char buffer[400]="",
tmp[100]="";
int pass[5],
level,i;
long timet;
char answer[81]="";
char buf[2048];
level=strlen(Password);
timet=time(NULL);
srandom((int) timet);
for(i=0;i<5;i++) pass[i]=(int) (level * (random()/(RAND_MAX+1.0)));
sprintf(buffer,"%10.10ld%s",timet,Password);
axio_printf(NodeIo,"%s %d %d %d %d %d [%010.10ld]\n",
PassPrompt,pass[0]+1,pass[1]+1,pass[2]+1,pass[3]+1,pass[4]+1,timet);
sprintf(answer,"%c%c%c%c%c",Password[pass[0]],Password[pass[1]],Password[pass[2]],Password[pass[3]],Password[pass[4]]);
axio_flush(NodeIo);
axio_gets(buf, sizeof(buf), NodeIo);
if(strlen(buf)==32) i=strcmp(buf,tmp);
else i=strcmp(buf,answer);
if(i) {
axio_printf(NodeIo,"Password incorrect!");
return 0;
}
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
axio_printf(NodeIo,"URONode Shell engaged - use EXTREME caution! \n\n");
return 1;
}
/*---------------------------------------------------------------------------*/
int do_system(int argc, char **argv)
{
int i;
struct passwd *pw=NULL;
argp[0]=argv[0];
for(i=1;i<(argc);i++) argp[i]=argv[i];
argp[argc]=NULL;
axio_puts("",NodeIo);
if (other_id!=NULL && strcmp(other_id, USER_NOBODY)!=0) pw=getpwnam(other_id);
if (pw==NULL) {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
node_msg("Permission denied\n");
syslog(LOG_INFO, "system: %s attempted command %s", User.call, argv[0]);
axio_puts("",NodeIo);
return 1;
}
if (strncmp(argv[0],"sysop",strlen(argv[0]))==0)
{
if (shell==1) {
User.state = STATE_EXTCMD;
User.dl_type = AF_UNSPEC;
strcpy(User.dl_name, "sysop");
strupr(User.dl_name);
update_user();
if (check_passwd()==0) return 0;
login_open(pw, "/bin/bash");
axio_puts("",NodeIo);
return 0;
} else {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
node_msg("permission denied");
axio_puts("",NodeIo);
return 1;
};
}
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
node_msg("unknown command");
return 0;
}
int examine_user(void)
{
FILE *users;
char call[10], buf[1024], *cp, *ep;
char flags[40];
strcpy(other_id, USER_NOBODY);
if ((users=fopen(CONF_USERS_FILE, "r"))==NULL) {
node_msg("system: cannot open authority file: %s", CONF_USERS_FILE);
syslog(LOG_ERR, "system: cannot open authority file: %s", CONF_USERS_FILE);
axio_puts("",NodeIo);
return 1;
}
strcpy(call, User.call);
cp=strchr(call, '-');
if (cp) *cp='\0';
while(fgets(buf, 1024, users)) {
ep=strchr(buf, '#');
if (ep) *ep='\0';
if (*buf==0) continue;
cp=strtok(buf, ":\t\n\r");
if (cp==NULL) continue;
if (strcasecmp(cp, call)==0) {
cp=strtok(NULL, ":\t\n\r");
if (cp==NULL) continue;
strcpy(Password, cp);
cp=strtok(NULL, ":\t\n\r");
if (cp==NULL) continue;
strcpy(other_id, cp);
cp=strtok(NULL, ":\t\n\r");
if (cp==NULL) continue;
strcpy(flags, cp);
}
}
if (strcmp(other_id, USER_NOBODY)==0) return 0;
cp=strtok(flags, " ,;-/\t\n\r");
if (cp==NULL) return 0;
do {
if (strcmp(cp, "shell")==0) {
shell=1;
add_internal_cmd(&Nodecmds, "SYSop", 1, do_system);
}
cp=strtok(NULL, " ,;-/\t\n\r");
} while(cp!=NULL);
return 0;
}
struct nodelastlog {
char ll_user[8];
long ll_time;
char ll_line[LAST_DATA_SIZE];
char ll_host[LAST_DATA_SIZE];
int ll_count;
};
struct ipheardlastlog {
char ii_host[LAST_DATA_SIZE];
};
void lastlog(void)
{
struct nodelastlog ll;
int last;
int count=0;
int hit=0;
int UserId=0;
char tty[LAST_DATA_SIZE];
char hostname[LAST_DATA_SIZE];
char usercall[10];
char *cp;
int escape;
strcpy(usercall, User.call);
cp=strchr(usercall, '-');
if (cp) *cp='\0';
strcpy(tty, "");
switch (User.ul_type) {
case AF_FLEXNET: strcpy(hostname, "FlexNet");
break;
case AF_AX25: strcpy(hostname, "[");
strcat(hostname, "AX25");
strcat(hostname, "] ");
strcat(hostname, User.call);
if (strlen(User.ul_name)>0) {
strcat(hostname, " via ");
strcat(hostname, User.ul_name);
}
break;
case AF_NETROM: strcpy(hostname, "<");
strcat(hostname, User.ul_port);
strcat(hostname, "> ");
strcat(hostname, User.call);
if (strlen(User.ul_name)>0) {
strcat(hostname, "@");
strcat(hostname, User.ul_name);
}
break;
#ifdef HAVE_ROSE
case AF_ROSE: strcpy(hostname, User.call);
if (strlen(User.ul_name)>0) {
strcat(hostname, " at ");
strcat(hostname, User.ul_name);
}
break;
#endif
case AF_INET: strcpy(hostname, User.ul_name);
break;
case AF_UNSPEC: strcpy(hostname, User.call);
strcat(hostname, " on local");
break;
default: strcpy(hostname, "");
break;
}
if ((last = open(DATA_NODE_LAST_FILE, O_RDWR, 0)) >= 0) {
lseek(last, (off_t)UserId * sizeof(ll), L_SET);
while (read(last, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time != 0) {
if (strcmp(ll.ll_user,usercall)==0) {
escape = (check_perms(PERM_NOESC, 0L) == 0) ? -1 : EscChar;
#ifdef HAVEMOTD
/*
if (User.ul_type != AF_NETROM) {
axio_printf(NodeIo," Escape is: %s%c\n", escape < 32 ? "CTRL-" : "", escape < 32 ? (escape + 'A' - 1) : escape);
axio_printf(NodeIo,"Last login: %.*s ",24-5,(char *)ctime(&ll.ll_time));
if (*ll.ll_host != '\0') axio_printf(NodeIo,"\n From: %.*s\n",(int)sizeof(ll.ll_host), ll.ll_host);
else axio_printf(NodeIo," on %.*s\n",(int)sizeof(ll.ll_line), ll.ll_line);
}
*/
#endif
count=ll.ll_count;
hit++;
break;
} else UserId++;
}
lseek(last, (off_t)UserId * sizeof(ll), L_SET);
}
memset((char *)&ll, 0, sizeof(ll));
if ((hit==0) && (User.ul_type != AF_NETROM)) {
axio_printf(NodeIo,"Welcome, new user! Please use the Info and ? commands.\n\n");
count=0;
}
ll.ll_count=count+1;
(void)time(&ll.ll_time);
strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
strncpy(ll.ll_user, usercall, sizeof(ll.ll_user));
if (hostname) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
write(last, (char *)&ll, sizeof(ll));
close(last);
}
int do_last(int argc, char **argv)
{
int last;
struct nodelastlog ll;
int Entries=0;
char call[10], *cp;
if ((last = open(DATA_NODE_LAST_FILE, O_RDONLY, 0)) <= 0) {
node_perror(DATA_NODE_LAST_FILE, errno);
return -1;
}
if (argc < 2) {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
axio_printf(NodeIo,"Usage: Who <callsign or *>");
close(last);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}
if (strcmp(argv[1],"*")==0) {
cp=NULL;
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[01;37m");
}
axio_printf(NodeIo,"Logins for ALL:\n", call);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0m");
}
} else {
if (!ax25_aton_entry(argv[1], call)) {
strcpy(call,strupr(argv[1]));
cp=strchr(call,'-');
if (cp) *cp='\0';
cp=call;
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[01;37m");
}
axio_printf(NodeIo,"Last online information for %s:\n", call);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[0m");
}
} else {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
axio_printf(NodeIo,"Usage: Who <callsign or *>\n");
if (User.ul_type == AF_NETROM) {
node_msg("");
}
close(last);
return -1;
}
}
lseek(last, (off_t)Entries * sizeof(ll), L_SET);
/* while (Entries < 20 && (read(last, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time != 0)) { */
while (read(last, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time !=0) {
if (cp && strcasecmp(cp,ll.ll_user)!=0) continue;
if (Entries==0) {
axio_printf(NodeIo,"User Last Online Count From\n");
axio_printf(NodeIo,"------ -------------------- ----- -----------------------------");
}
axio_printf(NodeIo,"\n%-10s ", ll.ll_user);
axio_printf(NodeIo,"%.*s ",24-5,(char *)ctime(&ll.ll_time));
axio_printf(NodeIo,"%-5d ",ll.ll_count);
if (*ll.ll_host != '\0') axio_printf(NodeIo," %.*s",(int)sizeof(ll.ll_host), ll.ll_host);
else axio_printf(NodeIo," on %.*s",(int)sizeof(ll.ll_line), ll.ll_line);
Entries++;
}
lseek(last, (off_t)Entries * sizeof(ll), L_SET);
close(last);
if (!cp && Entries==0) axio_printf(NodeIo,"No users in the lastlog database.");
if (cp && Entries==0) axio_printf(NodeIo,"%s Never logged in.", call);
if (User.ul_type == AF_NETROM) {
node_msg("");
}
return 0;
}

289
user.c Normal file
View File

@ -0,0 +1,289 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <signal.h>
#include <netax25/procutils.h>
#include <netax25/axlib.h>
#include "node.h"
#include "sysinfo.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;
if (stat(DATA_NODE_LOGIN_FILE, &statbuf) == -1) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
return;
}
if (statbuf.st_size % sizeof(struct user) != 0) {
node_msg("%s: Incorrect size", DATA_NODE_LOGIN_FILE);
node_log(LOGLVL_ERROR, "%s: Incorrect size", DATA_NODE_LOGIN_FILE);
return;
}
time(&User.logintime);
User.cmdtime = User.logintime;
User.pid = getpid();
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r+")) == NULL) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
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);
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 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;
}
int user_list(int argc, char **argv)
{
FILE *f;
struct user u;
struct tm *tp;
struct proc_nr_nodes *np;
char buf[80];
long l;
axio_puts("",NodeIo);
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) {
node_perror(DATA_NODE_LOGIN_FILE, errno);
return 0;
}
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} %s", NodeId, VERSION);
}
if (User.ul_type == AF_INET) {
axio_printf(NodeIo, "\e[01;35m");
} else {
axio_printf(NodeIo, "Current users:");
}
if (user_count() == 0) {
axio_printf(NodeIo, " No users online.\n");
}
if (User.ul_type == AF_INET) {
axio_printf(NodeIo,"\e[0;m");
}
if (user_count() != 0) /* axio_printf(NodeIo,"") */ ;
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_FLEXNET:
sprintf(buf, "\nFlexNet (%.9s)",
u.call);
break;
case AF_AX25:
sprintf(buf, "\nUplink (%.9s on interface %.10s)",
u.call, u.ul_name);
break;
case AF_NETROM:
if ((np = find_node(u.ul_name, NULL)) != NULL) {
sprintf(buf, "\nCircuit (%.9s %.18s)",
u.call,
print_node(np->alias, np->call));
} else {
sprintf(buf, "\nCircuit (%.9s %.18s)",
u.call, u.ul_name);
}
break;
#ifdef HAVE_ROSE
case AF_ROSE:
sprintf(buf, "\nROSE (%.9s %.18s)",
u.call, u.ul_name);
break;
#endif
case AF_INET:
sprintf(buf, "\nTelnet (%.9s @ %.16s)",
u.call, u.ul_name);
break;
case AF_UNSPEC:
sprintf(buf, "\nHost (%.9s on local)",
u.call);
break;
default:
sprintf(buf, "\n?????? (%.9s %.18s)",
u.call, u.ul_name);
break;
}
axio_printf(NodeIo,"%-37.37s ", buf);
switch (u.state) {
case STATE_QUIT:
logout_user();
break;
case STATE_LOGIN:
axio_puts(" -> Logging in",NodeIo);
break;
case STATE_IDLE:
time(&l);
l -= u.cmdtime;
tp = gmtime(&l);
axio_printf(NodeIo," -> 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_FLEXNET:
axio_printf(NodeIo," -> Trying (%s)",
u.dl_name);
break;
case AF_AX25:
axio_printf(NodeIo," -> Trying (%s on interface %s)",
u.dl_name, u.dl_port);
break;
case AF_NETROM:
axio_printf(NodeIo," -> Trying (%s)",
u.dl_name);
break;
#ifdef HAVE_ROSE
case AF_ROSE:
axio_printf(NodeIo," -> Trying (%s)",
u.dl_name);
break;
#endif
case AF_INET:
axio_printf(NodeIo," -> Trying (%s:%s)",
u.dl_name, u.dl_port);
break;
default:
axio_puts(" -> ???",NodeIo);
break;
}
break;
case STATE_CONNECTED:
switch (u.dl_type) {
case AF_FLEXNET:
axio_printf(NodeIo,"<--> FlexNet (%s)",
u.dl_name);
break;
case AF_AX25:
axio_printf(NodeIo,"<--> Downlink (%s on interface %s)",
u.dl_name, u.dl_port);
break;
case AF_NETROM:
axio_printf(NodeIo,"<--> Circuit (%s)",
u.dl_name);
break;
#ifdef HAVE_ROSE
case AF_ROSE:
axio_printf(NodeIo,"<--> ROSE (%s)",
u.dl_name);
break;
#endif
case AF_INET:
axio_printf(NodeIo,"<--> Telnet (%s:%s)",
u.dl_name, u.dl_port);
break;
default:
axio_printf(NodeIo,"<--> ???");
break;
}
break;
case STATE_PINGING:
axio_printf(NodeIo,"<--> Pinging (%s)", u.dl_name);
break;
case STATE_EXTCMD:
axio_printf(NodeIo,"<--> Extcmd (%s)", u.dl_name);
break;
default:
axio_puts(" -> ??????",NodeIo);
break;
}
axio_puts("",NodeIo);
}
if (User.ul_type == AF_NETROM) {
node_msg("");
}
fclose(f);
return 0;
}

115
util.c Normal file
View File

@ -0,0 +1,115 @@
#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 <sys/socket.h>
#include <netax25/ax25.h>
#include <netrose/rose.h>
#include <netax25/axlib.h>
#include "node.h"
#include "sysinfo.h"
#include "procinfo.h"
static char buf[256];
char *HostName;
char *Prompt;
void node_msg(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
axio_printf(NodeIo,"%s\n", buf);
}
/*
void node_prompt(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo,"%s} ", NodeId);
}
if ((User.ul_type == AF_INET) && (check_perms(PERM_ANSI, 0L) != -1)) {
axio_printf(NodeIo,"\n\e[01;31m%s\e[0m@\e[01;34m%s\e[0m:/uronode$ ",User.call, HostName);
}
if ((User.ul_type == AF_INET) && (check_perms(PERM_ANSI, 0L) == -1)) {
axio_printf(NodeIo,"\n%s@%s:/uronode$ ", User.call, HostName);
}
if (User.ul_type == AF_AX25) {
axio_printf(NodeIo,"%s",Prompt);
}
}
*/
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));
axio_printf(NodeIo,"\nERROR; %s\n", buf);
axio_eolmode(NodeIo, oldmode);
axio_flush(NodeIo);
node_log(LOGLVL_ERROR, buf);
}
char *print_node(const char *alias, const char *call)
{
static char node[17];
sprintf(node, "%s%s%s",
!strcmp(alias, "*") ? "" : alias,
!strcmp(call, "*") ? "" : ":", call);
return node;
}
void node_log(int loglevel, const char *fmt, ...)
{
static int opened = 0;
va_list args;
int pri;
if (LogLevel < loglevel)
return;
if (!opened) {
openlog("uronode", LOG_PID, LOG_LOCAL7);
opened = 1;
}
switch (loglevel) {
case LOGLVL_ERROR:
pri = LOG_ERR;
break;
case LOGLVL_LOGIN:
pri = LOG_NOTICE;
break;
case LOGLVL_GW:
pri = LOG_INFO;
break;
default:
pri = LOG_INFO;
break;
}
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
buf[sizeof(buf) - 1] = 0;
va_end(args);
syslog(pri, "%s", buf);
}