From 4013fe89dba7bcbd25ffded96d12bba6c9c78476 Mon Sep 17 00:00:00 2001 From: Dave Hibberd Date: Thu, 3 Sep 2015 20:01:45 +0100 Subject: [PATCH] Imported Upstream version 2.3.1 --- BBS.txt | 6 + CHANGES.1 | 929 +++++++++++++++++++++++++++++++++ CHANGES.2 | 637 ++++++++++++++++++++++ COLORS | 25 + COPYING | 339 ++++++++++++ FAQ | 35 ++ INSTALL | 79 +++ Makefile.in | 100 ++++ Makefile.include.in | 13 + README | 95 ++++ URONode.his | 49 ++ axcalluser.c | 77 +++ axcalluser.h | 16 + axdigi.c | 255 +++++++++ cmdparse.c | 300 +++++++++++ command.c | 1058 +++++++++++++++++++++++++++++++++++++ config.c | 485 +++++++++++++++++ config.h.in | 36 ++ configure | 303 +++++++++++ etc/axdigi.conf | 20 + etc/flexd.conf | 14 + etc/gateways | 0 etc/help/bye.hlp | 6 + etc/help/color.hlp | 18 + etc/help/connect.hlp | 25 + etc/help/desti.hlp | 14 + etc/help/escape.hlp | 16 + etc/help/finger.hlp | 13 + etc/help/help.hlp | 10 + etc/help/host.hlp | 11 + etc/help/info.hlp | 8 + etc/help/links.hlp | 16 + etc/help/mail.hlp | 12 + etc/help/message.hlp | 14 + etc/help/mheard.hlp | 8 + etc/help/msg.hlp | 15 + etc/help/netstat.hlp | 7 + etc/help/nodes.hlp | 15 + etc/help/ping.hlp | 15 + etc/help/ports.hlp | 12 + etc/help/quit.hlp | 6 + etc/help/rose.hlp | 2 + etc/help/routes.hlp | 16 + etc/help/sessions.hlp | 10 + etc/help/status.hlp | 14 + etc/help/telnet.hlp | 26 + etc/help/users.hlp | 8 + etc/help/version.hlp | 6 + etc/help/who.hlp | 8 + etc/help/zconnect.hlp | 23 + etc/help/ztelnet.hlp | 25 + etc/lastlog | 0 etc/loggedin | 0 etc/uronode.conf | 89 ++++ etc/uronode.info | 3 + etc/uronode.motd | 4 + etc/uronode.perms | 26 + etc/uronode.routes | 21 + etc/uronode.users | 6 + extcmd.c | 203 ++++++++ flexd.c | 431 +++++++++++++++ gateway.c | 1131 ++++++++++++++++++++++++++++++++++++++++ ipc.c | 193 +++++++ man/axdigi.8.gz | Bin 0 -> 1006 bytes man/flexd.conf.5.gz | Bin 0 -> 988 bytes man/nodeusers.1.gz | Bin 0 -> 596 bytes man/uronode.8.gz | Bin 0 -> 3287 bytes man/uronode.conf.5.gz | Bin 0 -> 3333 bytes man/uronode.perms.5.gz | Bin 0 -> 1267 bytes mheard.c | 151 ++++++ node.c | 419 +++++++++++++++ node.h | 172 ++++++ nodeusers.c | 82 +++ procinfo.c | 358 +++++++++++++ procinfo.h | 99 ++++ router.c | 261 ++++++++++ sysinfo.c | 243 +++++++++ sysinfo.h | 26 + system.c | 632 ++++++++++++++++++++++ user.c | 289 ++++++++++ util.c | 115 ++++ 81 files changed, 10204 insertions(+) create mode 100644 BBS.txt create mode 100644 CHANGES.1 create mode 100644 CHANGES.2 create mode 100644 COLORS create mode 100644 COPYING create mode 100644 FAQ create mode 100644 INSTALL create mode 100644 Makefile.in create mode 100644 Makefile.include.in create mode 100644 README create mode 100644 URONode.his create mode 100644 axcalluser.c create mode 100644 axcalluser.h create mode 100644 axdigi.c create mode 100644 cmdparse.c create mode 100644 command.c create mode 100644 config.c create mode 100644 config.h.in create mode 100755 configure create mode 100644 etc/axdigi.conf create mode 100644 etc/flexd.conf create mode 100644 etc/gateways create mode 100644 etc/help/bye.hlp create mode 100644 etc/help/color.hlp create mode 100644 etc/help/connect.hlp create mode 100644 etc/help/desti.hlp create mode 100644 etc/help/escape.hlp create mode 100644 etc/help/finger.hlp create mode 100644 etc/help/help.hlp create mode 100644 etc/help/host.hlp create mode 100644 etc/help/info.hlp create mode 100644 etc/help/links.hlp create mode 100644 etc/help/mail.hlp create mode 100644 etc/help/message.hlp create mode 100644 etc/help/mheard.hlp create mode 100644 etc/help/msg.hlp create mode 100644 etc/help/netstat.hlp create mode 100644 etc/help/nodes.hlp create mode 100644 etc/help/ping.hlp create mode 100644 etc/help/ports.hlp create mode 100644 etc/help/quit.hlp create mode 100644 etc/help/rose.hlp create mode 100644 etc/help/routes.hlp create mode 100644 etc/help/sessions.hlp create mode 100644 etc/help/status.hlp create mode 100644 etc/help/telnet.hlp create mode 100644 etc/help/users.hlp create mode 100644 etc/help/version.hlp create mode 100644 etc/help/who.hlp create mode 100644 etc/help/zconnect.hlp create mode 100644 etc/help/ztelnet.hlp create mode 100644 etc/lastlog create mode 100644 etc/loggedin create mode 100644 etc/uronode.conf create mode 100644 etc/uronode.info create mode 100644 etc/uronode.motd create mode 100644 etc/uronode.perms create mode 100644 etc/uronode.routes create mode 100644 etc/uronode.users create mode 100644 extcmd.c create mode 100644 flexd.c create mode 100644 gateway.c create mode 100644 ipc.c create mode 100644 man/axdigi.8.gz create mode 100644 man/flexd.conf.5.gz create mode 100644 man/nodeusers.1.gz create mode 100644 man/uronode.8.gz create mode 100644 man/uronode.conf.5.gz create mode 100644 man/uronode.perms.5.gz create mode 100644 mheard.c create mode 100644 node.c create mode 100644 node.h create mode 100644 nodeusers.c create mode 100644 procinfo.c create mode 100644 procinfo.h create mode 100644 router.c create mode 100644 sysinfo.c create mode 100644 sysinfo.h create mode 100644 system.c create mode 100644 user.c create mode 100644 util.c diff --git a/BBS.txt b/BBS.txt new file mode 100644 index 0000000..22e94cf --- /dev/null +++ b/BBS.txt @@ -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. diff --git a/CHANGES.1 b/CHANGES.1 new file mode 100644 index 0000000..aa59b32 --- /dev/null +++ b/CHANGES.1 @@ -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 . 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 +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 ". 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 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 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 , 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 +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 , the 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. diff --git a/CHANGES.2 b/CHANGES.2 new file mode 100644 index 0000000..1e742f3 --- /dev/null +++ b/CHANGES.2 @@ -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 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 , loop back into the node, +and try to connect to the same 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 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! + +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@.ampr.org:/uronode$ +netrom : - 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 diff --git a/COLORS b/COLORS new file mode 100644 index 0000000..ba14b9b --- /dev/null +++ b/COLORS @@ -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 + diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/COPYING @@ -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. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/FAQ b/FAQ new file mode 100644 index 0000000..3376db7 --- /dev/null +++ b/FAQ @@ -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. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..3bf51a6 --- /dev/null +++ b/INSTALL @@ -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 + + 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 +} diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..750e546 --- /dev/null +++ b/Makefile.in @@ -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 diff --git a/Makefile.include.in b/Makefile.include.in new file mode 100644 index 0000000..aca87b5 --- /dev/null +++ b/Makefile.include.in @@ -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@ \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..974b485 --- /dev/null +++ b/README @@ -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 | (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 + Config file: flexd.conf: + MyCall # the callsign used during the connection + PollInterval # how often the destinations are downloaded + FlexGate # 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 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 + :::[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. diff --git a/URONode.his b/URONode.his new file mode 100644 index 0000000..48ca670 --- /dev/null +++ b/URONode.his @@ -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! diff --git a/axcalluser.c b/axcalluser.c new file mode 100644 index 0000000..107a285 --- /dev/null +++ b/axcalluser.c @@ -0,0 +1,77 @@ +/* axcalluser.c - determine username corresponding to callsign */ +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/axcalluser.h b/axcalluser.h new file mode 100644 index 0000000..f802c30 --- /dev/null +++ b/axcalluser.h @@ -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 diff --git a/axdigi.c b/axdigi.c new file mode 100644 index 0000000..252d7e5 --- /dev/null +++ b/axdigi.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +/* below added by N1URO */ +#include +#include +#include + +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 */ +} + diff --git a/cmdparse.c b/cmdparse.c new file mode 100644 index 0000000..298b1cf --- /dev/null +++ b/cmdparse.c @@ -0,0 +1,300 @@ +#include +#include +#include + + +#include +#include +#include +#include + +#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;nnext) { + 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); + } +} diff --git a/command.c b/command.c new file mode 100644 index 0000000..53fbcbb --- /dev/null +++ b/command.c @@ -0,0 +1,1058 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "node.h" +#include "procinfo.h" +#include "sysinfo.h" + +struct cmd *Nodecmds = NULL; + +void init_nodecmds(void) +{ + add_internal_cmd(&Nodecmds, "?", 1, do_help); + add_internal_cmd(&Nodecmds, "Bye", 1, do_bye); + add_internal_cmd(&Nodecmds, "Escape", 1, do_escape); + if (User.ul_type == AF_INET) { + add_internal_cmd(&Nodecmds, "EXit", 1, do_bye); + } + add_internal_cmd(&Nodecmds, "Help", 1, do_help); + add_internal_cmd(&Nodecmds, "Info", 1, do_help); + add_internal_cmd(&Nodecmds, "Quit", 1, do_bye); + add_internal_cmd(&Nodecmds, "Status", 1, do_status); + add_internal_cmd(&Nodecmds, "Version", 1, do_version); +#ifdef HAVEMOTD + add_internal_cmd(&Nodecmds, "Who", 1, do_last); +#endif + add_internal_cmd(&Nodecmds, "MSg", 2, do_msg); +#ifdef HAVE_AX25 + add_internal_cmd(&Nodecmds, "Connect", 1, do_connect); + add_internal_cmd(&Nodecmds, "Links", 1, do_links); + add_internal_cmd(&Nodecmds, "INTerfaces", 3, do_ports); + add_internal_cmd(&Nodecmds, "SEssions", 2, do_sessions); + add_internal_cmd(&Nodecmds, "Users", 1, nuser_list); +#ifdef HAVE_FLEX + add_internal_cmd(&Nodecmds, "Desti", 1, do_dest); +#endif +#ifdef HAVE_MHEARD + add_internal_cmd(&Nodecmds, "MHeard", 2, do_mheard); +#endif +#ifdef HAVE_NETROM + add_internal_cmd(&Nodecmds, "Nodes", 1, do_nodes); + add_internal_cmd(&Nodecmds, "Routes", 1, do_routes); +#endif +#endif +#ifdef HAVE_TCPIP + add_internal_cmd(&Nodecmds, "Finger", 1, do_finger); + add_internal_cmd(&Nodecmds, "HOst", 2, do_host); + add_internal_cmd(&Nodecmds, "Ping", 1, do_ping); + add_internal_cmd(&Nodecmds, "Telnet", 1, do_connect); +#endif +#ifdef HAVE_ZLIB_H + add_internal_cmd(&Nodecmds, "ZConnect", 1, do_connect); + add_internal_cmd(&Nodecmds, "ZTelnet", 1, do_connect); +#endif +}; + +void node_prompt(const char *fmt, ...) +{ + 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,"\r\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,"\r\n%s@%s:/uronode$ ", User.call, HostName); + } + if ((User.ul_type == AF_AX25) && (check_perms(PERM_ANSI, 0L) != -1)) { + axio_printf(NodeIo,"\b\e[01;33m"); + } + if (User.ul_type == AF_AX25) { + axio_printf(NodeIo,"%s",Prompt); + } + if ((User.ul_type == AF_ROSE) && (check_perms(PERM_ANSI, 0L) == -1)) { + axio_printf(NodeIo,"\r-=> "); + } + if ((User.ul_type == AF_ROSE) && (check_perms(PERM_ANSI, 0L) != -1)) { + axio_printf(NodeIo,"\r\e[01;35m-=>\e[0m \b"); + } + axio_flush(NodeIo); +} + +void node_logout(char *reason) +{ +#ifdef HAVEMOTD + if (User.ul_type == AF_INET) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[03;36m"); + } + axio_printf(NodeIo, "Thank you %s, for connecting to the \n%s URONode packet shell.\n", User.call, HostName); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + } + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,""); + } + if (User.ul_type == AF_ROSE) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[03;36m"); + } + axio_printf(NodeIo, "%s, thank you for connecting to the %s\nURONode ROSE network node. Come back again soon, 73!\r ", User.call, RoseId); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m\b"); + } + } else + if ((User.ul_type == AF_FLEXNET) || (User.ul_type == AF_AX25)) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[03;36m"); + } + axio_printf(NodeIo, "%s de %s\n73! ", User.call, FlexId); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m\b"); + } + } +#endif + axio_flush(NodeIo); + axio_end_all(); + logout_user(); + ipc_close(); + node_log(LOGLVL_LOGIN, "%s @ %s logged out", User.call, User.ul_name); + node_log(LOGLVL_LOGIN, "%s %s", NodeId, reason); + free_cmdlist(Nodecmds); + Nodecmds = NULL; + exit(0); +} + +int do_bye(int argc, char **argv) +{ + node_logout("User hit bye or quit"); + return 0; /* Keep gcc happy */ +} + +int do_escape(int argc, char **argv) +{ + int now = 0; + + if (argc > 1) { + EscChar = get_escape(argv[1]); + now = 1; + } + if (EscChar < -1 || EscChar > 255) { + if (User.ul_type == AF_NETROM) { + node_msg("%s} ", NodeId); + } + node_msg("Invalid escape character: %s", argv[1]); + return 0; + } + + if (EscChar == -1) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo, "%s} ", NodeId); + } + axio_printf(NodeIo,"The escape mechanism is %sdisabled", now ? "now " : ""); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo, "%s} ", NodeId); + } + axio_printf(NodeIo,"The escape character is %s%s%c", + now ? "now " : "", + EscChar < 32 ? "CTRL-" : "", + EscChar < 32 ? (EscChar + 'A' - 1) : EscChar); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +int do_help(int argc, char **argv) +{ + FILE *fp; + char fname[256], line[256]; + struct cmd *cmdp; + int i = 0; + + if (*argv[0] == '?') { /* "?" */ + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo, "%s} ", NodeId); + } + if (User.ul_type == AF_INET) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;37m"); + } + axio_printf(NodeIo, "Shell "); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;37m"); + } + axio_printf(NodeIo,"Commands:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + for (cmdp = Nodecmds; cmdp != NULL; cmdp = cmdp->next) { + axio_printf(NodeIo,"%s%s", i ? ", " : "\n", cmdp->name); + if (++i == 10) { + axio_printf(NodeIo,""); + i = 0; + } + } + if (i) axio_printf(NodeIo,""); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + if (argv[1] && strchr(argv[1], '/')) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + node_msg("Invalid command %s", argv[1]); + return 0; + } + if (*argv[0] == 'i') { /* "info" */ + strcpy(fname, CONF_NODE_INFO_FILE); + 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,"System Information:\n"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + axio_printf(NodeIo,"%s - %s \n", VERSION, COMPILING); + } else if (!argv[1]) { /* "help" */ + strcpy(fname, DATA_NODE_HELP_DIR "help.hlp"); + } else { /* "help " */ + strlwr(argv[1]); + snprintf(fname, sizeof(fname), DATA_NODE_HELP_DIR "%s.hlp", argv[1]); + fname[sizeof(fname) - 1] = 0; + } + if ((fp = fopen(fname, "r")) == NULL) { + if (*argv[0] != 'i') + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"No help for command %s", argv[1] ? argv[1] : "help"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (*argv[0] != 'i') + node_msg("Help for command %s", argv[1] ? argv[1] : "help"); + while (fgets(line, 256, fp) != NULL) + axio_puts(line,NodeIo); + fclose(fp); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +int do_host(int argc, char **argv) +{ + struct hostent *h; + struct in_addr addr; + char **p, *cp; + + if (argc < 2) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + node_msg("Usage: host |"); + return 0; + } + if (inet_aton(argv[1], &addr) != 0) + h = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); + else + h = gethostbyname(argv[1]); + if (h == NULL) { + switch (h_errno) { + case HOST_NOT_FOUND: + cp = "Unknown host"; + break; + case TRY_AGAIN: + cp = "Temporary name server error"; + break; + case NO_RECOVERY: + cp = "Non-recoverable name server error"; + break; + case NO_ADDRESS: + cp = "No address"; + break; + default: + cp = "Unknown error"; + break; + } + node_msg("%s", cp); + return 0; + } + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + node_msg("Host name information for %s:", argv[1]); + axio_printf(NodeIo,"Hostname: %s", h->h_name); + axio_puts("\nAliases: ",NodeIo); + p = h->h_aliases; + while (*p != NULL) { + axio_printf(NodeIo," %s", *p); + p++; + } + axio_puts("\nAddress(es):",NodeIo); + p = h->h_addr_list; + while (*p != NULL) { + addr.s_addr = ((struct in_addr *)(*p))->s_addr; + axio_printf(NodeIo," %s", inet_ntoa(addr)); + p++; + } + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +int do_ports(int argc, char **argv) +{ + struct proc_ax25 *ax, *ax_list; + struct proc_dev *dev, *dev_list; + char *cp = NULL; + int n, tx, rx; + + ax_list=read_proc_ax25(); + dev_list=read_proc_dev(); + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;35m"); + } + node_msg("Interfaces:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + axio_printf(NodeIo,"Name Description QSO RX packets TX packets\n"); + axio_printf(NodeIo,"------- ------------------------------------------ ---- ----------- -----------"); + while ((cp = ax25_config_get_next(cp)) != NULL) { + n=0; + if (ax_list) for (ax=ax_list;ax!=NULL;ax=ax->next) { + // if (strcmp(ax25_config_get_name(ax->dev), cp)==0 && strcmp(ax->dest_addr, "*")!=0) n++; + if (strcmp(ax->dest_addr, "*")!=0 && strcmp(ax25_config_get_name(ax->dev), cp)==0) n++; + } + tx=0; rx=0; + if (dev_list) for (dev=dev_list;dev!=NULL;dev=dev->next) { + if (strcmp(dev->interface, ax25_config_get_dev(cp))==0) { + tx=dev->tx_packets; + rx=dev->rx_packets; + } + } + if (is_hidden(cp) && check_perms(PERM_HIDDEN, 0L) == -1) + continue; + axio_printf(NodeIo,"\n%-7.7s %-42.42s %4d %11d %11d", cp, ax25_config_get_desc(cp), n, rx, tx); + } + + free_proc_ax25(ax_list); + free_proc_dev(dev_list); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +int do_sessions(int argc, char **argv) +{ + struct proc_ax25 *ax_p, *ax_list; +#ifdef HAVE_NETROM + struct proc_nr *nr_p, *nr_list; +#endif + char *cp; + + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} %s\n", NodeId, VERSION); + } + if ((ax_list = read_proc_ax25()) == NULL) { + if (errno) node_perror("sessions: read_proc_ax25:", errno); + else axio_printf (NodeIo,"No such AX25 sessions actives."); + + } else { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;33m"); + } + node_msg("AX.25 Sessions:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + axio_printf(NodeIo,"Int. Dest addr Src addr State Unack T1 Retr Rtt Snd-Q Rcv-Q\n"); + axio_printf(NodeIo,"------- --------- --------- ------------ ----- ------- ------ --- ----- -----\n"); + for (ax_p = ax_list; ax_p != NULL; ax_p = ax_p->next) { + if (argc > 1 && strcasecmp(argv[1], "*") && strcasecmp(ax_p->dest_addr, argv[1]) && + strcasecmp(ax_p->src_addr, argv[1])) continue; + if ((argc < 2) && !strcmp(ax_p->dest_addr, "*")) + continue; + cp = ax25_config_get_name(ax_p->dev); + axio_printf(NodeIo,"%-7s %-9s %-9s ", cp, ax_p->dest_addr, ax_p->src_addr); + if (!strcmp(ax_p->dest_addr, "*")) { + axio_printf(NodeIo,"Listening\n"); + continue; + } + switch (ax_p->st) { + case 0: + cp = "Disconnected"; + break; + case 1: + cp = "Conn pending"; + break; + case 2: + cp = "Disc pending"; + break; + case 3: + cp = "Connected "; + break; + case 4: + cp = "Recovery "; + break; + default: + cp = "Unknown "; + break; + } + axio_printf(NodeIo,"%s %02d/%02d %03d/%03d %02d/%03d %3d %5ld %5ld\n", + cp, + ax_p->vs < ax_p->va ? ax_p->vs - ax_p->va + 8 : ax_p->vs - ax_p->va, + ax_p->window, + ax_p->t1timer, ax_p->t1, + ax_p->n2count, ax_p->n2, + ax_p->rtt, + ax_p->sndq, ax_p->rcvq); + } + free_proc_ax25(ax_list); + axio_puts("",NodeIo); + } + +#ifdef HAVE_NETROM + if ((nr_list = read_proc_nr()) == NULL) { + if (errno) node_perror("sessions: read_proc_nr", errno); + else axio_printf (NodeIo,"No such NET/ROM sessions actives.\n"); + } else { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;36m"); + } + node_msg("\nNET/ROM Sessions:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + axio_printf(NodeIo,"User addr Dest node Src node State Unack T1 Retr Snd-Q Rcv-Q\n"); + axio_printf(NodeIo,"--------- --------- --------- ------------ ----- ------- ------ ----- -----"); + for (nr_p = nr_list; nr_p != NULL; nr_p = nr_p->next) { + if (argc > 1 && strcasecmp(argv[1], "*") && strcasecmp(nr_p->user_addr, argv[1]) && + strcasecmp(nr_p->dest_node, argv[1]) && strcasecmp(nr_p->src_node, argv[1])) continue; + if ((argc < 2) && !strcmp(nr_p->user_addr, "*")) continue; + cp = nr_config_get_name(nr_p->dev); + axio_printf(NodeIo,"\n%-9s %-9s %-9s ", nr_p->user_addr, nr_p->dest_node, nr_p->src_node); + if (!strcmp(nr_p->user_addr, "*")) { + axio_printf(NodeIo,"Listening\n"); + continue; + } + switch (nr_p->st) { + case 0: + cp = "Disconnected"; + break; + case 1: + cp = "Conn pending"; + break; + case 2: + cp = "Disc pending"; + break; + case 3: + cp = "Connected "; + break; + case 4: + cp = "Recovery "; + break; + default: + cp = "Unknown "; + break; + } + axio_printf(NodeIo,"%s %02d/%02d %03d/%03d %02d/%03d %5ld %5ld", + cp, + nr_p->vs < nr_p->va ? nr_p->vs - nr_p->va + 8 : nr_p->vs - nr_p->va, + nr_p->window, + nr_p->t1timer, nr_p->t1, + nr_p->n2count, nr_p->n2, + nr_p->sndq, nr_p->rcvq); + } + free_proc_nr(nr_list); + } + +#endif + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +int do_routes(int argc, char **argv) +{ + struct proc_nr *nr, *nr_list; + struct proc_nr_neigh *nrh, *nrh_list; + struct proc_nr_nodes *nrn, *nrn_list; + struct proc_ax25 *ap; + char *cp, portcall[10]; + int link, n; + + nr_list=read_proc_nr(); + nrn_list=read_proc_nr_nodes(); + if ((nrh_list = read_proc_nr_neigh()) == NULL) { + if (errno) node_perror("do_routes: read_proc_nr_neigh", errno); + else + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf (NodeIo,"No such routes"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + free_proc_nr_neigh(nrh_list); + free_proc_nr_nodes(nrn_list); + free_proc_nr(nr_list); + + return 0; + } + /* if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;33m"); + } */ + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;36m"); + } + node_msg("Routes:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + axio_printf(NodeIo,"Link Intface Callsign Qual Nodes Lock QSO\n"); + axio_printf(NodeIo,"---- ------- --------- ---- ----- ---- ---"); + strcpy(portcall,nr_config_get_addr(nr_config_get_next(NULL))); + if (strchr(portcall, '-')==NULL) strcat(portcall, "-0"); + for (nrh = nrh_list; nrh != NULL; nrh = nrh->next) { + link=0; n=0; + if ((ap = find_link(portcall, nrh->call, nrh->dev)) != NULL && ap->st >= 3) link = 1; + if ((ap = find_link(nrh->call, portcall, nrh->dev)) != NULL && ap->st >= 3) link = 2; + cp = ax25_config_get_name(nrh->dev); + + if (nr_list) for (nr=nr_list;nr!=NULL;nr=nr->next) { + if (strcmp(nr->dest_node, nrh->call)==0) { + n++; + } else { + if (nrn_list) for(nrn=nrn_list;nrn!=NULL;nrn=nrn->next) { + if (strcmp(nrn->call, nr->dest_node)==0) { + switch(nrn->w) { + case 1: if (nrn->addr1==nrh->addr) n++; break; + case 2: if (nrn->addr2==nrh->addr) n++; break; + case 3: if (nrn->addr3==nrh->addr) n++; break; + } + } + } + } + } + + axio_printf(NodeIo,"\n%c %-7s %-9s %4d %5d %c %4d", + link == 0 ? ' ' : '>', + cp, + nrh->call, + nrh->qual, + nrh->cnt, + nrh->lock == 1 ? '!' : ' ', + n); + } + + free_proc_nr_neigh(nrh_list); + free_proc_nr_nodes(nrn_list); + free_proc_nr(nr_list); + free_proc_ax25(ap); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +int do_nodes(int argc, char **argv) +{ + struct proc_nr_nodes *p, *list; + struct proc_nr_neigh *np, *nlist; + int i = 0; + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if ((list = read_proc_nr_nodes()) == NULL) { + if (errno) + node_perror("do_nodes: read_proc_nr_nodes", errno); + else + axio_printf(NodeIo,"No known nodes"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + /* "nodes" */ + if (argc == 1) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;36m"); + } else if (check_perms(PERM_ANSI, 0L) == -1) { + axio_printf(NodeIo, ""); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;36m"); + } + node_msg("Nodes:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + for (p = list; p != NULL; p = p->next) { + axio_printf(NodeIo,"%-16.16s %c",print_node(p->alias, p->call),(++i % 4) ? ' ' : '\n'); + } + if ((User.ul_type == AF_NETROM) && (i % 4) != 0) { + node_msg(""); + } + free_proc_nr_nodes(list); + return 0; + } + if ((nlist = read_proc_nr_neigh()) == NULL) { + node_perror("do_nodes: read_proc_nr_neigh", errno); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + /* "nodes *" */ + if (*argv[1] == '*') { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;36m"); + } + + node_msg("Detailed nodes listing:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + axio_printf(NodeIo,"Node Qual Obs Intface Neighbour\n"); + axio_printf(NodeIo,"----------------- ---- --- ------- ---------"); + for (p = list; p != NULL; p = p->next) { + axio_printf(NodeIo,"\n%-16.16s ", print_node(p->alias, p->call)); + if ((np = find_neigh(p->addr1, nlist)) != NULL) { + axio_printf(NodeIo,"%4d %3d %-7s %s",p->qual1,p->obs1,ax25_config_get_name(np->dev),np->call); + } + else if (p->n > 1 && (np = find_neigh(p->addr2, nlist)) != NULL) { + axio_printf(NodeIo," "); + axio_printf(NodeIo,"%7d %12d %-7s %s",p->qual2, p->obs2,ax25_config_get_name(np->dev),np->call); + } + else if (p->n > 2 && (np = find_neigh(p->addr3, nlist)) != NULL) { + axio_printf(NodeIo," "); + axio_printf(NodeIo,"%7d %12d %-7s %s",p->qual3, p->obs3,ax25_config_get_name(np->dev),np->call); + } + else if (p->n == 0) axio_puts("",NodeIo); + } + free_proc_nr_nodes(list); + free_proc_nr_neigh(nlist); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + /* "nodes " */ + p = find_node(argv[1], list); + if (p != NULL) { + if (p->n == 0) axio_printf(NodeIo,"Local node without routes: %s", print_node(p->alias, p->call)); + else { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;36m"); + } + node_msg("Routes to: %s", print_node(p->alias, p->call)); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + axio_printf(NodeIo,"Which Qual Obs Intface Neighbour\n"); + axio_printf(NodeIo,"----- ---- --- ------- ---------"); + + if ((np = find_neigh(p->addr1, nlist)) != NULL) { + axio_printf(NodeIo,"\n%c %4d %3d %-7s %s",p->w == 1 ? '>' : ' ',p->qual1,p->obs1, + ax25_config_get_name(np->dev),np->call); + } + if (p->n > 1 && (np = find_neigh(p->addr2, nlist)) != NULL) { + axio_printf(NodeIo,"\n%c %4d %3d %-7s %s",p->w == 2 ? '>' : ' ',p->qual2, p->obs2, + ax25_config_get_name(np->dev),np->call); + } + if (p->n > 1 && (np = find_neigh(p->addr3, nlist)) != NULL) { + axio_printf(NodeIo,"\n%c %4d %3d %-7s %s",p->w == 3 ? '>' : ' ',p->qual3, p->obs3, + ax25_config_get_name(np->dev),np->call); + } + } + } else { + axio_printf(NodeIo,"No such node"); + } + free_proc_nr_nodes(list); + free_proc_nr_neigh(nlist); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +/* + * by Heikki Hannikainen + * The following was mostly learnt from the procps package and the + * gnu sh-utils (mainly uname). + */ +int do_status(int argc, char **argv) +{ + int upminutes, uphours, updays; + double uptime_secs, idle_secs; + double av[3]; + unsigned **mem; + struct utsname name; + time_t t; +#ifdef HAVE_AX25 + struct flex_dst *fd, *fd_list; + struct ax_routes *ar, *ar_list; + struct proc_ax25 *ax, *ax_list; +#ifdef HAVE_NETROM + struct proc_nr *nr, *nr_list; + struct proc_nr_nodes *nop, *nolist; + struct proc_nr_neigh *nep, *nelist; + int n, r, nn; +#endif + int na, nl, nd; +#endif + int ma, mu, mf, sa, su, sf; + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;37m"); + } + node_msg("Status:"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + time(&t); + axio_printf(NodeIo,"System time: %s", ctime(&t)); + if (uname(&name) == -1) axio_printf(NodeIo,"Cannot get system name\n"); + else { + axio_printf(NodeIo,"Hostname: %s\n", HostName); + axio_printf(NodeIo,"Operating system: %s %s (%s)\n", name.sysname, name.release, name.machine); + } + /* read and calculate the amount of uptime and format it nicely */ + uptime(&uptime_secs, &idle_secs); + updays = (int) uptime_secs / (60*60*24); + upminutes = (int) uptime_secs / 60; + uphours = upminutes / 60; + uphours = uphours % 24; + upminutes = upminutes % 60; + axio_printf(NodeIo,"Uptime: "); + if (updays) axio_printf(NodeIo,"%d day%s, ", updays, (updays != 1) ? "s" : ""); + if(uphours) axio_printf(NodeIo,"%d hour%s ", uphours, (uphours != 1) ? "s" : ""); + axio_printf(NodeIo,"%d minute%s\n", upminutes, (upminutes != 1) ? "s" : ""); + loadavg(&av[0], &av[1], &av[2]); + axio_printf(NodeIo,"Load average: %.2f, %.2f, %.2f\n", av[0], av[1], av[2]); + axio_printf(NodeIo,"Users: %d node, %d system\n", user_count(), system_user_count()); + + if (!(mem = meminfo()) || mem[meminfo_main][meminfo_total] == 0) { + /* cannot normalize mem usage */ + axio_printf(NodeIo,"Cannot get memory information!\n"); + } else { + ma = mem[meminfo_main][meminfo_total]; + mu = (mem[meminfo_main][meminfo_total] - mem[meminfo_free][meminfo_total]); + mf = mem[meminfo_free][meminfo_total]; + axio_printf(NodeIo,"Memory: Available Used Free perc. Used\n"); + axio_printf(NodeIo,"------------------ ---------- ---------- ---------- ----------\n"); + axio_printf(NodeIo,"Physical: %-7d kB %-7d kB %-7d kB %3d %%\n", ma, mu, mf, (mu*100)/ma); + + if (!(mem = meminfo()) || mem[meminfo_stotal][meminfo_total] != 0) +{ + sa = mem[meminfo_stotal][meminfo_total]; + su = (mem[meminfo_stotal][meminfo_total] - mem[meminfo_sfree][meminfo_total]); + sf = mem[meminfo_sfree][meminfo_total]; + axio_printf(NodeIo,"Swap: %-7d kB %-7d kB %-7d kB %3d %%\n",sa,su,sf,(su*100)/sa); + } + else +/* axio_printf(NodeIo,"Cannot get swap information!\n"); */ + axio_printf(NodeIo," "); + + } + +#ifdef HAVE_AX25 +#ifdef HAVE_NETROM + if ((nolist = read_proc_nr_nodes()) == NULL && errno != 0) + node_perror("sessions: read_proc_nr_nodes", errno); + n = 0; + for (nop = nolist; nop != NULL; nop = nop->next) + n++; + free_proc_nr_nodes(nolist); + if ((nelist = read_proc_nr_neigh()) == NULL && errno != 0) + node_perror("sessions: read_proc_nr_neigh", errno); + r = 0; + for (nep = nelist; nep != NULL; nep = nep->next) + r++; + free_proc_nr_neigh(nelist); +#endif + na=0; + ax_list=read_proc_ax25(); + if (ax_list) for (ax=ax_list;ax!=NULL;ax=ax->next) { + if (strcmp(ax->dest_addr, "*")==0) continue; + na++; + } + free_proc_ax25(ax_list); +#ifdef HAVE_NETROM + nn=0; + nr_list=read_proc_nr(); + if (nr_list) for (nr=nr_list;nr!=NULL;nr=nr->next) { + if (strcmp(nr->dest_node, "*")==0) continue; + nn++; + } + free_proc_nr(nr_list); +#endif + nl=0; + ar_list=read_ax_routes(); + if (ar_list) for (ar=ar_list;ar!=NULL;ar=ar->next) { + nl++; + } + free_ax_routes(ar_list); + nd=0; + fd_list=read_flex_dst(); + if (fd_list) for (fd=fd_list;fd!=NULL;fd=fd->next) { + nd++; + } + free_flex_dst(fd_list); + + axio_printf(NodeIo,"Sockets: Sessions Dest/Nodes Links/Routes\n"); + axio_printf(NodeIo,"------------------ ---------- ---------- ------------\n"); + axio_printf(NodeIo,"AX25: %-10d %-10d %-10d\n",na,nd,nl); +#ifdef HAVE_NETROM + axio_printf(NodeIo,"NET/ROM: %-10d %-10d %-10d",nn,n,r); +#endif +#endif + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; +} + +int do_version(int argc, char **argv) +{ + if (User.ul_type != AF_NETROM) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;37mShell : %s\n\e[01;35mHostname : %s\n\e[01;33max25/Flex: %s\n\e[01;36mNetRom : %s\n\e[01;35mRose : %s \e[0;m", VERSION, HostName, FlexId, NodeId, RoseId); + return 0; + } + if (check_perms(PERM_ANSI, 0L) == -1) { + axio_printf(NodeIo,"Shell : %s\nHostname : %s\nax25/Flex: %s\nNetRom : %s\nRose : %s", VERSION, HostName, FlexId, NodeId, RoseId); + return 0; + } + /* + if (User.ul_type != AF_NETROM) { + axio_printf(NodeIo, "Version : %s\nax25/Flex: %s\nNetRom : %s", VERSION, FlexId, NodeId); + return 0; + } + */ + } else + axio_printf(NodeIo,"%s} ", NodeId); + if (check_perms(PERM_ANSI ,0L) != -1) { + axio_printf(NodeIo,"\e[01;37m"); + } + axio_printf(NodeIo,"%s", VERSION); + node_msg(""); + if (check_perms(PERM_ANSI ,0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + return 0; +} +int nuser_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} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;37m"); + } + if (User.ul_type == AF_NETROM) { + /* axio_printf(NodeIo, "\e[0;m%s} %s", NodeId, VERSION); */ + axio_printf(NodeIo, "%s", VERSION); + } else { + axio_printf(NodeIo, "Current users:"); + } + if (user_count() == 0) { + axio_printf(NodeIo, " No users online.\n"); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + 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; + } + axio_puts("",NodeIo); + } + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + fclose(f); + return 0; +} diff --git a/config.c b/config.c new file mode 100644 index 0000000..f222db6 --- /dev/null +++ b/config.c @@ -0,0 +1,485 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* axutils.h needs this... */ +#include +#include +#include + +#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; +} diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..76a7e9e --- /dev/null +++ b/config.h.in @@ -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 diff --git a/configure b/configure new file mode 100755 index 0000000..68fde56 --- /dev/null +++ b/configure @@ -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 + +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 + +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 + +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 diff --git a/etc/axdigi.conf b/etc/axdigi.conf new file mode 100644 index 0000000..55c809d --- /dev/null +++ b/etc/axdigi.conf @@ -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 +# diff --git a/etc/flexd.conf b/etc/flexd.conf new file mode 100644 index 0000000..b9e9190 --- /dev/null +++ b/etc/flexd.conf @@ -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-# diff --git a/etc/gateways b/etc/gateways new file mode 100644 index 0000000..e69de29 diff --git a/etc/help/bye.hlp b/etc/help/bye.hlp new file mode 100644 index 0000000..9359a79 --- /dev/null +++ b/etc/help/bye.hlp @@ -0,0 +1,6 @@ + +USAGE + Bye + +DESCRIPTION + Disconnects you from this node. \ No newline at end of file diff --git a/etc/help/color.hlp b/etc/help/color.hlp new file mode 100644 index 0000000..443c251 --- /dev/null +++ b/etc/help/color.hlp @@ -0,0 +1,18 @@ + +USAGE + + +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 diff --git a/etc/help/connect.hlp b/etc/help/connect.hlp new file mode 100644 index 0000000..1fad0aa --- /dev/null +++ b/etc/help/connect.hlp @@ -0,0 +1,25 @@ + +USAGE + Connect [s|d] For NET/ROM or Links + Connect [via ...] [s|d] For AX25 + Connect
[] [d|s] For ROSE + Connect [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 diff --git a/etc/help/desti.hlp b/etc/help/desti.hlp new file mode 100644 index 0000000..5a92410 --- /dev/null +++ b/etc/help/desti.hlp @@ -0,0 +1,14 @@ + +USAGE + Dest [*|] + +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. \ No newline at end of file diff --git a/etc/help/escape.hlp b/etc/help/escape.hlp new file mode 100644 index 0000000..24f9bb4 --- /dev/null +++ b/etc/help/escape.hlp @@ -0,0 +1,16 @@ + +USAGE + Escape + +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: + + 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 \ No newline at end of file diff --git a/etc/help/finger.hlp b/etc/help/finger.hlp new file mode 100644 index 0000000..a5ac691 --- /dev/null +++ b/etc/help/finger.hlp @@ -0,0 +1,13 @@ + +USAGE + Finger [][@] + +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 \ No newline at end of file diff --git a/etc/help/help.hlp b/etc/help/help.hlp new file mode 100644 index 0000000..25afe58 --- /dev/null +++ b/etc/help/help.hlp @@ -0,0 +1,10 @@ + +USAGE + Help [] + +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. diff --git a/etc/help/host.hlp b/etc/help/host.hlp new file mode 100644 index 0000000..cbf64fe --- /dev/null +++ b/etc/help/host.hlp @@ -0,0 +1,11 @@ + +USAGE + Host | + +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). \ No newline at end of file diff --git a/etc/help/info.hlp b/etc/help/info.hlp new file mode 100644 index 0000000..4ee8cb9 --- /dev/null +++ b/etc/help/info.hlp @@ -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. diff --git a/etc/help/links.hlp b/etc/help/links.hlp new file mode 100644 index 0000000..66480d3 --- /dev/null +++ b/etc/help/links.hlp @@ -0,0 +1,16 @@ + +USAGE + Links [ d | n | v | ] + +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. \ No newline at end of file diff --git a/etc/help/mail.hlp b/etc/help/mail.hlp new file mode 100644 index 0000000..003272c --- /dev/null +++ b/etc/help/mail.hlp @@ -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. + diff --git a/etc/help/message.hlp b/etc/help/message.hlp new file mode 100644 index 0000000..44fe46d --- /dev/null +++ b/etc/help/message.hlp @@ -0,0 +1,14 @@ + +USAGE + MEssage + +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. + diff --git a/etc/help/mheard.hlp b/etc/help/mheard.hlp new file mode 100644 index 0000000..4a08386 --- /dev/null +++ b/etc/help/mheard.hlp @@ -0,0 +1,8 @@ + +USAGE + Mheard [] + +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. \ No newline at end of file diff --git a/etc/help/msg.hlp b/etc/help/msg.hlp new file mode 100644 index 0000000..1700183 --- /dev/null +++ b/etc/help/msg.hlp @@ -0,0 +1,15 @@ + +USAGE + MSg + +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! diff --git a/etc/help/netstat.hlp b/etc/help/netstat.hlp new file mode 100644 index 0000000..54f598a --- /dev/null +++ b/etc/help/netstat.hlp @@ -0,0 +1,7 @@ + +USAGE + NEtstat + +DESCRIPTION + Gives a list of active TCP/IP connections to and from the local + host. \ No newline at end of file diff --git a/etc/help/nodes.hlp b/etc/help/nodes.hlp new file mode 100644 index 0000000..93005de --- /dev/null +++ b/etc/help/nodes.hlp @@ -0,0 +1,15 @@ + +USAGE + Nodes [*|] + +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. diff --git a/etc/help/ping.hlp b/etc/help/ping.hlp new file mode 100644 index 0000000..30eb4ac --- /dev/null +++ b/etc/help/ping.hlp @@ -0,0 +1,15 @@ + +USAGE + PIng [] + +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 diff --git a/etc/help/ports.hlp b/etc/help/ports.hlp new file mode 100644 index 0000000..959db42 --- /dev/null +++ b/etc/help/ports.hlp @@ -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. \ No newline at end of file diff --git a/etc/help/quit.hlp b/etc/help/quit.hlp new file mode 100644 index 0000000..58cd7bc --- /dev/null +++ b/etc/help/quit.hlp @@ -0,0 +1,6 @@ + +USAGE + Quit + +DESCRIPTION + Disconnects you from this node. diff --git a/etc/help/rose.hlp b/etc/help/rose.hlp new file mode 100644 index 0000000..69c1f6e --- /dev/null +++ b/etc/help/rose.hlp @@ -0,0 +1,2 @@ + +c n1uro-8 3100860906 diff --git a/etc/help/routes.hlp b/etc/help/routes.hlp new file mode 100644 index 0000000..e1bf3ff --- /dev/null +++ b/etc/help/routes.hlp @@ -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 \ No newline at end of file diff --git a/etc/help/sessions.hlp b/etc/help/sessions.hlp new file mode 100644 index 0000000..ecd55ce --- /dev/null +++ b/etc/help/sessions.hlp @@ -0,0 +1,10 @@ + +USAGE + SEssions [* | ] + +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 . diff --git a/etc/help/status.hlp b/etc/help/status.hlp new file mode 100644 index 0000000..44c18c7 --- /dev/null +++ b/etc/help/status.hlp @@ -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. diff --git a/etc/help/telnet.hlp b/etc/help/telnet.hlp new file mode 100644 index 0000000..26f474f --- /dev/null +++ b/etc/help/telnet.hlp @@ -0,0 +1,26 @@ + +USAGE + Telnet [] [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 diff --git a/etc/help/users.hlp b/etc/help/users.hlp new file mode 100644 index 0000000..8ac0cb1 --- /dev/null +++ b/etc/help/users.hlp @@ -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. diff --git a/etc/help/version.hlp b/etc/help/version.hlp new file mode 100644 index 0000000..a17ce1a --- /dev/null +++ b/etc/help/version.hlp @@ -0,0 +1,6 @@ + +USAGE + Version + +DESCRIPTION + Displays the software version information, diff --git a/etc/help/who.hlp b/etc/help/who.hlp new file mode 100644 index 0000000..8e8eef9 --- /dev/null +++ b/etc/help/who.hlp @@ -0,0 +1,8 @@ + +USAGE + Who ( | *) + +DESCRIPTION + Shows a list when the user with the callsign last + connected to this node. Use the asterisk to print out + the entire log table. diff --git a/etc/help/zconnect.hlp b/etc/help/zconnect.hlp new file mode 100644 index 0000000..c58fff0 --- /dev/null +++ b/etc/help/zconnect.hlp @@ -0,0 +1,23 @@ + +USAGE + ZConnect [s|d] For NET/ROM or Links + ZConnect [via ...] [s|d] For AX25 + ZConnect
[] [d|s] For ROSE + ZConnect [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. diff --git a/etc/help/ztelnet.hlp b/etc/help/ztelnet.hlp new file mode 100644 index 0000000..e4b36ee --- /dev/null +++ b/etc/help/ztelnet.hlp @@ -0,0 +1,25 @@ + +USAGE + ZTelnet [] [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 diff --git a/etc/lastlog b/etc/lastlog new file mode 100644 index 0000000..e69de29 diff --git a/etc/loggedin b/etc/loggedin new file mode 100644 index 0000000..e69de29 diff --git a/etc/uronode.conf b/etc/uronode.conf new file mode 100644 index 0000000..e2af7f6 --- /dev/null +++ b/etc/uronode.conf @@ -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 + +# "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 diff --git a/etc/uronode.info b/etc/uronode.info new file mode 100644 index 0000000..f41b887 --- /dev/null +++ b/etc/uronode.info @@ -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. diff --git a/etc/uronode.motd b/etc/uronode.motd new file mode 100644 index 0000000..048cf8a --- /dev/null +++ b/etc/uronode.motd @@ -0,0 +1,4 @@ +This is copy of URONode is located in , +, [XX##xx] (grid) +Type "?" for commands or H for more detailed help on a command. +*** please edit /etc/ax25/uronode.motd to change this text diff --git a/etc/uronode.perms b/etc/uronode.perms new file mode 100644 index 0000000..fcbe6e8 --- /dev/null +++ b/etc/uronode.perms @@ -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 diff --git a/etc/uronode.routes b/etc/uronode.routes new file mode 100644 index 0000000..9b94f1e --- /dev/null +++ b/etc/uronode.routes @@ -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 d 'description' +# +#route n1uro-1 fxuro ax0 d 'N1URO FlexNet Hub' + +# Routing across another node with sending a string "C " +# route n 'description' +# +#route n1uro-14 WMASS ax0 n 'N1URO-NOS' n1uro-1 + +# Routing via digipeaters +# route v 'description' +# +#route n1uro-9 MACTFX ax0 v 'N1URO Xnet' n1uro-1 diff --git a/etc/uronode.users b/etc/uronode.users new file mode 100644 index 0000000..59d7dd0 --- /dev/null +++ b/etc/uronode.users @@ -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 diff --git a/extcmd.c b/extcmd.c new file mode 100644 index 0000000..e108cac --- /dev/null +++ b/extcmd.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/flexd.c b/flexd.c new file mode 100644 index 0000000..b82e5bd --- /dev/null +++ b/flexd.c @@ -0,0 +1,431 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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_timedigis[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;kdigis[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') { + /* 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; +} + diff --git a/gateway.c b/gateway.c new file mode 100644 index 0000000..603201d --- /dev/null +++ b/gateway.c @@ -0,0 +1,1131 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "procinfo.h" +#include "node.h" + +static void invert_ssid(char *out, char *in) +{ + char *cp; + + if ((cp = strchr(in, '-')) != NULL) { + *cp = 0; + sprintf(out, "%s-%d", in, 15 - atoi(cp + 1)); + *cp = '-'; + } else { + sprintf(out, "%s-15", in); + } +} + +/* + * Initiate a AX.25, NET/ROM, ROSE or TCP connection to the host + * specified by `address'. + */ +static ax25io *connect_to(char **addr, int family, int escape, int compr) +{ + int fd; + ax25io *riop; + fd_set read_fdset; + fd_set write_fdset; + int salen; + union { + struct full_sockaddr_ax25 ax; +#ifdef HAVE_ROSE + struct sockaddr_rose rs; +#endif + struct sockaddr_in in; + } sa; + char call[10], path[20], *cp, *eol; + int ret, retlen = sizeof(int); + int paclen; + struct hostent *hp; + struct servent *sp; + struct user u; +#ifdef HAVE_NETROM + struct proc_nr_nodes *np; +#endif + + strcpy(call, User.call); + /* + * Fill in protocol spesific stuff. + */ + switch (family) { +#ifdef HAVE_ROSE + case AF_ROSE: + if (aliascmd==0) { + if (check_perms(PERM_ROSE, 0L) == -1) { + axio_printf(NodeIo,"Permission denied"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + node_log(LOGLVL_GW, "Permission denied: rose"); + return NULL; + } + } + if ((fd = socket(AF_ROSE, SOCK_SEQPACKET, 0)) < 0) { + node_perror("connect_to: socket", errno); + return NULL; + } + sa.rs.srose_family = AF_ROSE; + sa.rs.srose_ndigis = 0; + ax25_aton_entry(call, sa.rs.srose_call.ax25_call); + rose_aton(rs_config_get_addr(NULL), sa.rs.srose_addr.rose_addr); + salen = sizeof(struct sockaddr_rose); + if (bind(fd, (struct sockaddr *)&sa, salen) == -1) { + node_perror("connect_to: bind", errno); + close(fd); + return NULL; + } + memset(path, 0, 11); + memcpy(path, rs_config_get_addr(NULL), 4); + salen = strlen(addr[1]); + if ((salen != 6) && (salen != 10)) + { + axio_printf(NodeIo,"Invalid ROSE address"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return(NULL); + } + memcpy(path + (10-salen), addr[1], salen); + sprintf(User.dl_name, "%s @ %s", addr[0], path); + sa.rs.srose_family = AF_ROSE; + sa.rs.srose_ndigis = 0; + if (ax25_aton_entry(addr[0], sa.rs.srose_call.ax25_call) < 0) { + close(fd); + return NULL; + } + if (rose_aton(path, sa.rs.srose_addr.rose_addr) < 0) { + close(fd); + return NULL; + } + if (addr[2] != NULL) { + if (ax25_aton_entry(addr[2], sa.rs.srose_digi.ax25_call) < 0) { + close(fd); + return NULL; + } + sa.rs.srose_ndigis = 1; + } + salen = sizeof(struct sockaddr_rose); + paclen = rs_config_get_paclen(NULL); + eol = ROSE_EOL; + /* Uncomment the below if you wish to have the node show a 'Trying' state */ + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;35m"); + } + axio_printf(NodeIo,"Trying %s... press to abort", User.dl_name); + + break; +#endif +#ifdef HAVE_NETROM + case AF_NETROM: + if (aliascmd==0) { + if (check_perms(PERM_NETROM, 0L) == -1) { + axio_printf(NodeIo,"Permission denied"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + node_log(LOGLVL_GW, "Permission denied: netrom"); + return NULL; + } + } + if ((fd = socket(AF_NETROM, SOCK_SEQPACKET, 0)) < 0) { + node_perror("connect_to: socket", errno); + return NULL; + } + /* Why on earth is this different from ax.25 ????? */ + sprintf(path, "%s %s", nr_config_get_addr(NrPort), call); + ax25_aton(path, &sa.ax); + sa.ax.fsa_ax25.sax25_family = AF_NETROM; + salen = sizeof(struct full_sockaddr_ax25); + if (bind(fd, (struct sockaddr *)&sa, salen) == -1) { + node_perror("connect_to: bind", errno); + close(fd); + return NULL; + } + if ((np = find_node(addr[0], NULL)) == NULL) { + axio_printf(NodeIo,"No such node"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return NULL; + } + strcpy(User.dl_name, print_node(np->alias, np->call)); + if (ax25_aton(np->call, &sa.ax) == -1) { + close(fd); + return NULL; + } + sa.ax.fsa_ax25.sax25_family = AF_NETROM; + salen = sizeof(struct sockaddr_ax25); + paclen = nr_config_get_paclen(NrPort); + eol = NETROM_EOL; + /* Uncomment the below if you wish the node to show a 'Trying' state */ + if (check_perms(PERM_ANSI, 0L) != -1) { + if (User.ul_type == AF_NETROM) { + break; + } + node_msg("\e[01;36mTrying %s... hit to abort", User.dl_name); + } + break; +#endif +#ifdef HAVE_AX25 + case AF_FLEXNET: + case AF_AX25: + if (aliascmd==0) { + if (check_perms(PERM_AX25, 0L) == -1 || (is_hidden(addr[0]) && check_perms(PERM_HIDDEN, 0L) == -1)) { + axio_printf(NodeIo,"Permission denied"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + node_log(LOGLVL_GW, "Permission denied: ax.25 port %s", addr[0]); + return NULL; + } + } + if (ax25_config_get_addr(addr[0]) == NULL) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Invalid port"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return NULL; + } + if ((fd = socket(AF_AX25, SOCK_SEQPACKET, 0)) < 0) { + node_perror("connect_to: socket", errno); + return NULL; + } + /* + * Invert the SSID only if user is coming in with AX.25 + * and going out on the same port he is coming in via. + */ +/* if (User.ul_type == AF_AX25 && !strcasecmp(addr[0], User.ul_name)) */ + invert_ssid(call, User.call); + sprintf(path, "%s %s", call, ax25_config_get_addr(addr[0])); + ax25_aton(path, &sa.ax); + sa.ax.fsa_ax25.sax25_family = AF_AX25; + salen = sizeof(struct full_sockaddr_ax25); + if (bind(fd, (struct sockaddr *)&sa, salen) < 0) { + node_perror("connect_to: bind", errno); + close(fd); + return NULL; + } + if (ax25_aton_arglist((const char **)addr+1, &sa.ax) < 0) { + close(fd); + return NULL; + } + strcpy(User.dl_name, strupr(addr[1])); + strcpy(User.dl_port, strlwr(addr[0])); + sa.ax.fsa_ax25.sax25_family = AF_AX25; + salen = sizeof(struct full_sockaddr_ax25); + paclen = ax25_config_get_paclen(addr[0]); + eol = AX25_EOL; + /* Uncomment the below if you wish the node to show a 'Trying' state */ + /* if (family==AF_FLEXNET) node_msg("Trying %s via FlexNet... Type to abort", User.dl_name); */ + if ((family==AF_FLEXNET) || (family == AF_AX25)) { + if (!strcmp(User.dl_port,User.ul_name)) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[05;31m"); + } + axio_printf(NodeIo,"\aLoop detected on "); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo, "%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;33m"); + } + axio_printf(NodeIo,"link setup (%s)...", User.dl_port); + } + /* else node_msg("Trying %s on %s... Type to abort", User.dl_name, User.dl_port); */ + break; +#endif + case AF_INET: + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + node_perror("connect_to: socket", errno); + return NULL; + } + if ((hp = gethostbyname(addr[0])) == NULL) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo, "%s} ", NodeId); + } + axio_printf(NodeIo,"Unknown host %s", addr[0]); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + close(fd); + return NULL; + } + sa.in.sin_family = AF_INET; + sa.in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; + sp = NULL; + if (addr[1] == NULL) + sp = getservbyname("telnet", "tcp"); + if (sp == NULL) + sp = getservbyname(addr[1], "tcp"); + if (sp == NULL) + sp = getservbyport(htons(atoi(addr[1])), "tcp"); + if (sp != NULL) { + sa.in.sin_port = sp->s_port; + } else if (atoi(addr[1]) != 0) { + sa.in.sin_port = htons(atoi(addr[1])); + } else { + axio_printf(NodeIo,"%s Unknown service %s", NodeId, addr[1]); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + close(fd); + return NULL; + } + strcpy(User.dl_name, inet_ntoa(sa.in.sin_addr)); + if (sp != NULL) + strcpy(User.dl_port, sp->s_name); + else + sprintf(User.dl_port, "%d", ntohs(sa.in.sin_port)); + salen = sizeof(struct sockaddr_in); + paclen = 1024; + eol = INET_EOL; + if (aliascmd==0) { + if (check_perms(PERM_TELNET, sa.in.sin_addr.s_addr) == -1) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Permission denied"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + node_log(LOGLVL_GW, "Permission denied: telnet %s", User.dl_name); + close(fd); + return NULL; + } + } + /* if ((check_perms(PERM_ANSI, 0L) != -1) && (family == AF_NETROM)) { + axio_printf(NodeIo,"\e[01;36m%s Trying %s... Type to abort. (Escape: %s%c) \n",NodeId, + User.dl_name, + escape < 32 ? "CTRL-" : "", + escape < 32 ? (escape + 'A' - 1) : escape); + axio_flush(NodeIo); + } */ + break; + default: + axio_printf(NodeIo,"%s Unsupported address family", NodeId); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return NULL; + } + axio_flush(NodeIo); + /* + * Ok. Now set up a non-blocking connect... + */ + if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { + node_perror("connect_to: fcntl - fd", errno); + close(fd); + return NULL; + } + if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) { + node_perror("connect_to: fcntl - stdin", errno); + close(fd); + return NULL; + } + if (connect(fd, (struct sockaddr *)&sa, salen) == -1 && errno != EINPROGRESS) { + node_perror("Duplicate connection not allowed", errno); + close(fd); + return NULL; + } + User.dl_type = family; + User.state = STATE_TRYING; + update_user(); + /* + * ... and wait for it to finish (or user to abort). + */ + while (1) { + FD_ZERO(&read_fdset); + FD_ZERO(&write_fdset); + FD_SET(fd, &write_fdset); + FD_SET(STDIN_FILENO, &read_fdset); + if (select(fd + 1, &read_fdset, &write_fdset, 0, 0) == -1) { + node_perror("connect_to: select", errno); + break; + } + if (FD_ISSET(fd, &write_fdset)) { + /* See if we got connected or if this was an error */ + getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &retlen); + if (ret != 0) { + /* + * This is STUPID !!!! + * FBB interprets "Connection refused" as + * success because it contains the string + * "Connect"... + * But I'm NOT going to toss away valuable + * information (the strerror() info). + * Fortunately (???) FBB is case sensitive + * when examining the return string so + * simply converting the strerror() message + * to lower case fixes the problem. Ugly + * but it _should_ work. + */ + cp = strdup(strerror(ret)); + strlwr(cp); + if (family==AF_FLEXNET) { + axio_printf(NodeIo,"\n*** failure with %s", User.dl_name); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + } + else + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo, "\n%s} Failure with %s: %s\n", NodeId, User.dl_name, cp); + } else { + axio_printf(NodeIo,"\nFailure with %s: %s", User.dl_name, cp); + } + node_log(LOGLVL_GW, "Failure with %s: %s", User.dl_name, cp); + free(cp); + close(fd); + return NULL; + } + break; + } + if (FD_ISSET(STDIN_FILENO, &read_fdset)) { + errno = 0; + if (axio_getline(NodeIo) != NULL) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[05;31m"); + } + axio_printf(NodeIo,"Aborted"); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + close(fd); + return NULL; + } else if (errno != EAGAIN) { + close(fd); + return NULL; + } + } + } + if (User.dl_type == AF_INET) { + if ((User.ul_type == AF_NETROM) || (User.ul_type == AF_ROSE)) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;32m"); + } + node_msg("Socket established to %s:%s", User.dl_name, User.dl_port); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + } + else +/* if (family==AF_FLEXNET) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;32m"); + } + node_msg("\n*** connected to %s", User.dl_name); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + } + else */ + if ((family==AF_AX25) || (family==AF_FLEXNET) || (family==AF_ROSE)) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;32m"); + } + if ((family==AF_AX25) || (family==AF_FLEXNET)) { +/* node_msg("\n"); */ + } + node_msg("\n*** connected to %s", User.dl_name); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + } + else + if (family == AF_NETROM) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;32m"); + } + if (User.ul_type == AF_INET) { + axio_printf(NodeIo,"Virtual circuit established to %s\n", User.dl_name); + } + if (User.ul_type == AF_NETROM) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + axio_printf(NodeIo,"%s} ", NodeId); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;32m"); + } + axio_printf(NodeIo, "Connected to %s\n", User.dl_name); + } + if ((User.ul_type == AF_AX25) || (User.ul_type == AF_ROSE)) { + axio_printf(NodeIo,"*** connected to %s\n", User.dl_name); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + } + /* + else + if (family == AF_NETROM) { + node_msg("%s} Connected to %s\n", NodeId, User.dl_name); + } else { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;32m"); + } + node_msg("*** connected to %s\n", + User.dl_name, + escape < 32 ? "CTRL-" : "", + escape < 32 ? (escape + 'A' - 1) : escape); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + */ + axio_flush(NodeIo); + node_log(LOGLVL_GW, "%s Connected to %s", NodeId, User.dl_name); + errno = 0; + if ((riop = axio_init(fd, fd, paclen, eol)) == NULL) { + node_perror("connect_to: Initializing I/O failed", errno); + close(fd); + return NULL; + } + + if (compr && axio_compr(riop, compr) < 0) + node_msg("connect_to: axio_compr failed"); + + User.state = STATE_CONNECTED; + update_user(); + return riop; +} + +int do_connect(int argc, char **argv) +{ + int i, k; + ax25io *riop; + struct ax_routes *ax; + struct flex_dst *flx; + struct flex_gt *flgt; + int c, compress, family = AF_UNSPEC, stay, escape; + char *nodoconn = NULL; + fd_set fdset; + char *connstr = NULL; + axio_puts("",NodeIo); + + stay = ReConnectTo; + if (!strcasecmp(argv[argc - 1], "s")) { + stay = 1; + argv[--argc] = NULL; + } else if (!strcasecmp(argv[argc - 1], "d")) { + stay = 0; + argv[--argc] = NULL; + } + compress = 0; + c = argv[0][0]; +#ifdef HAVE_ZLIB_H + if (*argv[0] == 'z') { + compress = 1; + c = argv[0][1]; + } +#endif + + if (argc < 2) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (c == 't') + axio_printf(NodeIo,"Usage: telnet [] [d|s]"); + else + axio_printf(NodeIo,"Usage: connect [] [via ...] [d|s]"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + if (c == 't') + family = AF_INET; + else if (argc > 2) { + // #ifdef HAVE_ROSE + if (strspn(argv[2], "0123456789") == strlen(argv[2])) + family = AF_ROSE; + else + // #endif + family = AF_AX25; + } + else if (argc == 2) { /* Determine destination */ + /* call buffer increased by VE3TOK */ + static char call[10]; + strncpy(call, strupr(argv[1]), 10); + + /* if (find_node(argv[1], NULL)!=NULL) { + family = AF_NETROM; + } + else */ + + if ((flx=find_dest(argv[1], NULL))!=NULL) { /* Check FlexNet */ + k=1; + flgt=find_gateway(flx->addr, NULL); + argv[k++]=ax25_config_get_name(flgt->dev); + argv[k++]=call; + while((k-3)digis[k-3][0]!='\0') argv[k]=flgt->digis[(k++)-3]; + argv[k++]=flgt->call; + argv[k]=NULL; + argc=k; + family = AF_FLEXNET; + } + else if (find_node(argv[1], NULL)!=NULL) { + family = AF_NETROM; + } + + else if ((ax=find_route(argv[1], NULL))!=NULL) { /* Check AX25 Links */ + k=1; + + switch(*ax->conn_type) { + case CONN_TYPE_DIRECT: + { + argv[k++]=ax->dev; + argv[k++]=ax->dest_call; + break; + } + case CONN_TYPE_DIGI: + { + argv[k++]=ax->dev; + argv[k++]=ax->dest_call; + while((k-3)digis[k-3][0]!='\0') argv[k]=ax->digis[(k++)-3]; + break; + } + case CONN_TYPE_NODE: + { + argv[k++]=ax->dev; + argv[k++]=ax->digis[0]; + nodoconn=ax->dest_call; + break; + } + } + argv[k]=NULL; + argc=k; + family = AF_AX25; + } + /* else if ((flx=find_dest(argv[1], NULL))!=NULL) { Check FlexNet + k=1; + flgt=find_gateway(flx->addr, NULL); + argv[k++]=ax25_config_get_name(flgt->dev); + argv[k++]=call; + while((k-3)digis[k-3][0]!='\0') argv[k]=flgt->digis[(k++)-3]; + argv[k++]=flgt->call; + argv[k]=NULL; + argc=k; + family = AF_FLEXNET; + else if (find_node(argv[1], NULL)!=NULL) { + family = AF_NETROM; + } */ + + else if ((ax=find_mheard(argv[1]))!=NULL) { /* Check Mheard database */ + k=1; + /* K2MF supplied code */ + /* This code *actually* reads mheard.dat and fixes + * the digi path the way it should be. -N1URO */ + argv[k++] = ax->dev; + argv[k++] = ax->dest_call; + + /* First count the number of digipeaters in the path + * from the destination */ + i = k - 3; + + while(i < AX25_MAX_DIGIS) { + if(ax->digis[i][0] == '\0') + break; + + i++; + } + /* Then construct the reverse digipeater path back to + * the destination */ + while(i && ax->digis[i - 1][0] != '\0') + argv[k++] = ax->digis[--i]; + /* end K2MF code */ + argv[k]=NULL; + argc=k; + family = AF_AX25; + } else { /* Give up */ + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Remote not in Desti, NetRom, or MHeard tables. Retry your entry."); + family = AF_UNSPEC; + // free_flex_dst(flx); + // free_ax_routes(ax); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + } + + if (family == AF_INET && argc > 3) connstr = argv[3]; + escape = (check_perms(PERM_NOESC, 0L) == 0) ? -1 : EscChar; + riop = connect_to(++argv, family, escape, compress); + if (riop == NULL) { + if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1) + node_perror("do_connect: fcntl - stdin", errno); + return 0; + } + if (family == AF_INET) + axio_tnmode(riop, 1); + if (connstr) { + axio_printf(riop, "%s\n", connstr); + axio_flush(riop); + } + + /* + * If eol conventions are compatible, switch to binary mode, + * else switch to special gateway mode. + */ + if (axio_cmpeol(riop, NodeIo) == 0) { + axio_eolmode(riop, EOLMODE_BINARY); + axio_eolmode(NodeIo, EOLMODE_BINARY); + } else { + axio_eolmode(riop, EOLMODE_GW); + axio_eolmode(NodeIo, EOLMODE_GW); + } + if (nodoconn != NULL) axio_printf(riop, "C %s\n",nodoconn); + + while (1) { + FD_ZERO(&fdset); + FD_SET(riop->ifd, &fdset); + FD_SET(STDIN_FILENO, &fdset); + if (select(32, &fdset, 0, 0, 0) == -1) { + node_perror("do_connect: select", errno); + break; + } + if (FD_ISSET(riop->ifd, &fdset)) { + alarm(ConnTimeout); + while((c = axio_getc(riop)) != -1) + axio_putc(c, NodeIo); + if (errno != EAGAIN) { + if (errno && errno != ENOTCONN) + axio_printf(NodeIo,"%s", strerror(errno)); + break; + } + } + if (FD_ISSET(STDIN_FILENO, &fdset)) { + alarm(ConnTimeout); + while((c = axio_getc(NodeIo)) != -1) { + if (escape != -1 && c == escape) break; + axio_putc(c, riop); + } + if (escape != -1 && c == escape) { + axio_eolmode(NodeIo, EOLMODE_TEXT); + axio_getline(NodeIo); + break; + } + if (errno != EAGAIN) { + stay = 0; + break; + } + } + axio_flush(riop); + axio_flush(NodeIo); + } + axio_end(riop); + node_log(LOGLVL_GW, "Disconnected from %s", User.dl_name); +#ifdef HAVEMOTD + /* if (User.ul_type != AF_NETROM) { */ + /* if (stay) { */ + axio_eolmode(NodeIo, EOLMODE_TEXT); + if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1) + node_perror("do_connect: fcntl - stdin", errno); + if (User.ul_type == AF_INET) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;31m"); + } + axio_printf(NodeIo,"\nReturning 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,"\r*** reconnected to %s", FlexId); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + } + if (User.ul_type == AF_ROSE) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;31m"); + } + axio_printf(NodeIo,"\r*** reconnected to %s", RoseId); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[0;m"); + } + } + if (User.ul_type == AF_INET) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0m"); + } + } + /* } */ + /* } */ + if ((User.ul_type == AF_NETROM) && (!stay)) { + node_logout("No reconnect"); + } + if ((User.ul_type == AF_NETROM) && (stay)) { + axio_printf(NodeIo,"%s} ", NodeId); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;31mWelcome back.\n\e[0;m"); + } + if (check_perms(PERM_ANSI, 0L) == -1) { + axio_printf(NodeIo,"Welcome back.\n"); + } + } +#else + node_logout("No reconnect"); +#endif + // free_flex_dst(flx); + // free_ax_routes(ax); + return 0; +} +int do_finger(int argc, char **argv) +{ + ax25io *riop; + int i, compress; + char *name, *addr[3], *cp; + compress = 0; + + /* if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } */ + axio_puts("",NodeIo); + if (argc < 2) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Usage: finger user@."); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } else if ((cp = strchr(argv[1], '@')) != NULL) { + *cp = 0; + name = argv[1]; + addr[0] = ++cp; + } else { + name = argv[1]; + addr[0] = "localhost"; + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Usage: finger user@."); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + addr[1] = "finger"; + addr[2] = NULL; + riop = connect_to(addr, AF_INET, 0, compress); + /* If you uncommented 'Trying' state on, uncomment this also. */ + /* escape = (check_perms(PERM_NOESC, 0L) == 0) ? -1 : EscChar; */ + if (riop != NULL) { + if (fcntl(riop->ifd, F_SETFL, 0) == -1) + node_perror("do_finger: fcntl - fd", errno); + axio_printf(NodeIo,"[%s]\n", addr[0]); + axio_printf(riop, "%s\n", name); + axio_flush(riop); + while((i = axio_getc(riop)) != -1) + axio_putc(i, NodeIo); + axio_end(riop); + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;31m"); + } + axio_printf(NodeIo,"Finger complete."); + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + } + axio_eolmode(NodeIo, EOLMODE_TEXT); + if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1) + node_perror("do_finger: fcntl - stdin", errno); + return 0; +} + +/* + * Returns difference of tv1 and tv2 in milliseconds. + */ +static long calc_rtt(struct timeval tv1, struct timeval tv2) +{ + struct timeval tv; + + tv.tv_usec = tv1.tv_usec - tv2.tv_usec; + tv.tv_sec = tv1.tv_sec - tv2.tv_sec; + if (tv.tv_usec < 0) { + tv.tv_sec -= 1L; + tv.tv_usec += 1000000L; + } + return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); +} + +/* + * Checksum routine for Internet Protocol family headers (C Version) + */ +static unsigned short in_cksum(unsigned char *addr, int len) +{ + register int nleft = len; + register unsigned char *w = addr; + register unsigned int sum = 0; + unsigned short answer = 0; + + /* + * Our algorithm is simple, using a 32 bit accumulator (sum), we add + * sequential 16 bit words to it, and at the end, fold back all the + * carry bits from the top 16 bits into the lower 16 bits. + */ + while (nleft > 1) { + sum += (*(w + 1) << 8) + *(w); + w += 2; + nleft -= 2; + } + + /* mop up an odd byte, if necessary */ + if (nleft == 1) { + sum += *w; + } + + /* add back carry outs from top 16 bits to low 16 bits */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return answer; +} + +int do_ping(int argc, char **argv) +{ + static int sequence = 0; + unsigned char buf[256]; + struct hostent *hp; + struct sockaddr_in to, from; + struct protoent *prot; + struct icmphdr *icp; + struct timeval tv1, tv2; + struct iphdr *ip; + fd_set fdset; + int fd, i, id, len = sizeof(struct icmphdr); + int salen = sizeof(struct sockaddr); + + /* if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } */ + axio_puts("",NodeIo); + if (argc < 2) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Usage: ping []"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + if (argc > 2) { + len = atoi(argv[2]) + sizeof(struct icmphdr); + if (len > 256) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Maximum size is %d", 256 - sizeof(struct icmphdr)); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + } + if ((hp = gethostbyname(argv[1])) == NULL) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Unknown host %s", argv[1]); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + memset(&to, 0, sizeof(to)); + to.sin_family = AF_INET; + to.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; + if ((prot = getprotobyname("icmp")) == NULL) { + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + axio_printf(NodeIo,"Unknown protocol icmp"); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + return 0; + } + if ((fd = socket(AF_INET, SOCK_RAW, prot->p_proto)) == -1) { + node_perror("do_ping: socket", errno); + return 0; + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;35mICMP Echo request sent to: \e[0m"); + } + if (check_perms(PERM_ANSI, 0L) == -1) { + axio_printf(NodeIo, "ICMP Echo request sent to: "); + } + node_msg("%s", inet_ntoa(to.sin_addr)); + axio_flush(NodeIo); + strcpy(User.dl_name, inet_ntoa(to.sin_addr)); + User.dl_type = AF_INET; + User.state = STATE_PINGING; + update_user(); + /* + * Fill the data portion (if any) with some garbage. + */ + for (i = sizeof(struct icmphdr); i < len; i++) + buf[i] = (i - sizeof(struct icmphdr)) & 0xff; + /* + * Fill in the icmp header. + */ + id = getpid() & 0xffff; + icp = (struct icmphdr *)buf; + icp->type = ICMP_ECHO; + icp->code = 0; + icp->checksum = 0; + icp->un.echo.id = id; + icp->un.echo.sequence = sequence++; + /* + * Calculate checksum. + */ + icp->checksum = in_cksum(buf, len); + /* + * Take the time and send the packet. + */ + gettimeofday(&tv1, NULL); + if (sendto(fd, buf, len, 0, (struct sockaddr *)&to, salen) != len) { + node_perror("do_ping: sendto", errno); + close(fd); + return 0; + } + /* + * Now wait for it to come back (or user to abort). + */ + if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) { + node_perror("do_ping: fcntl - stdin", errno); + close(fd); + return 0; + } + while (1) { + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + FD_SET(STDIN_FILENO, &fdset); + if (select(fd + 1, &fdset, 0, 0, 0) == -1) { + node_perror("do_ping: select", errno); + break; + } + if (FD_ISSET(fd, &fdset)) { + if ((len = recvfrom(fd, buf, 256, 0, (struct sockaddr *)&from, &salen)) == -1) { + node_perror("do_ping: recvfrom", errno); + break; + } + gettimeofday(&tv2, NULL); + ip = (struct iphdr *)buf; + /* Is it long enough? */ + if (len >= (ip->ihl << 2) + sizeof(struct icmphdr)) { + len -= ip->ihl << 2; + icp = (struct icmphdr *)(buf + (ip->ihl << 2)); + /* Is it ours? */ + if (icp->type == ICMP_ECHOREPLY && icp->un.echo.id == id && icp->un.echo.sequence == sequence - 1) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo,"\e[01;35mICMP Echo reply received from: \e[0m"); + } + if (check_perms(PERM_ANSI, 0L) == -1) { + axio_printf(NodeIo, "ICMP Echo reply received from: "); + } + node_msg("%s", inet_ntoa(to.sin_addr)); + if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[01;31m"); + } + /* if (User.ul_type == AF_NETROM) { + axio_printf(NodeIo,"%s} ", NodeId); + } */ + axio_printf(NodeIo, "Ping completed in: %ldms (ttl=%d)", calc_rtt(tv2, tv1), ip->ttl); + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + break; + } + } + } + if (FD_ISSET(STDIN_FILENO, &fdset)) { + if (axio_getline(NodeIo) != NULL) { + if (User.ul_type == AF_NETROM){ + axio_printf(NodeIo,"%s} ", NodeId); + } + if (User.ul_type == AF_INET) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[05;38m"); + } + } + axio_printf(NodeIo,"Aborted"); + if (User.ul_type == AF_INET) { + if (check_perms(PERM_ANSI, 0L) != -1) { + axio_printf(NodeIo, "\e[0;m"); + } + } + if (User.ul_type == AF_NETROM) { + node_msg(""); + } + break; + } else if (errno != EAGAIN) { + break; + } + } + } + if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1) + node_perror("do_ping: fcntl - stdin", errno); + close(fd); + return 0; +} + diff --git a/ipc.c b/ipc.c new file mode 100644 index 0000000..c171c34 --- /dev/null +++ b/ipc.c @@ -0,0 +1,193 @@ +/* oringinal by Heikki Hannikainen, modified by Brian Rogers */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 "); + 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; +} diff --git a/man/axdigi.8.gz b/man/axdigi.8.gz new file mode 100644 index 0000000000000000000000000000000000000000..a058441fba35fc23e4dccebac7c504df4a61504a GIT binary patch literal 1006 zcmVk3?I zW#!>0eF44@keagOI=f+4wX;{sq+DIOozzz?hznz(;&j-+u@F{JI?Rgsl%o9pGJ$}C z;DXQu!?DyF=SG#W9w<#ExR-h#%65npX@WxVX7Y*PrH3StTUR2LT)~6Une@_VcXLK~ zp~2WpSi;j~9tKPZlnB)hU%oGE=ikFYn`11tUN2_Aoimu)i;VUBWu6+H%RSsm?S;*G zD(>(F_kfh>Kqjq7J)u2NO?qT%zcaPYSQMrZCnV;I4ia9Iu7^jd6ci{hYD1yCs;ohO zAc!75<7tYVP#<+lV37wl1%DAx*2>EYLxV;=Ko<$Oy>_M)g*h@Mou?WlH%)g&fdX`Q1aPb-2qwOv$oRr~lU(^CBCK%OQbjoc1{Aac_hT zNF&GcTBl);bz^b@Z>7k7ofw(My&O`vcyd%4JC<@95ZOKD-is2KdB+e3qBCL;uUEd^ z&?P^?UU;gW9!@mr@#%8dK0w=De7sE9f6h`sNt_1&05!GcU;qFB literal 0 HcmV?d00001 diff --git a/man/flexd.conf.5.gz b/man/flexd.conf.5.gz new file mode 100644 index 0000000000000000000000000000000000000000..efa7cc81f4a8e2968bd4e4f657bd2fdbbde1a9c6 GIT binary patch literal 988 zcmV<210(z&iwFoc`rlLl17>Vxcw{bPZ*FETH2`&0U2o$y5PU9w#WsGp1W4pKxd6eT z2;d}6FF?L<_CpKgg_c$}aT2MLlx_X{&Qf;HzH0*nwy5Ro?#%2un|-B+r^#RU+1=~Q z16|S4#Wjr^Zz{StA6*{NldTCS9%#gPgGg)rpR(< zOL{+}^hEMx7OmIOI7_9eI7=7qC)2xck8iWb*B6yNy{YV$eq2`)M<$SGUC_MSV(Cat zUjT)ueQX=jwvf0sa6!>g?Fv(N6ql^#ywoe>T2HQ&1M+U}VwRH4@K_nkfz~E2jr}Qm z-G)evH|%N7q|pRgwlUo~rS;O}%f5mh01*Q+Hf1S|$K~8rZEa7&NlV>WpGPOah0tv_)nL?v;&S?A*muo95M~w>hLdc|~UBY3T zR}LI0#1yWbgWZ2x7dZf^3Xbm1LhNwJA=eFPIevdf_3!VS^RaxKk1mK~o}DDHMtgzk zsrv~|WuZ~yl{S@@(?j(?`UlDvmCfF0^jWBX?(TF|{r1OZGuUiy)RfT`v`v)ZMKB9X zn=@=-$!G z>n!1b#e@&75{TYhTtU>xz66`97aeatRh5{caTVOKpwhdVbVy~@x}zMHjpCWgxdwr8 z&1`$b&_VTDiOR_-eU-GUGE-wqywP=2@s}MZ-{+&YZO=xRdvv`a^`jKF(jYCGnume& za06Ro6hib;S7Z?P!}qjwYt&~k8;B3$*69Qje?Jx0q?!MrE)7^>OTf$lj}%4Zj2MKx9kJaR&Tx$ft6E(2o)g4V9BiloNE^^-xPYh1nj zxTk)lxpwel^tvofj{2aXWiGhL_UL**OMfDG>#wuHV9S&VhZfr@|BEm*`=D`cz*O2w zQ6SXr@>%ju8sG?#o0zu7hb;~E$%=hPgTbyHm_{yw2kf7HNvW3`D+gkSSUE!( z!{Od;mf)l5WJ2So=_`JFZog3rtGR;d`1<5@{~&AF*VtuO+he^E8y_5C#E(CpWa?kZ Kf6I{u2LJ#m0QL9) literal 0 HcmV?d00001 diff --git a/man/nodeusers.1.gz b/man/nodeusers.1.gz new file mode 100644 index 0000000000000000000000000000000000000000..f5e243033199ca9d8e1835abfa0f5ea8407e1f4f GIT binary patch literal 596 zcmV-a0;~NWiwFqn##%@K18#3*Wp#69a&s;*0CiJMZ`&{oz3W#HxvV`zSqcPbfgniI zxM+aX4r~|0y7j==vLj5EJW1}?uP>O6D zl?tX87w03`N!>lcX!z`{sVz2*uwNY9pzctO7|&?J>Ly~^l%jLOI`}z;+cb&kH-rR8 zT^ZY;mqvp!=2zE3JB;ePv+r@T&$b!kYxpBkXwzK7{o8o4F;$a0~Sd#A>m&;$rXAvMe| z(*>Xdq06zU#!70zAwNnYcL7*+N-`WLzOa_4L!)ibWa^N;tZW zx({q%7%NOv9oX$lLxeuVDTi#o`gO@yRr>! zctF>C@%JX)-NGn~B3SLRgsys>LPzU_YdJYT?aQm%{5nb5+Dh6xHFYo}p3+UhTu%wS z>?1EsvtaySS>{EB+R%+w!b;fQ%~s#;U@l)~`1rE4SV}Xl1ut}0glM_+Lt}0l8UA0I io=rn?eYTD>nESTrQ_G^@$IkOgF4!ym-}sEb0{{R+4Jj4? literal 0 HcmV?d00001 diff --git a/man/uronode.8.gz b/man/uronode.8.gz new file mode 100644 index 0000000000000000000000000000000000000000..7d2e41093fcbf0b7d62d3ee6261c05f97143d1d7 GIT binary patch literal 3287 zcmV;|3@Gy-iwFqZ`QKCk19ft5Zf|5|E;s<4S!-__Hx~W8{1t@0#4en1ldXYtVYqQ@ zr`9%+ypn>Z&1SLG3?&gB4b|a{Wd;55d+sGU57}G>keByy?sJmawfry{kH(i* z@|7ICd?n8}rOD-s@4tUFknc=U-^+pjnC@Jq*Ydq8)KZs@zSJroh-7*#N9XUa1ktgX zmj8Y(`Eya)qLRAEMtLepLcrzQ0M zbXxHhB<#A8tG9b_5%!&?D$nKbQsqXuGx^E=o_&@N{=Eg$FbZrkc$^9ecjk$K$emIC z`-?M~B*|y_Df``hW-4sqCy4mdrz*=z?TDGv%q-1WJl?W08BedCppj`;nL<^@7EemU zG{}Y{U4e|-$QNQ*n98V1!(0WJ?4uCZ$#A65l?*z@6|%CxSE<*w(sE^8l}IsM09i13 zwF0GTYvo3jYOO0WIYB`e_)4e)kjOSpgI?C|lE7@G3n|hSmeLiSGlk4`v8+~fqL8Md zO@;_LzgmdPzW$s7{i|yssIL$XLObICUE_y(N3@Hn2VE#xEv`qj`840^qx1Lr< z2V`vsTk+XMLVjE1JN(i8yOzK-#M(QJ2Wv%Mr&XD*$Z^O+coX2@%(5WqgDn`y4uTnP zB>C3dgR$Hcw^+quu&V69z_BE`g6P=reuaB7nW;+674$-ssuh^9Wv0vIZv+QH_;{dB z=BWiIM62Yw2Gu!idau$7GCOlmKq2!HbSt=MR0losYfV7NjYb$EvX`Ubg*@=~S=hP^ zI}ahpLe+Uis>eQ&TPTHhCz7H~`a8k+p&~H>3ktWanAm5nPBgD^`_D+>F3V!M0dZjAHP@@?yI( z>577_Ss3llM5*R_rS1&LYe`|QqwK(VyTY1m$p6MHh!#4~c`;n$i?)_KM4leX%gP_vB1(G$o^eW4Cj5BjNZ9&@0mYdJmuCJmim#U3MiqigzgI05iT|Y(@scvBpgz zM+`PP=`Ro=*SGO=3skVqi`MI^i1D;8OImn}I@LpcjC&XN%IS&1UJuoHWgt>vBQ2|9 z7o1aUQ76gU!fp#lnBk#A6*Ii?3Oc3B&jtdwFlza(2YeYyW=_r#tIHil{&mul_|L_k z9p{t>biRc#K=jio8JEC&_8Cr0Q1(AMZfpwDI!BA(&9OSAn8)ROgGqWK z*i$KCHr~0iTh}~y5rpvJ+%A^@j*mIQ*GGX=4yWZ98Pvk|c+$lN~mNUGX&r5wr6=If%522tM{4i*! zgXJ>nRDEsHKDZuZUuzf?;-_XKW04W$;tIj871cqcvMGX}Np%~V9x-BvrY%L6Xpey* z4pQ5&$(4_v2wslMvM$9?sgk3?urB)laqY@uwozL_)ab7$XVQ5|+2=_50sttfbBcd1 zEe$EOpb}z3DOiBsj&h!do3C6rh4PWyP|b;&rc_HWU0;OJOqUCVEYlN&xOf%{TzV=U zO6j$twvUUf{FdaPN{u@p9Dz{>T>cFDHhM?ZC3+ATr@;R^G7{%S;BMMrpUY7yL}kVH z4h4*durDKg0_qf|!iM6L;SzFDsj29X;g)E`<|aZdrT{^)H*P`{sOct+mZQ8yd5UI% ztM&sf3*)x<9G8xNI!pvtd9k?b)ax0$bt@Sc-iSb@=0cYQB~N(bbn)nEf2gVHz>!b| zw`>^#Cv+U2xJQoRm;Jg86MhT##*jOpBbI7S zAmje3M|;G2{qzk%l2jNW$p^bV(_^6Y@pu+|CERD6`2WDz!J_y-u^5|<#=K2|^X!{v zu*MR4c8w|4JdPo&$7{!PXR#xtf)@PMhFhL;r}`Hy$v#{h&f(bwL8fSf0R<7YF&!iT+-no=bP95e@rpgPa|lZvNOTl!i; z;XWB`E9{;k$LaY%1<>|s4oMvgL7?Dq{l7NtgG8QLxWF1cP! zHO%MDh0BZVIU>X6d1a9J4kokNA-bk&t3wIwu}$ZCVu&MaRB21ws8*bPad{GwModKENIT6hE?sa z(2hTJWat)ov`HIL=B9f-@}bl(ABAB(ykbr@z{TXW@wyE3BqJN^Wq^as0d_dEU;4ZRk=;CEHEf)4Y`YE37ROxvlhK@bNO(8Dh zn;S?M$DORZr?u5kT63QjJ`z-SV)$Tive$(9txt2=VUfm9$KNEYJajPydeAtOf_j_> z?qGU#CC}ecVo%;oWEY?E;N@zQ84~`7bVCpYi_L_4(+hsho|)v_j-AtQ^^eE{z=idUF2rukzG< zIZ@j$uS=B~`+T`g(xOhmd{HK*I%6%(;L!BiA2ARqYJC0j&1fo5tIe91UZ-iYs;gvS zc()YiIXJtp_wvV|zq^@X=W_eqrgE?SN21o7GO^_{?4H=2yt#TY`RBPjE$!~LcBM)a V4QyAnPKx|Y{13)K^qQ<7003`skE#Fw literal 0 HcmV?d00001 diff --git a/man/uronode.conf.5.gz b/man/uronode.conf.5.gz new file mode 100644 index 0000000000000000000000000000000000000000..5ab80b022752c275a7b17eea9847a5d8dedec076 GIT binary patch literal 3333 zcmV+g4f^sQiwFoW`QKCk19ft5Zf|5|E@N+QW-c`VB8^;xX?)-{@g1{s|tuBsJ zSrCMx2f0(m>v#f~<3J-(-F*=oahGr%9@bR8D4Isx+0Q-bh_~n`w6} zzt8pKMM`!mD$i0~E9dB|PgqCdn`fnVOgbw+Q@W^~mm0rmE9cOaq$xn3Z%yQ8oh{Zu z?LY!2zLHtVsx32%%L|j&MLChi3RCJvZ6X7C9OyU?E6sIoHi|iZ&u4x z=UI{Atbpyo*K6r2wSe)a?YV_2$-Q1dg5D9CG1D#6(d8mHaE!p2)YN3wPqp#dfl%&@ zJll1Ci-+1RR0YF~?(QJ{-QDBY1=97^pM$(V^%$`Ywyyr<-D)!fNKfi2O6^*A1u z#x}ZSlC_ zw-cDpB}sDn_q&n(BxV}+q0nrIK`LAhp;y+$Tysd)Ri*7hIY_WpRxP}?jv_q7?kX!w z5*i01Q&;IlwnVVWwb{s`Ml_Inp{Wh3&*xS@WD2ez5|MY{+VO%Jy>x3+=M)JtH{hX5 zQ?J&PK2GEJNTHElED^-ga9p<5;W#AuI1=f!Qw7LrPiiFcg2MoABiEHibOOX9P2{$k zPWbC)ZQzoUXdxxxng?xtNNpw|m|ICu5@7rlVR4SAR} zFEnJ6`ms`_Lo|qy(>f%~IOzq$nJLTLtk9^b)j#=&B6nb6aF! zAt5Nl#G&||BnvL%I~0caF-u{I5vo$Eypl`EK=y{&VvR^M8xD^-&^tMt1|j$;SfWod zwFX8^JNu=X>jY&#b3GF8^itKir#r8|-QSmyq!=9__-Z>a#(9BE`oqZ<&%fi_s;F#Y z?CKQeCq0~`-y}UQwMTUdmCY_Pl}k;xshnEvNMz;FU?5hNt1Z%<{O%}RNP!a0S)#}= zK{SU?HB2C>%EK@U4s>o~Y)WUz=nI^5f_al%6S>Y->wF8huU48%Arpm29pyy+6{IPh za;+Y;Fw0OxPflNjs3y*-;h+O!3dLXmuF~Y4uAqC02WJ07$wsG5mgkMG)K^Ajo#$in zj^LjPb+4IWZp^)OIh?nZ$GhXc@ws%Kp@7JfP)1M1tSuBId3f5@n4~?}D+6>e#jOG! z5mr}_6Il`}Vr(PR+1bSfJeRhOWurHraGr-+*>EW|_>`F|Buat0ck*a=jz;Y*QW>d@UbH2_ zW9t``0%Y1~gEpsFH0tmOQ>T3d4!e=bGFPkC$tXvK6O?Bf=Eq zcAbu!GYoBN1gWLEE22n)oO<+UMcP#U6JqP|x6aURPV}Q*;7`+ZL~=6=SNG{EU1<}K zrKe(AmnqZ>7{d39BIxIA#17frvKAj3YZ!)0rb@tncz_b{l-L6q;FPKxu(Xb)8jUt z-jEar;-+p<5jb$j$||dX27iPlsReQ`3qpRc|#hgd5|QAdcGxBV_5J8un*q#d=E9d zq_zsEdar%va7Y9hwuq^e?8|jLxRD@$3u^XsL@aCk7<6?l)+3VuxA~2RDvfwiw}Gxf z1lN}#SgGSLdiLd*P4R!=DZi6s78ZALwvHdE6huiN6^v`i&;#yuPI2n6d^out{?sMa6mnr;_A#C zx{A<-ckg;Ej#NrqNNJ*BDyqxSuET*$E6f)z&X7ZHp&We~ILdYh z{(Y9Fy1X_t&7D;ELlxvylFXON-VYuE8m#$v60gaM?}bXmrr4AntiWuEq4nNPSsN+RORoRCZdb~&k4jh6->h8%JpV(A` zh-Ls+XlZ|*zWs~5`ZyC|4-kKBfikplfFTi7D8v&-)~8y*GgW&mxK*^bsm}ILi_2Ce zq6x8u5T_2)2+6A@^wnIsbs`B=3a$nRhks1=>HobWIRf;q=BU&p+?b`N4FgMt0tOn5 z=|C%D)}hr`AJ8pwd4izI=~Ew{Z`KiaHPsAxh15-WTso`O4EB>R+@L zStb3(4c?e=;EIJsa4l%qvesBPXeD$gJZ8gj=(|1qLCE$`zV4lzJUJFjj$B&7ssu!u z@)9;*y(mS_=UsHdkd{o=v>K{EoWL|1qib%P41Fe3D4BL5-rni^ ziPv}U2x;rb0k>^MGD6%i!#<)S(sv4~UFRAZs6e{ViuEH+l+b?9SQ=mXUMQ5!l*xm| zJm59Ab*3WGiFC??V_&Wt<21=-@t631mzLRL@)iI0WWFXvF*`RWgLHAsv2t0{tclA_ zX0)1#VVd#jg{c88w><7mDE3tI5%j7xZ5IhCaGOiylzO-#2nk`1o30(^rpyI=Z+KkhT^#ROVKF*gY~yVgdK!I`U8SC`;1_a?ma-X?%O!N2{@rr6Fv_EEJE*?7EhoF?ZBEPJa?ACx?9kWim(y| zIvWEW{O+#Y>8)A23FZt+R4>Cce>P!H>h+M(BOS z2#Rj=#b>D}-N_%qPRh}23>%Ib2rzCEH&(W|`J;Z$%OAwC;Y-{!tBPw^y-nm{hyHT>>n!ZG!B^(^Js(W(D0t^P=fkaO?<2#!vd-I0E61- P8#v=%EX!&!>LLIDeVTnW literal 0 HcmV?d00001 diff --git a/man/uronode.perms.5.gz b/man/uronode.perms.5.gz new file mode 100644 index 0000000000000000000000000000000000000000..9e88876eeae4f6766631aaa661ecdc7caaa5f44f GIT binary patch literal 1267 zcmVFP0oYv_$8a9cQ~;p*$xNe>>BDW9QN{Vbi`Ig#hm{p#USm{RB-8!Dt zY&-xuP~IzRJZzPgJnGy{lkcn9ay?tj8Gl$Z{;g4{5EzMq^5CS%Km;f% z>)?ZMp)BC2!XCn2!ok?1mf22%-9qW5^YPn=T(W*Dw7wWXYK@U;Kp!By6cYNkfAP`v z0Or&6aJ6_Gz-p092eAIW9L|;~Ur2(PEkR_Nlisub*1F~zgvp?=E&$npcop$3IIPj3 zt#UqqG{L<*=BL^N`kPJ}Y;`L5FpRDM>UXo{ciRLyE1SSUSX+l&Rz;UnAeU;$~10{X| zWn!MIuu`kb+zh}vCORI~;WnaHYkMT`s(1$=1p;rC)EU~Pi%e>jtANpNUKrX95_}<2 z`3K{^V0@LZrifL=DBtnFHZk3F@YOWxRp}=yne?esMToQ$uEAX|;c6W7(okfLg`w2P zN})SqCzQcJ&zS@jlVVbA86Zh!cN}i9dOk>}{DJi^FKP_5XI@%O-Z4s%d}xpo7ehrF z)8Adr+6c$l(qh0HY>X$NOEg4GA!gMXLPxYVc3kyb%=7qw7|-3LeQp zrNW{{E<}z;KHh8jJeQ%>H8MDxf397(TC3x%m!E4;PqyOPVgXwDsuMe5AYGBuvIg2) z%qL~pKrbrx$VFt$feDY)*dp6Ax^21xfwq0@-!>U};r@p)QbR+~ACLKO^chZ0m}oQn zS4>m)>M0Ob2Li^rj>*;vX}(Hp>}N`BGm*DcEWejp^Qv=Nf;L^oX4`fqy~~0Q>E5R@ zi|%&DBvJY;wWuK~ zZgd@sH~}Xo!?BQA4zoxVjHt|;*-?)NtvpRwBG&7e=vCcGAiQsS&MSctmpFESpyy4rd+C zKI-tRn}30R-B`bmK2zv4>U%zY(5yFOb~{gI@ZD+@*lMxkFg1b(d=bHrn_FCpWJl0S zJrRK{izf+DKP7#J&!YktIOa7vp-_k%HbP^ILGQ9xuM61$J}RxF;R*v5a}r``>?G8z z8GMA%67*_kI3(q6CnLMi6D`S=#r-{$M&ok{N&Qb5Z`tN0T9ox8hjR`a+@IRogNK7W z>X;XZ)9B=HTcy$DEn8?Wyrs(M`X;V_W53|)7r5uDeBLQf39WjlzR6{}7e@K~v_Px< z8nI|1;tTbD_ApK2yJ}c^H;fe>%8(9eQx4DHRV3d_rc=0mNEY}g{Q94MEuf(b002`vU_k%? literal 0 HcmV?d00001 diff --git a/mheard.c b/mheard.c new file mode 100644 index 0000000..9c2ed9a --- /dev/null +++ b/mheard.c @@ -0,0 +1,151 @@ +/* Routine rewritten mainly by Barry K2MF (Mr. MFNOS) and Brian N1URO */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#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; +} diff --git a/node.c b/node.c new file mode 100644 index 0000000..f1ebafc --- /dev/null +++ b/node.c @@ -0,0 +1,419 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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