home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / DOC / HOWTO / MINI / DYNAMIC_ < prev    next >
Encoding:
Text File  |  1996-08-25  |  37.1 KB  |  1,052 lines

  1.  
  2. Dynamic-IP-Hacks Mini-HowTo Version 1.3.1 
  3.  
  4. Moderated by:         Michael Driscoll <fenris@lightspeed.net>
  5.  
  6. Featuring hacks from: Michael Driscoll <fenris@lightspeed.net
  7.                       Ryan R. Klems <rklems@primenet.com>
  8.                       Matthew Driver <mdriver@cfmeu.asn.au>
  9.                       Matthew Nuckolls <mnuck@umr.edu>
  10.                       Justin Cragin <beyond@lightspeed.net>
  11.  
  12. Created        Mon Apr 22 16:24:33 PST 1996
  13. Last Updated   Sun Aug 18 04:12:37 PDT 1996
  14.  
  15. If you just want to see the hacks skip down to section 2.0.
  16.  
  17. 0.0 Table of Contents
  18. 1.0 Legalities, Definitions, &c.
  19.  1.1 Where to get the latest version of this HowTo
  20.  1.2 Feedback
  21.  1.3 Why this HowTo?
  22.  1.4 What is dynamic IP addressing and why do I have to put up with it?
  23.  1.5 Can you help me set up {pppd,telnetd,sendmail,&c.}?
  24.  1.6 Hey, what about SLIP?
  25.  1.7 Copyright
  26.  1.8 A Warning
  27. 2.0 Hack #1: Keeping your system up and accessible 24/7
  28.  2.1 What you'll need
  29.  2.2 Setting up keepalive.sh
  30.   2.2.1 Using diald instead of a crontab entry
  31.  2.3 ip-up and ip-down
  32.   2.3.1 Setting up your ip-up and ip-down
  33.  2.4 How to find out your new IP address from another computer
  34.   2.4.1 Telnetting to a POP3 server
  35. 3.0 Hack #2: Dynamically changing /etc/hosts
  36.  3.1 What you'll need
  37.  3.2 More fun with ip-up and ip-down!
  38. 4.0 Hacks #3-5: Various hacks from Ryan R. Klems <rklems@primenet.com>
  39.  4.1 mail.c
  40.  4.2 pppdm.c
  41.  4.3 portmsg.c
  42. 5.0 Hack #6: Setting up a dynamic DNS entry by Matthew Driver 
  43.     <mdriver@cfmeu.asn.au>
  44. 6.0 Hack #7: Updating your .plan by Matthew Nuckolls <mnuck@umr.edu>
  45. 7.0 Hack #8: A simple procmail recipe for finding your new IP
  46.     by Justin Cragin <beyond@lightspeed.net>
  47. 8.0 We need more hacks!
  48. 9.0 CREDITS
  49.  
  50. 1.0 Legalities, Definitions, &c.
  51.  
  52. Section 1.2: Where to get the latest version of this HowTo
  53.  
  54. The latest version of the Dynamic-IP-Hacks HowTo can be found at
  55. sunsite.unc.edu under the directory /pub/Linux/docs/howto/mini.
  56.  
  57. Section 1.3: Feedback
  58.  
  59. Feedback concerning this mini-HowTo should be addressed to Michael
  60. Driscoll <fenris@lightspeed.net>.
  61.  
  62. Section 1.3: Why this HowTo?
  63.  
  64. The problem is, Linux just isn't as happy as it could be with dynamic IP
  65. addressing.  It's the Unix equivalent of waking every morning to find
  66. that your postal address has changed and that all of your stationary is
  67. out of date.  Unfortunately, ISP's are moving more and more towards this
  68. kind of addressing these days, and anyone who can't shell out more bucks
  69. for a stable IP address is just kinda stuck with this.  The purpose of
  70. this HowTo, therefore, is to make your Linux box happier and more
  71. comfortable with dynamic IP addressing, which in turn should make you a
  72. bit happier and more comfortable.
  73.  
  74. Section 1.4: What is dynamic IP addressing and why do I have to put up
  75. with it?
  76.  
  77. First of all, I suppose I should explain just what an IP address is :)
  78. An IP address is a set of four numbers, each from 0 to 255, separated by
  79. a dot.  An example would be 10.127.96.1.  Each computer on the Internet
  80. has a unique IP address.  The human-readable addresses that you probably
  81. use, like sunsite.unc.edu and bak2.lightspeed.net, are just
  82. semi-arbitrary names that are translated into their IP addresses by a
  83. DNS server whenever you try to access them.
  84.  
  85. Dynamic IP addressing is something used by an ISP to cut down on the
  86. number of IP addresses that they need to "own".  The way it works is,
  87. when you dial up your ISP, they simply give you the next IP number in
  88. their queue.  This way, they don't need an IP address for every single
  89. customer they have, they just need one for every customer that might be
  90. online at any given time.  Usually this is only about a tenth of their
  91. customer base at any given time.
  92.  
  93. Why do they do this?  Well, there just aren't enough IP addresses out
  94. there to give to every single customer of every single ISP on the
  95. planet, especially now that every computer user and his dog is getting
  96. connected.  Besides, it doesn't affect Windows users at all, so why
  97. should they care? :) Therefore, it seems that unless you want to shell
  98. out some more money for a stable IP you should just try to make do with
  99. what you have.
  100.  
  101. Section 1.5: Can you help me set up {pppd,telnetd,sendmail,&c.}?
  102.  
  103. No.  Figure it out yourself.  Builds character :)
  104.  
  105. Actually, it would be pretty pointless for me to reinvent the wheel by
  106. helping you set these up, as many documents already exist to help you
  107. out with these.  Start by trying these:
  108.  
  109. man pppd 
  110. man chat 
  111. man in.telnetd 
  112. man inetd 
  113. PPP-HowTo 
  114. NET-2-HowTo 
  115. NAG
  116.   (Network Administrator's Guide by Olaf Kirch,
  117.    available at fine LDP sites everywhere!)
  118.  
  119. Section 1.6: Hey, what about SLIP?
  120.  
  121. To tell you the truth, I didn't write about it here because I don't know
  122. it.
  123.  
  124. Luckily, this shouldn't be too much of a problem as PPP seems to be the
  125. emerging standard, especially for dynamic IP addressing.
  126.  
  127. Sorry if you're that 2% out there that has dynamic IP addressing with
  128. SLIP, but maybe you can glean a bit out of this HowTo and make your own
  129. setup (if you do then be sure to see Section 4 to get your hack included
  130. in this HowTo!)
  131.  
  132. Section 1.7: Copyright
  133.  
  134. Unless otherwise stated, Linux HowTo documents are copyrighted by their
  135. respective authors. Linux HowTo documents may be reproduced and
  136. distributed in whole or in part, in any medium physical or electronic,
  137. as long as this copyright notice is retained on all copies. Commercial
  138. redistribution is allowed and encouraged; however, the author would like
  139. to be notified of any such distributions.
  140.  
  141. All translations, derivative works, or aggregate works incorporating any
  142. Linux HowTo documents must be covered under this copyright notice. That
  143. is, you may not produce a derivative work from a HowTo and impose
  144. additional restrictions on its distribution. Exceptions to these rules
  145. may be granted under certain conditions; please contact the Linux HowTo
  146. coordinator at the address given below.
  147.  
  148. In short, we wish to promote dissemination of this information through
  149. as many channels as possible. However, we do wish to retain copyright on
  150. the HowTo documents, and would like to be notified of any plans to
  151. redistribute the HowTos.
  152.  
  153. If you have questions, please contact Greg Hankins, the Linux HowTo
  154. coordinator, at gregh@sunsite.unc.edu via email.
  155.  
  156. Section 1.8: A Warning
  157.  
  158. This should go without saying, but I should say it anyways to cover 
  159. things.
  160.  
  161. I'm not sure all of this is the canonical way to do things, and if
  162. something I've done is just too weird let me know how to fix it.  There
  163. might be security risks in all of this, but I don't know of them yet.
  164. This works on my machine, and I don't think it'll break yours too badly
  165. :)  Either way, you should take care when doing this stuff and make sure
  166. you understand at least a bit about what this stuff is doing so you can
  167. fix it if it goes haywire.
  168.  
  169. Also keep in mind this quote from the DNS-HOWTO by Nicolai Langfeldt
  170. <janl@math.uio.nl>:
  171.  
  172.     In this document I state flatly a couple of things that are
  173.     not completely true (they are at least half truths though).
  174.     All in the interest of simplification.  Things will probably
  175.     work if you believe what I say.  
  176.  
  177. *****************************
  178. *The good stuff starts here!*
  179. *****************************
  180.  
  181. 2.0 Hack #1: Keeping your system up and accessible 24/7
  182.     written by Michael Driscoll <fenris@lightspeed.net>
  183.  
  184. This hack involves a problem I have with my ISP.  For reasons unknown to
  185. me (or apparently even to them) they like to hang up on me every five
  186. minutes to five hours.  This was a problem for me because I wanted to be
  187. able to telnet to my Linux box from the computer in math class :) While
  188. it was easy enough to use a cron job to check the network status every
  189. few minutes and start pppd if it wasn't up, since my ISP uses dynamic
  190. addressing I couldn't find my address from the remote machine after this
  191. happened (except by luck).  This hack keeps your PPP session up and puts
  192. your new IP number in an accessible place (your mail spool on your ISP's
  193. mail server).
  194.  
  195. Section 2.1: What you'll need
  196.  
  197. Not too much.  A working PPP setup.  A working sendmail (actually it
  198. just has to be working to the point where it can send a message to your
  199. ISP's mail server).  A working telnetd/ftpd/inetd/whatever setup so you
  200. can actually get into your computer from somewhere else.  A working cron.
  201.  
  202. Section 2.2: Setting up keepalive.sh
  203.  
  204. (note: This section can be probably be better with diald, see section 2.2.2)
  205.  
  206. cron is a daemon that starts programs at specified times.  You can look
  207. at your crontab by running "crontab -e".  We'll be using crontab to run
  208. a shell program that will keep our PPP connection up.
  209.  
  210. Run "crontab -e" as root and add this line:
  211.  
  212. #*/2 * * * * /etc/ppp/keepalive.sh
  213.  
  214. What this does is call the /etc/ppp/keepalive.sh script every two minutes.
  215. (The '#` comments out the entry so it won't start running the script until
  216.  we are ready).
  217.  
  218. Then put the following script named keepalive.sh in /etc/ppp:
  219. -------------------------------------------------------------------------
  220. #!/bin/sh
  221. if [ -f /var/run/ppp0.pid ] ; then
  222.  ping -c4 -l3 <your nameserver> 2>&1 | grep "0 packets" > /dev/null && \
  223.  { /usr/sbin/ppp-off > /dev/null 2>&1 ; sleep 2 ; /usr/sbin/pppd }
  224. else
  225.  /usr/sbin/pppd
  226. fi
  227. ------------------------------------------------------------------------
  228. (PS: This is an experimental script which replaces the old crontab entry
  229. I had here...if you see any problems with it, please let me know!)
  230.  
  231. Now type "chmod 700 /etc/ppp/keepalive.sh" as root to make it an executable
  232. script.
  233.  
  234. Hint1: Check those paths!  For pppd and ppp-off insert whatever it is that
  235.        you use to start/stop your connection.
  236. Hint2: I use your ISP's DNS server because I figure that if that's
  237.        down, your net connection is screwed anyways :)
  238. Hint3: Be sure to use your DNS server's numeric IP address, otherwise
  239.        ping returns a different message and the "grep" won't work.
  240.  
  241. Now whenever you want your connection to stay up, you can just run
  242. crontab -e and take out that "#" to uncomment the entry...and when you
  243. want your connection to stay down, run crontab -e and put the "#" back
  244. in, then kill your connection with ppp-off or whatever it is that you
  245. use.
  246.  
  247. I know there are other ways then this to keep a connection up
  248. (specifically I know that there is a script for pppd, and also a daemon
  249. called pppupd that will do it) but I have not tried them.  If you use
  250. them and think them worthwhile, then drop me a note and I'll try them
  251. out.
  252.  
  253. Section 2.2.1: Using diald instead of a crontab entry 
  254.                       from Divya Mahajan <vmahajan@giasdl01.vsnl.net.in>
  255.  
  256. Apparently, the crontab entry can also be done more elegantly (and more
  257. effeciently) using diald.  I have left the crontab section in for
  258. reference and because it doesn't require an extra package, and when I
  259. try diald out I might switch the order of these two sections.  What
  260. follows is an explanation of how to use diald to acheive a constant
  261. connection.  (I don't actually use the program yet, the comments and
  262. script are courtesy of Divya).
  263.  
  264. 1: Get the latest diald (diald-0.14.tar.gz probably in
  265. ftp://sunsite.unc.edu/pub/Linux/systems/Network/serial/diald-0.14.tar.gz)
  266.  
  267. 2: Compile the stuff. (Actually you could probably get a precompiled diald
  268.         package too from the Slackware sites)
  269.  
  270. 3: After you have installed diald, you must modify /etc/diald.conf
  271.    Add the following lines to the end:
  272.  
  273. > restrict 06:00 19:00 * * *
  274. > up
  275.    (This would force the link to be up between 6am to 7pm everyday.
  276.     If you want 24hrs + 7days remove the restrict.)
  277. > device /dev/modem
  278.    (Use the correct device;)
  279. > dynamic
  280. > reroute
  281. > connect-timeout 120
  282.    (Modify this if your dialer takes a longer or shorter time to connect
  283.     to your ISP)
  284. > redial-timeout 10
  285.    (Interval between 2 redials)
  286. > defaultroute
  287. > accounting-log /var/adm/diald.log
  288.    (Keep track of how much time you are using)
  289. >connect /path_to_myscript
  290.    (You must use a dialing script so add the above line.  When diald
  291.     calls this script both standard input and standard output are
  292.     redirected to /dev/modem (or whatever you chose above) so ensure
  293.     that your dialer script doesn't print any garbage. I personally use
  294.     "/usr/sbin/dip mydipfile.dip >> /var/adm/dip.log 2>
  295.     /var/adm/dip.err" which logs the dial attempts. Initially you may
  296.     want to run dip with the -v option to debug the dip file, i.e #dip
  297.     -v mydipfile.dip.  Remember to put the line "mode ppp" after you
  298.     have logged in and started your PPP services at the ISP (Use
  299.     dip-3.3.7n-uri). Also store all PPP settings in /etc/ppp/options
  300.     rather than relying on the commandline.  Once your DIP file is
  301.     debugged and ready, its time to roll.  Start up diald
  302.     /usr/sbin/diald, if everything went fine it should start dialing and
  303.     connect you to the ISP.  When PPP shutsdown due to modem HUP, diald
  304.     will automatically retry.  Once you are confident, just put
  305.     /usr/sbin/diald into your /etc/rc.d/rc.local)
  306.  
  307. Now you have a 24hr PPP.
  308.  
  309. diald is also good for a lot of other things, like demand dialing per port,
  310. etc.  Look at the diald homepage (http://www.cs.toronto.edu/~schenk/diald.html)
  311. for some examples.
  312.  
  313. Note:  diald only takes the place of the crontab entry, the rest of this
  314. hack will still be needed if you want to make your ip address available
  315. for remote use.
  316.  
  317. Section 2.3: ip-up and ip-down
  318.  
  319. /etc/ppp/ip-up and /etc/ppp/ip-down are rather useful scripts for us.
  320. They are executed when pppd goes up/down and therefore are good for
  321. events that need to occur at this time.  Mine look like this:
  322.  
  323. ip-up:
  324.  
  325. >#!/bin/sh 
  326. >echo -n ^G > /dev/console 
  327. >echo $4 > /var/log/add 
  328. >mail -s "New IP address" fenris@lightspeed.net < /var/log/add 
  329. >chmod 644 /var/log/add
  330. >echo "127.0.0.1 localhost" > /etc/hosts 
  331. >echo $4 ulfheim.lightspeed.net ulfheim >> /etc/hosts
  332.  
  333. ip-down:
  334.  
  335. >#!/bin/sh 
  336. >echo -n ^G > /dev/console 
  337. >rm /var/log/add 
  338. >echo 127.0.0.1 ulfheim.lightspeed.net localhost ulfheim > /etc/hosts
  339.  
  340. Don't worry if you don't get all of this, we'll be explaining most of it
  341. right now.
  342.  
  343. Section 2.3.1: Setting up your ip-up and ip-down
  344.  
  345. The second part of this hack involves making your new IP address
  346. available to you from practically any machine on the net.  To achieve
  347. this we do the following:
  348.  
  349. Create a file as root called /etc/ppp/ip-up.  Put this in it:
  350.  
  351. #!/bin/sh 
  352. # $4 is our new ip address passed by pppd 
  353. # /var/log/add will hold our address 
  354. echo $4 > /var/log/add
  355. # mail our address to our ISP's mail server, with the subject "new ip
  356. # address"
  357. mail -s "New IP address" yourname@your_internet_address < /var/log/add
  358.  
  359. Then create /etc/ppp/ip-down and put this in it:
  360.  
  361. #!/bin/sh 
  362. rm /var/log/add
  363.  
  364. Then run "chmod 700 /etc/ppp/ip-up /etc/ppp/ip-down" to make them
  365. executable.
  366.  
  367. Now edit your rc startup scripts and put in a "rm /var/log/add" anywhere
  368. you feel is appropriate (just in case your power goes down while your
  369. connection is up).  I put it in /etc/rc.d/rc.inet1, which should be
  370. okay.
  371.  
  372. Voila!  Now every time pppd is started your address will be mailed to
  373. your ISP's mail server.  We retreive it in the next section.
  374.  
  375. Section 2.4: How to find out your new IP address from another computer
  376.  
  377. Well, this calls for some resourcefulness on your part.  I really can't
  378. walk you through it, as it depends on which machine you're trying to get
  379. it from.  In Windows, you can try to set up an email program to retrieve
  380. mail from your ISP's mail server, and if you're in Unix see if there's a
  381. program called "popclient" or somesuch.  If all else fails, you can
  382. always use telnet (see the next section).
  383.  
  384. <shadow@indirect.com> has made some scripts that put the status of his
  385. machine and his new IP address on his home page.  Email me at
  386. <fenris@lightspeed.net> and ask for the "dynamic IP home page scripts"
  387. and I'll send you a uuencoded copy of the scripts.  If I get enough
  388. requests for these I'll write up a chapter on it.  BTW you need ftp
  389. access to your ISP's web server for this particular hack.
  390.  
  391. Section 2.4.1: Telnetting to a POP3 server
  392.  
  393. This is how I retrieve my IP address, as I am usually showing off when I
  394. do all of this anyways, and it really confuses all of the GUI users I
  395. show it to :)  Hopefully your ISP uses a POP3 server for mail (most
  396. likely), otherwise you'll just have to figure this out yourself by
  397. looking up the RFC for the protocol you need and figure out how to do it
  398. by telnet.
  399.  
  400. Anyways, first you want to telnet to port 110 of your ISP's mail server.
  401. In Unix you do this with "telnet your_isp's_mail_server 110", on a VAX
  402. you might need to do "telnet your_isp's_mail_server/port=110", and in a
  403. Web browser you should use "telnet://your_isp's_mail_server:110".
  404. Hopefully you can figure it out.
  405.  
  406. Once you are connected, you should see something like this:
  407.  
  408. >Connected to new-ls.lightspeed.net.  
  409. >Escape character is '^]'.  
  410.  
  411. >+OK QUALCOMM Pop server derived from UCB (version 2.1.4-R3) at
  412. >new-ls.lightspeed.net starting.
  413.  
  414. type "user your_username" to login.
  415.  
  416. >+OK Password required for fenris.
  417.  
  418. now type "pass your_password"
  419.  
  420. >+OK fenris has 2 message(s) (3030 octets).
  421.  
  422. type "list" to look at a list of your messages.
  423.  
  424. >+OK 2 messages (3030 octets) 
  425. >1 2400 
  426. >2 630 
  427. >.
  428.  
  429. See that message with size 630?  That's my IP address!  How do I know?
  430. Because it's always that size :)
  431.  
  432. Now type "retr message_number" to retrieve the message you want.
  433.  
  434. >+OK 630 octets 
  435. >Received: from ulfheim.lightspeed.net (avatar@bak2-pp-ls.lightspeed.net
  436. >[204.216.66.74]) by new-ls.lightspeed.net (8.6.12/8.6.12) with ESMTP id
  437. >TAA12048 for <fenris@lightspeed.net>; Mon, 22 Apr 1996 19:15:37 -0700
  438. >Received: (from avatar@localhost) by ulfheim.lightspeed.net (8.7/8.6.9)
  439. >TAA00594 for fenris@lightspeed.net; Mon, 22 Apr 1996 19:15:29
  440. >Date: Mon, 22 Apr 1996 19:15:29 -0700
  441. >From: Deus In Machina <avatar@ulfheim.lightspeed.net>
  442. >Message-Id: <199604230215.TAA00594@ulfheim.lightspeed.net>
  443. >To: fenris@lightspeed.net
  444. >Subject: New IP address 
  445. >204.216.66.74
  446. >
  447. >.
  448.  
  449. And there it is!  Use "dele message_number" to get rid of it or just
  450. "quit" to leave it there and quit.  Now just telnet to your machine at
  451. that address and have fun!
  452.  
  453. If any of this is just not working, then check out RFC 1225, which
  454. describes the POP3 protocol in full detail.
  455.  
  456. By the way, if this part of the hack doesn't work for you because you
  457. have cron automatically downloading your mail, then check out hack #8
  458. which uses procmail to send your new IP address to any email address you
  459. want upon request.
  460.  
  461. 3.0 Hack #2: Dynamically changing /etc/hosts
  462.     written by Michael Driscoll <fenris@lightspeed.net>
  463.  
  464. As I said before, Linux isn't completely happy with dynamic IP
  465. addressing.  For example, sometimes talkd won't work with kludgy values
  466. in /etc/hosts.  However, the following hack makes up for a lot of that
  467. by changing /etc/hosts according to the IP address we receive when we
  468. call up our ISP.
  469.  
  470. For me this fixed problems with "hostname" and "talk".
  471.  
  472. Section 3.1: What you'll need.
  473.  
  474. Nothing but a working PPP setup, really.
  475.  
  476. Section 3.2: More fun with ip-up and ip-down
  477.  
  478. This hack is really very easy, and only involves three files, ip-up,
  479. ip-down, and an rc file (I put it in rc.S).
  480.  
  481. ***   First, make a backup of /etc/hosts, just in case this screws up  ***
  482. *** anything.  Also, if you have anything more complex than a two-line ***
  483. ***        /etc/hosts or so, then this will need modifying.            ***
  484.  
  485. Add the following lines to /etc/ppp/ip-up:
  486.  
  487. echo 127.0.0.1 localhost > /etc/hosts 
  488. echo $4 yourmachine.yourdomain yourmachine >> /etc/hosts 
  489. #
  490.  
  491. EXAMPLE:  My machine is named "ulfheim" and its domain is
  492. "lightspeed.net".  The lines in my ip-up say:
  493.  
  494. echo 127.0.0.1 localhost > /etc/hosts 
  495. echo $4 ulfheim.lightspeed.net ulfheim >> /etc/hosts 
  496. #
  497.  
  498. Then add the following lines to /etc/ppp/ip-down:
  499.  
  500. ------------------------------------------------------------------------ 
  501. echo 127.0.0.1 yourmachine.yourdomain localhost yourmachine > /etc/hosts
  502. ------------------------------------------------------------------------
  503.  
  504. EXAMPLE:  My machine is named "ulfheim" and its domain is
  505. "lightspeed.net".  The lines in my ip-down say:
  506.  
  507. ------------------------------------------------------------------------ 
  508. echo 127.0.0.1 ulfheim.lightspeed.net localhost ulfheim > /etc/hosts 
  509. ------------------------------------------------------------------------
  510.  
  511. Now put the following in an rc script (I chose rc.S, it seems ok there).
  512.  
  513. ------------------------------------------------------------------------ 
  514. echo 127.0.0.1 yourmachine.yourdomain localhost yourmachine > /etc/hosts
  515. ------------------------------------------------------------------------
  516.  
  517. EXAMPLE:  My machine is named "ulfheim" and its domain is
  518. "lightspeed.net".  The lines at the end of my /etc/rc.d/rc.S say:
  519.  
  520. ------------------------------------------------------------------------ 
  521. echo 127.0.0.1 ulfheim.lightspeed.net localhost ulfheim > /etc/hosts 
  522. ------------------------------------------------------------------------
  523.  
  524. This last one is in case your power goes out or something while your
  525. connection was still up, it restores your offline /etc/hosts.
  526.  
  527. 4.0 Hacks #3-5: Various hacks from Ryan R. Klems <rklems@primenet.com>
  528.     intro written by Michael Driscoll <fenris@lightspeed.net>
  529.     code straight from Ryan R. Klems <rklems@primenet.com>
  530.  
  531. Here's some C code sent to me from Ryan R. Klems <rklems@primenet.com>.
  532.  
  533. There are three programs, the first, mail.c, is a CGI that scans
  534. through your mail spool for your new IP address as set up by Hack #1.
  535. It then uses the IP address to set up a page containing a link to this
  536. IP address.
  537.  
  538. The second, pppdm.c, can probably take the place of hack #1, as it looks
  539. for a PPP connection, restarts pppd if it is down, and mails your new ip
  540. address to your ISP's mailserver.
  541.  
  542. The third, portmsg.c, sits on a specified port and waits for a telnet
  543. connection.  Upon connection, it will pull grep your mail spool for your
  544. newest IP and output a message containing that.
  545.  
  546. These sources will need a bit of customization, so you probably
  547. shouldn't mess with them unless you know what they are doing.
  548.  
  549. Oh yes, and Ryan has written to tell me that he wouldn't mind helping
  550. you set up the code to meet your needs, as long as you ask nicely :-)
  551.  
  552. Section 4.1: mail.c
  553.  
  554. /*
  555.  * mail.c written by Ryan R. Klems (rklems@primenet.com)
  556.  * Copyright 1996, Author releases this source freely, allowing
  557.  * copying and modification, so long as the original copyright notice
  558.  * is maintained.
  559.  *
  560.  * I request that if you use this file you mail me... Thats all I ask =)
  561.  *
  562.  * A CGI for reading through your mailfile and finding an IP
  563.  * address that you had your computer mail to you.
  564.  *
  565.  * Compiling:
  566.  *    gcc mail.c -o mail.cgi
  567.  *
  568.  * Make sure to 'chmod +s mail.cgi' afterwards...must run with set uid
  569.  * bit on to be able to open the mail file.
  570.  */
  571.  
  572. #include <stdio.h>
  573. #include <string.h>
  574. #define MAILFILE "/var/mail/rklems" /* your mailfile */
  575.  
  576. main(void)
  577. {
  578.   FILE *mail;    /* file pointer for mail file */
  579.   char bob[80], location[80];
  580.  
  581.   printf("Content-type: text/html\n\n");
  582.   printf("<HTML><HEAD><TITLE>IP Address</TITLE></HEAD>\n");
  583.   printf("<BODY><BASEFONT SIZE=4>\n");
  584.   printf("<H1>IP Address</H1>\n");
  585.   strcpy(bob, "42.**");
  586.   if((mail = fopen(MAILFILE, "r")) == NULL)
  587.     printf("Mail file is empty or does not exist.\n");
  588.   else
  589.   {
  590.     /* 
  591.      * loop continues till end of file because you want most recent IP
  592.      * 198.68. is the domain of my ISP, change to yours...
  593.      */
  594.     while(!feof(mail)) /* until reaching EOF, do this */
  595.     {
  596.       fgets(location, 80, mail); /* Grab a line, from mail */
  597.       sscanf(location, "198.68.%s", bob); /* look for domain */
  598.     }
  599.     strcpy(location, "198.68.");
  600.     strcat(location, bob);
  601.     printf("The IP Address of your computer is: %s\n", location);
  602.   }
  603.   printf("</BODY></HTML>\n");
  604. }
  605.  
  606. Section 4.2: pppdm.c
  607.  
  608. /*
  609.  * pppdm.c created by Ryan R. Klems (rklems@primenet.com)
  610.  *   Released freely by the author to use/modify/copy/reditribute
  611.  *   My only request is that if you use it...mail me and let me know =)
  612.  *
  613.  * This program keeps your link dialed up to an ISP and mails you
  614.  * the newest IP address.  Useful for people with Dynamically allocated 
  615.  * IP addresses
  616.  * uses the following files...
  617.  * /root/ip        :   Outputs the IP to this file
  618.  * /root/log       :   If logging is defined
  619.  * /root/pppchat   :   The chat file set up for chat.
  620.  *     My chat file looks like:
  621.  *       ""  ATDT7917777 CONNECT "" "ogin:" "rklems" "assword:" "<password>"
  622.  *  <password> is YOUR password of course (like I'm gonna give you mine ;)
  623.  *  *NOTE* for silent dialing do ATMDT
  624.  *
  625.  *  Compiling...
  626.  *    gcc pppdm.c -o pdm
  627.  *  *NOTE* Don't call it anything like pppdm b/c it looks for pppd
  628.  *  might accidentally kill itself off ;)
  629.  */
  630.  
  631. #include <stdio.h>
  632. #include <stdlib.h>
  633. #include <unistd.h>
  634. #include <signal.h>
  635. #include <time.h>
  636. #define DOLOG
  637.  
  638. void main(void)
  639. {
  640.   FILE *fin,        /* multiuse file pointer */
  641.        *popen();    /* proto of popen() */
  642. #ifdef DOLOG
  643.   FILE *log;        /* log file pointer */
  644. #endif
  645.   char line[80],    /* a line of a file */
  646.        bah[80],        /* just stuff, also used for holding IP addr */
  647.        crap[80],    /* just stuff */
  648.        bob;        /* single char placeholder, not used for anything */
  649.   int j,        /* flag for if a link was found */
  650.       k,        /* flag for if this is a new link */
  651.       pid;        /* pid of pppd process to kill off */
  652. #ifdef DOLOG
  653.   time_t now;        /* thing for time logging */
  654. #endif
  655.  
  656.   for(;;) /* Loop forever... */
  657.   {
  658.     /* look at ifconfig for IP addr */
  659.     if ((fin = popen("ifconfig", "r")) != NULL)
  660.       while(fgets(line, 80, fin) != NULL)
  661.         if(sscanf(line, "ppp0 %s", bah))
  662.         {
  663.           fgets(line, 80, fin);
  664.           sscanf(line, "          inet addr:%15s", bah);
  665.           j=1;
  666.         }
  667.     fclose(fin);
  668.     if (!j) /* no link */
  669.     {
  670.       if((fin = popen("ps -a -x", "r")) == NULL)
  671.       {
  672.         fprintf(stderr, "PPPdm error: cannot open file.\n");
  673.         exit(1);
  674.       }
  675.       /* scan through processes & kill off any zombie pppd processes */
  676.       while(fgets(line, 80, fin) != NULL)
  677.         if (sscanf(line, "%d  ?  %c     %4s pppd%s", &pid, &bob, crap, bah) == 4)
  678.           kill(pid, SIGKILL);
  679.       fclose(fin);
  680.       k=0; /* new dial attempt */
  681.       system("pppd connect 'chat -v -f /root/pppchat'"); /* try again */
  682. #ifdef DOLOG
  683.       now = time(NULL);
  684.       if ((log = fopen("/root/log", "a")) == NULL)
  685.       {
  686.         fprintf(stderr, "Error in opening log file.\n");
  687.         exit(1);
  688.       }
  689.       fprintf(log, "Initiating ppp-link. %s\n", ctime(&now));
  690.       fclose(log);
  691. #endif
  692.       sleep(60); /* wait 1 min and check again */
  693.     }
  694.     if(j && !k) /* first time with new address */
  695.     {
  696.       if ((fin = fopen("/root/ip", "w")) == NULL)
  697.       {
  698.         fprintf(stderr, "Error in opening output file.\n");
  699.         exit(1);
  700.       }
  701.       fprintf(fin, "%s\n", bah); /* write out addr */
  702.       fclose(fin);
  703.       /* mail it to yourself */
  704.       system("mail -s IP joker@your.moma.com < /root/ip");
  705.       k=1;
  706.     }
  707.     else /* take a nap and check again when we wake up */
  708.     {
  709.       j = 0;
  710.       sleep(300); /* wait 5 minutes to check again */
  711.     }
  712.   }
  713. }
  714.  
  715. Section 4.3: portmsg.c
  716.  
  717. /*
  718.  * Portmsg.c written by Ryan R. Klems (rklems@primenet.com)
  719.  * Copyright 1996, Author releases this source freely, allowing
  720.  * copying and modification, so long as the original copyright notice
  721.  * is maintained.
  722.  *
  723.  * I request that if you use this program that you mail me.  Thats
  724.  * all I ask.
  725.  *
  726.  * This program sets up a port on a server to accept telnets.  Upon
  727.  * accepting a telnet, the program outputs a message, and then closes
  728.  * the connection.
  729.  *
  730.  * address of message would be xxx.xxx.xxx.xxx yyyy where the x's
  731.  * s the IP number or IP name, and yyyy is the port number set up
  732.  * within this program.
  733.  *
  734.  * Compiling instructions:
  735.  *    Linux : gcc portmsg_gen.c -o <your_file_name>
  736.  *      SunOS : gcc portmsg_gen.c -lsocket -lnsl -o <your_file_name>
  737.  * ***Note***
  738.  *  I don't have access to any other operating systems, so if you
  739.  *  compile this program on an OS I don't have listed, and use 
  740.  *  compiler options I didn't mention...please email me =)
  741.  */
  742.  
  743. #include <stdlib.h>
  744. #include <stdio.h>
  745. #include <sys/types.h>
  746. #include <sys/socket.h>
  747. #include <sys/uio.h>
  748. #include <errno.h>
  749. #include <netinet/in.h>
  750. #include <strings.h>
  751. #include <netdb.h>
  752. #include <unistd.h>
  753. #define HOSTNAME "ares" /* hostname of computer */
  754. #define PORT 3000    /* tcp port to bind to */
  755. /* #define GETHOSTNAME */ /* uncomment if your server has gethostname() */
  756.  
  757. void get_location(void);    /* proto of my mail reading function */
  758. char location[80];        /* The IP address */
  759.  
  760. void main(void)
  761. {
  762.   struct in_addr host_ip_number;
  763.   struct sockaddr_in host_ip_addr;
  764.   struct sockaddr_in addr;
  765.   char host_name[100];
  766.   struct hostent *hp;
  767.   int s, new_sock;
  768.   int tmp, length;
  769.  
  770.   /* 
  771.    * The server I wrote this for doesn't have gethostname()
  772.    * so, I put in a little fix...
  773.    */
  774. #ifdef GETHOSTNAME
  775.   gethostname(host_name, sizeof(host_name));
  776. #else
  777.   strcpy(host_name, HOSTNAME); 
  778. #endif
  779.   hp = gethostbyname(host_name);
  780.   bzero((char *)&host_ip_addr, sizeof(host_ip_addr));
  781.   memcpy((char *)&host_ip_addr.sin_addr, hp->h_addr, hp->h_length);
  782.   host_ip_addr.sin_family = hp->h_addrtype;
  783.   host_ip_number = host_ip_addr.sin_addr;
  784.   host_ip_addr.sin_port = htons(PORT);
  785.   host_ip_addr.sin_addr.s_addr = INADDR_ANY;
  786.   /* open a socket s */
  787.   s = socket(host_ip_addr.sin_family, SOCK_STREAM, 0);
  788.   if ((int)s==-1)
  789.   {
  790.     fprintf(stderr, "Error in opening socket.\n");
  791.     exit(1);
  792.   }
  793.   tmp = 1;
  794.   if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp))<0)
  795.   {
  796.     fprintf(stderr, "Error in setsockopt.\n");
  797.     exit(1);
  798.   }
  799.   /* bind the socket to the server */
  800.   if (bind(s, (struct sockaddr *)&host_ip_addr, sizeof(host_ip_addr))  == -1)
  801.   {
  802.     if(errno == EADDRINUSE)
  803.     {
  804.       fprintf(stderr, "Socket already bound!\n");
  805.       exit(1);
  806.     }
  807.     else
  808.     {
  809.       fprintf(stderr, "Other error binding socket.\n");
  810.       exit(1);
  811.     }
  812.   }
  813.   /* tell the server to listen to the port */
  814.   if (listen(s, 1) == -1)
  815. /* 1 is the maximum size of the connection queue */
  816.   {
  817.     fprintf(stderr, "Error in listen.\n");
  818.     exit(1);
  819.   }  
  820.  while(1) /* just keep looping */
  821.  {
  822.    length = sizeof(addr);
  823.    /*
  824.     * port has been opened with socket(), bound with bind(), and set
  825.     * active with listen(), now accept() watches the port for 
  826.     * connections, it will wait here until it has one...
  827.     * new_sock is the file descriptor for the new socket
  828.     */
  829.    new_sock = accept(s, (struct sockaddr *)&addr, &length);
  830. /*
  831.  * The function get_location() and the send()'s are what I did to
  832.  * suit my particular needs.  Put your own messages in here...
  833.  */
  834.    get_location();
  835.    /* send just sends a string foo of length strlen(foo) with flags */
  836.    send(new_sock, "Location:\n", 11, 0);
  837.    send(new_sock, location, strlen(location), 0);
  838.    close(new_sock); /* Close connection after message printed */
  839.  }
  840. }
  841.  
  842. void get_location(void)
  843. {
  844.   FILE *mail;    /* file pointer for mail file */
  845.   char a[80];    /* char array for holding ip addr */
  846.  
  847. /* 
  848.  * FYI, this just opens my mail file, looks for a line with
  849.  * 198.68.(the domain of my ISP), takes the last part, puts
  850.  * the 198.68. in location, then cats the rest on the end
  851.  */
  852.   strcpy(a, "42.**");
  853.   /* open /var/mail/ryan for read, and check to see there is a file */
  854.   if((mail = fopen("/var/mail/ryan", "r")) == NULL)
  855.   {
  856.     strcpy(location, "Error in obtaining information.\n");
  857.     return;
  858.   }
  859.   else
  860.   {
  861.     while(!feof(mail)) /* until reaching EOF, do this */
  862.     {
  863.       fgets(location, 80, mail); /* Grab a line, from mail */
  864.       sscanf(location, "198.68.%s", a); /* look for domain */
  865.     }
  866.     strcpy(location, "198.68.");
  867.     strcat(location, a);
  868.     /* loops continues till end of file because I want most recent IP */
  869.   }
  870. }
  871.  
  872. 5.0 Hack #6: Setting up a dynamic DNS entry by Matthew Driver
  873.     <mdriver@cfmeu.asn.au>
  874.  
  875. There is already a page on this, at 
  876. http://www.cfmeu.asn.au/matthew/virtualip.html.  Check it out, Matthew
  877. just got it working and is asking for other people to try it to iron out
  878. the fine details.
  879.  
  880. 6.0 Hack #7: Updating your .plan by Matthew Nuckolls <mnuck@umr.edu>
  881.     written by Matthew Nuckolls <mnuck@umr.edu>
  882.  
  883. This pair of scripts allows one to put their current IP number in their 
  884. .plan file on a remote server. I use it so friends and family can see if 
  885. I'm dialed in, and where to send ytalk requests to.
  886.  
  887. Put something like
  888.  
  889. /etc/ppp/putip "None, the link is down"
  890.  
  891. as the first line in your ppp-off script.
  892.  
  893. You need a valid $HOME/.netrc file for putip to work. mine looks like:
  894.  
  895. machine rocket
  896. login mnuck
  897. password <mypassword>
  898.  
  899. and is chmod 600
  900.  
  901. -Matthew Nuckolls
  902.  mnuck@umr.edu
  903.  
  904. ----------ip-up:
  905.  
  906. #!/bin/sh
  907. #
  908. # make sure this is chmod 711, since your password is stored in the clear
  909.  
  910. PLANLOC = /home/mnuck/.plan
  911. REMOTE_USER_NAME = mnuck
  912. REMOTE_PASSWORD =
  913. REMOTE_PLANLOC = /afs/umr.edu/users/mnuck/pub/.plan
  914. REMOTE_SERVER = rocket
  915.  
  916. echo "My dynamic IP is: " $4 > /tmp/ip.myip
  917.  
  918. cat $PLANLOC /tmp/ip.myip > /tmp/plan
  919.  
  920. echo $REMOTE_USER_NAME > /tmp/ip.script
  921. echo $REMOTE_PASSWORD >> /tmp/ip.script
  922. echo "put /tmp/plan" $REMOTE_PLANLOC >> /tmp/ip.script
  923. echo "quit" >> /tmp/ip.script
  924.  
  925. ftp $REMOTE_SERVER < /tmp/ip.script &> /dev/null
  926.  
  927. rm -f /tmp/ip.myip
  928. rm -f /tmp/ip.script
  929. rm -f /tmp/plan
  930.  
  931. ----------end ip-up
  932. ----------putip:
  933.  
  934. #!/bin/sh
  935. #
  936. # This script relies on a vaild .netrc file
  937. #  -see ftp man page for details
  938.  
  939. PLANLOC = /home/mnuck/.plan
  940. REMOTE_PLANLOC = /afs/umr.edu/users/mnuck/pub/.plan
  941. REMOTE_SERVER = rocket
  942.  
  943. echo "My dynamic IP is: " $1 > /tmp/ip.myip
  944.  
  945. cat $PLANLOC /tmp/ip.myip > /tmp/plan
  946.  
  947. echo "put /tmp/plan" $REMOTE_PLANLOC > /tmp/ip.script
  948. echo "quit" >> /tmp/ip.script
  949.  
  950. ftp $REMOTE_SERVER < /tmp/ip.script &> /dev/null
  951.  
  952. rm -f /tmp/ip.myip
  953. rm -f /tmp/ip.script
  954. rm -f /tmp/plan
  955.  
  956. ----------end putip
  957.  
  958. 7.0 Hack #8: A simple procmail recipe for finding your new IP
  959.     by Justin Cragin <beyond@lightspeed.net>
  960.           written by Michael Driscoll <fenris@lightspeed.net>
  961.  
  962. Here's an easy one, assuming you already have procmail set up.  This
  963. hack requires that you have a spare shell/email account where you can
  964. temporarily stick your mail and is useful when you can't use the mailing
  965. trick in hack one to get your new IP address because you have a cron job
  966. regularly downloading your mail.
  967.  
  968. In your .procmailrc, simply add the following recipe:
  969.  
  970. :0:
  971. * ^Subject: sendmeip
  972. |mail -s "Your new IP" other.mail.address@site.net < /var/log/add
  973.  
  974. For the email address use a shell account whose mail is not being
  975. regularly downloaded by a cronjob to your local machine (what, doesn't
  976. anybody else collect shell accounts?  I have four so far ;)
  977.  
  978. /var/log/add is of course the file containing your IP address that
  979. we set up in hack one.
  980.  
  981. Now to use this, just mail yourself from any place on the 'net with
  982. a subject of sendmeip, and then telnet to the shell account and wait
  983. for the cronjob on your machine at home to download that mail and
  984. automatically send you a reply with your new IP in it!
  985.  
  986. 8.0 We need more hacks!
  987.  
  988. If you have a Dynamic IP hack that you would like to contribute to this
  989. HowTo, then let me know.  Be warned that if you do so that it will have
  990. to be covered under the copyright notice in Section 1.5, for reasons of
  991. CD publishing and whatnot.
  992.  
  993. If you {liked this HowTo, didn't like this HowTo, thought this HowTo was
  994. too confusing, found something in this HowTo that doesn't work and/or is
  995. just plain wrong, want to send me email, don't want to send me email,
  996. found a security problem in this HowTo, etc} then please mail me at
  997. <fenris@lightspeed.net>.  I mean it, I really would appreciate *any*
  998. feedback on this HowTo, even if you just mailed me to say that you read
  999. it!
  1000.  
  1001. Really!  Just e-mail me on anything!  I *really do* love getting e-mail!
  1002.  
  1003. Flames will *not* go to /dev/null.  I think if you feel that strongly
  1004. about it, I should listen.
  1005.  
  1006. If you write up a chapter for this HowTo not only will you be helping
  1007. the Linux community, but you will receive full credit for your hack,
  1008. your name will go into the credits at the end of this HowTo, you will be
  1009. acknowledged as a contributor in the beginning of this HowTo, your idea
  1010. will be archived with almost every CD Linux distribution in the world,
  1011. you'll be the envy of all of your peers, etc.
  1012.  
  1013. 9.0 CREDITS
  1014.  
  1015. Michael Driscoll <fenris@lightspeed.net> 
  1016.   is the HowTo moderator and the author of hacks one and two.
  1017. Christian G. Warden <cwarden@loop.com>
  1018.   helped debug the keepupalive.sh script used in hack one, now the thing
  1019.   will work in (hopefully) all cases, including those when the connection
  1020.   goes down but pppd does not.
  1021. Justin Cragin <beyond@lightspeed.net>
  1022.   gave me the idea for hack one, and then got mad when he found out I
  1023.   stole it.  I also stole the message for my answering machine from him,
  1024.   so I guess I owe him this one.  He also recently thought up a nice hack
  1025.   that has become hack eight, so he is now thrice credited.
  1026. <shadow@indirect.com> 
  1027.   gave me copies of some real neat scripts of his, see 2.4 for details.
  1028.   I seem to have lost his name, hopefully he'll send it to me again :)
  1029. Ajit Deshpande <adeshpan@ddt.eng.uc.edu> 
  1030.   wanted to be in the credits.
  1031. Divya Mahajan <vmahajan@giasdl01.vsnl.net.in>
  1032.   sent me the info on diald, which could probably end up replacing the
  1033.   crontab entry in hack one.
  1034. Ryan Klems <rklems@primenet.com>
  1035.   sent me a bunch of his own hacks, see 4.x for details.
  1036. Matthew Driver <mdriver@cfmeu.asn.au>
  1037.   gave me a pointer to his page on dynamic DNS entries.  Check out
  1038.   5.0 for the URL.
  1039. Matthew Nuckolls <mnuck@umr.edu>
  1040.   gave me hack seven, which updates a .plan containing your new IP address
  1041.   on a remote server via ftp.
  1042. Scott Johnston <sj@odin.iac.net>
  1043.   showed me a better way to set up hack one (took out long and confusing
  1044.   crontab entry and put it in script called by cron instead), and gave me
  1045.   various other pointers.
  1046. -- 
  1047. Michael Driscoll <fenris@lightspeed.net>
  1048.  
  1049.