commit 4013fe89dba7bcbd25ffded96d12bba6c9c78476 Author: Dave Hibberd Date: Thu Sep 3 20:01:45 2015 +0100 Imported Upstream version 2.3.1 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 0000000..a058441 Binary files /dev/null and b/man/axdigi.8.gz differ diff --git a/man/flexd.conf.5.gz b/man/flexd.conf.5.gz new file mode 100644 index 0000000..efa7cc8 Binary files /dev/null and b/man/flexd.conf.5.gz differ diff --git a/man/nodeusers.1.gz b/man/nodeusers.1.gz new file mode 100644 index 0000000..f5e2430 Binary files /dev/null and b/man/nodeusers.1.gz differ diff --git a/man/uronode.8.gz b/man/uronode.8.gz new file mode 100644 index 0000000..7d2e410 Binary files /dev/null and b/man/uronode.8.gz differ diff --git a/man/uronode.conf.5.gz b/man/uronode.conf.5.gz new file mode 100644 index 0000000..5ab80b0 Binary files /dev/null and b/man/uronode.conf.5.gz differ diff --git a/man/uronode.perms.5.gz b/man/uronode.perms.5.gz new file mode 100644 index 0000000..9e88876 Binary files /dev/null and b/man/uronode.perms.5.gz differ 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