Newsgroups: comp.os.linux.announce
From: juphoff@chaos.aoc.nrao.edu (Uppie)
Subject: DIP patch (dynamic IP address trapping, route 'default' option)
Message-ID: <1993Jul1.142935.23137@dg-rtp.dg.com>
Approved: linux-announce@tc.cornell.edu (Matt Welsh)
Date: Thu, 1 Jul 93 14:29:35 GMT

[Moderator's note: This is a patch against the DIP sources found in 
NET-2 (net-010.tar.z). The NET-2-FAQ can provide details. --mdw]

For those of us that have our SLIP IP addresses assigned dynamically,
here is a patch for dip that will trap the address when the remote
host 'displays' it.  (This is an option--those that don't want this
need not enable it.)

The meat of this patch was written by Paul Mossip (mossip@vizlab.rutgers.edu)
Someone mentioned the existance of his patch, so I emailed him requesting
a copy and he anonymously ftp'd it into my linux box.  

I have been using it heavily for several days now, and it works
beautifully.  Bravo to the author!  (And many thanks)

I extended his patch a slight bit; whenever I initiated a slip connection,
dip executed a 'route' command that assigned the remote machine's IP
address as both my Destination net/address and my Gateway address.
My connection would not function unless I deleted that route and created
a new one specifying my Destination net/address as 'default'.
I have added 'default' to the set of commands that dip accepts--
if you use it, your Destination net/address will be set to 'default',
if you don't use it, dip sets up the route as it did before.  (This
command, like the ones that Paul added, can either be entered in
dip's command mode, or read in from a script file.)

The abilites that Paul's patch added to dip allowed me to totally
automate my SLIP connections, with the exception of the routing change.
This patch has taken the last step; everything is done from a script
file and I haven't had a problem with the address assignment trapping once.

Those that have to deal with dynamically assigned IP address will
find this very useful.

Thanks once again to Paul Mossip--he put all of the real work into
this patch.


++++++++++ CUT HERE ++++++++++
diff -c ifconfig_old/dip/attach.c ifconfig/dip/attach.c
*** ifconfig_old/dip/attach.c	Tue Jun  8 08:58:49 1993
--- ifconfig/dip/attach.c	Wed Jun 30 02:36:40 1993
***************
*** 30,36 ****
  #endif
    if (system(buff) != 0) return(-1);
  
!   sprintf(buff, "%s add %s", _PATH_BIN_ROUTE, inet_ntoa(dip->rmt_ip));
    sprintf(&buff[strlen(buff)], " gw %s", inet_ntoa(dip->rmt_ip));
  #ifdef DEBUG
    syslog(LOG_ERR, ">>> ATTACH \"%s\"\n", buff);
--- 30,41 ----
  #endif
    if (system(buff) != 0) return(-1);
  
!   if (route_default == 1) {
!   	sprintf(buff, "%s add default", _PATH_BIN_ROUTE);
!   } else {
!   	sprintf(buff, "%s add %s", _PATH_BIN_ROUTE, inet_ntoa(dip->rmt_ip));
!   }
! 
    sprintf(&buff[strlen(buff)], " gw %s", inet_ntoa(dip->rmt_ip));
  #ifdef DEBUG
    syslog(LOG_ERR, ">>> ATTACH \"%s\"\n", buff);
diff -c ifconfig_old/dip/command.c ifconfig/dip/command.c
*** ifconfig_old/dip/command.c	Mon May 31 09:54:06 1993
--- ifconfig/dip/command.c	Wed Jun 30 04:10:32 1993
***************
*** 15,29 ****
  
  
  static _PROTOTYPE( int	do_dial, (int, char **)				);
  static _PROTOTYPE( int	do_goto, (int, char **)				);
  static _PROTOTYPE( int	do_help, (int, char **)				);
  static _PROTOTYPE( int	do_if, (int, char **)				);
- static _PROTOTYPE( int	do_local, (int, char **)			);
  static _PROTOTYPE( int	do_mode, (int, char **)				);
- static _PROTOTYPE( int	do_mtu, (int, char **)				);
  static _PROTOTYPE( int	do_port, (int, char **)				);
  static _PROTOTYPE( int	do_print, (int, char **)			);
- static _PROTOTYPE( int	do_remote, (int, char **)			);
  static _PROTOTYPE( int	do_reset, (int, char **)			);
  static _PROTOTYPE( int	do_send, (int, char **)				);
  static _PROTOTYPE( int	do_sleep, (int, char **)			);
--- 15,28 ----
  
  
  static _PROTOTYPE( int	do_dial, (int, char **)				);
+ static _PROTOTYPE( int	do_default, (int, char**)			);
+ static _PROTOTYPE( int	do_get, (int, char **)			        );
  static _PROTOTYPE( int	do_goto, (int, char **)				);
  static _PROTOTYPE( int	do_help, (int, char **)				);
  static _PROTOTYPE( int	do_if, (int, char **)				);
  static _PROTOTYPE( int	do_mode, (int, char **)				);
  static _PROTOTYPE( int	do_port, (int, char **)				);
  static _PROTOTYPE( int	do_print, (int, char **)			);
  static _PROTOTYPE( int	do_reset, (int, char **)			);
  static _PROTOTYPE( int	do_send, (int, char **)				);
  static _PROTOTYPE( int	do_sleep, (int, char **)			);
***************
*** 36,51 ****
    char	*name;
    int	(*func)(int, char **);
  } commands[] = {
    { "dial",		do_dial		},
    { "goto",		do_goto		},
    { "help",		do_help		},
    { "if",		do_if		},
-   { "local",		do_local	},
    { "mode",		do_mode		},
-   { "mtu",		do_mtu		},
    { "print",		do_print	},
    { "port",		do_port		},
-   { "remote",		do_remote	},
    { "reset",		do_reset	},
    { "send",		do_send		},
    { "sleep",		do_sleep	},
--- 35,49 ----
    char	*name;
    int	(*func)(int, char **);
  } commands[] = {
+   { "default",		do_default	},
    { "dial",		do_dial		},
+   { "get",		do_get   	},
    { "goto",		do_goto		},
    { "help",		do_help		},
    { "if",		do_if		},
    { "mode",		do_mode		},
    { "print",		do_print	},
    { "port",		do_port		},
    { "reset",		do_reset	},
    { "send",		do_send		},
    { "sleep",		do_sleep	},
***************
*** 523,573 ****
   *									*
   ************************************************************************/
  
  
! /* Set the name of the local side. */
! static int do_local(argc, argv)
! int argc;
! char *argv[];
! {
!   struct hostent *hp;
! 
!   if (argc != 2) {
! 	fprintf(stderr, "Usage: local name\n");
! 	return(-1);
!   }
!   strncpy(mydip.local, argv[1], 128);
!   if ((hp = gethostbyname(mydip.local)) == (struct hostent *)NULL) {
! 	herror(mydip.local);
! 	strcpy(mydip.local, "");
! 	return(-1);
!   }
!   strncpy(mydip.local, hp->h_name, 128);
!   memcpy((char *) &mydip.loc_ip, (char *) hp->h_addr_list[0], hp->h_length);
!   return(0);
! }
! 
! 
! /* Set the name of the remote side. */
! static int do_remote(argc, argv)
! int argc;
! char *argv[];
! {
!   struct hostent *hp;
! 
!   if (argc != 2) {
! 	fprintf(stderr, "Usage: remote name\n");
! 	return(-1);
!   }
!   strncpy(mydip.remote, argv[1], 128);
!   if ((hp = gethostbyname(mydip.remote)) == (struct hostent *)NULL) {
! 	herror(mydip.remote);
! 	strcpy(mydip.remote, "");
! 	return(-1);
!   }
!   strncpy(mydip.remote, hp->h_name, 128);
!   memcpy((char *) &mydip.rmt_ip, (char *) hp->h_addr_list[0], hp->h_length);
!   return(0);
! }
  
  
  /* Enter a specific protocol. */
--- 521,655 ----
   *									*
   ************************************************************************/
  
+ /* Get or ask for the value of a variable */
+ /* get local IP#, Remote IP# and MTU */
  
! #define VAR_IP 1
! #define VAR_NUM 2
! #define VAR_STR 3
! 
! static int do_get(argc, argv)
! int argc;
! char *argv[];
! {
!    char str[128]="";
!    int var=0;
!    void *v1=NULL,*v2=NULL;
!    _PROTOTYPE( void (*oldsig), (int) );
!    
!    if (argc <= 2 || argc > 4 || argv[1][0]!='$') {
!  	fprintf(stderr, "Usage: get $variable [value|ask|remote [timeout_value]]\n");
!  	return(-1);
!    }
!    
!    if (!strcmp(argv[1], "$locip")||!strcmp(argv[1], "$local"))
!        { v1= (void *) mydip.local; v2= (void *) &mydip.loc_ip; var=VAR_IP;}
!    else if (!strcmp(argv[1], "$rmtip")||!strcmp(argv[1], "$remote"))
!        { v1= (void *) mydip.remote; v2= (void *) &mydip.rmt_ip; var=VAR_IP;}
!    else if (!strcmp(argv[1], "$mtu"))
!        { v1= (void *) &mydip.mtu; var=VAR_NUM;}
!    else {
!      fprintf(stderr, "Variables must be :$locip|$rmtip|$local|$remote|$mtu\n");
!      return (-1);
!    }
!  
!    if (argc > 2) {
!      if (!strcmp(argv[2],"ask")) {
!        /* "ask" ask the stdinput for the value of the variable and 
!           put it in str */
!        register char *sp;
!        fprintf(stderr, "Enter the value for %s: ",argv[1]);
!        if (fgets(str, 128, stdin) == (char *)NULL) return (1);
!        if ((sp = strchr(str, '\n')) != (char *)NULL) *sp = '\0';
!      }
!      else if (!strcmp(argv[2],"remote")) {
!        /* Get the variable string from the "remote" line */
!        register char c,*p;
!        int howlong=0,state=0;
!        if (argc == 4) howlong = atoi(argv[3]);
! 
!        oldsig = signal(SIGALRM, TimeOut);
!        (void) alarm(howlong);
! 
!        p = str;
!        timeout = state = 0;
!        if (var == VAR_IP ||var == VAR_NUM) state = 1;
!        while(!timeout && (state >= 0)) {
! 	 c = (char) tty_getc();
! 	 c &= 0177;
! 	 if (timeout == 1) break;
! 	 switch (state) {
! 	 case 0: /* start by throwing away "white space" */
! 	   if (!strchr(" \n\t",c)) break;
! 	   if (var == VAR_STR) { *(p++) = c; state = 10; break;}
! 	   state=1;
! 	 case 1:
! 	   if ( c >= '0' && c <='9' ) {
! 	     *(p++)=c;
! 	     if (var == VAR_IP) { state=2; break;}
! 	     else state=5;
! 	     break;
! 	   }
! 	   break; 
! 	 case 2: case 3: case 4:
! 	   if ((c >= '0' && c <='9')|| c == '.') {
! 	     *(p++) = c;
! 	     if (c == '.') state++;
! 	     break;
! 	   } 
! 	   p = str;
! 	   state = 0;
! 	   break;
! 	 case 5:
! 	   if (c >= '0' && c <='9') {
! 	     *(p++) = c;
! 	     break;
! 	   } 
! 	   state=-1;
! 	   break;
! 	 case 10:
! 	   if (strchr(" \n\t",c)) state =-1;
! 	   else *(p++) = c;
! 	   break;
! 	 default:
! 	   break;
! 	 }
!        }
!        *p='\0';
!        (void) alarm(0);
!        (void) signal(SIGALRM, oldsig);
!        if (timeout == 1) return (1);
!      }
!      else   /* the third argv is the value for the variable */
!        strncpy(str,argv[2],128);
!    }
!    if (opt_v == 1) printf("About to set variable %s to %s\n",argv[1],str);
! 
!    if (*str){
!      switch (var){
!      case VAR_IP:
!        {
! 	 struct hostent *hp;
! 	 if ((hp = gethostbyname(str)) == (struct hostent *)NULL){
! 	   herror (str);
! 	   return (-1);
! 	 }
! 	 strncpy((char *)v1,hp->h_name,128);
! 	 memcpy((char *)v2,(char *) hp->h_addr_list[0],hp->h_length);
!        }
!        break;
!      case VAR_NUM:
!        *(int *)v1= atoi(str);
!        break;
!      case VAR_STR:
!        strcpy((char *)v1,str);
!        break;
!      default:
!        break;
!      }
!    }
!        return(0);
!  }
  
  
  /* Enter a specific protocol. */
***************
*** 597,614 ****
  }
  
  
! /* Set the correct MTU to use. */
! static int do_mtu(argc, argv)
  int argc;
  char *argv[];
  {
!   if (argc != 2) {
! 	fprintf(stderr, "Usage: mtu number\n");
  	return(-1);
    }
!   mydip.mtu = atoi(argv[1]);
!   if (opt_v == 1) printf("MTU set to %d\n", mydip.mtu);
  
    return(0);
  }
  
--- 679,697 ----
  }
  
  
! /* Set routing as default */
! static int do_default(argc, argv)
  int argc;
  char *argv[];
  {
!   if (argc != 1) {
! 	fprintf(stderr, "Usage: default\n");
  	return(-1);
    }
! 
!   if (opt_v == 1) printf("Destination net/address set to 'default'\n");
  
+   route_default = 1;
    return(0);
  }
  
diff -c ifconfig_old/dip/dip.8 ifconfig/dip/dip.8
*** ifconfig_old/dip/dip.8	Tue Jun  8 08:57:41 1993
--- ifconfig/dip/dip.8	Wed Jun 30 04:15:37 1993
***************
*** 56,65 ****
  .nf
  DIP knows about the following commands:
  
! 	dial     goto     help     if       local    
! 	mode     mtu      print    port     remote   
! 	reset    send     sleep    speed    term     
! 	wait     
  
  DIP> _
  .sp 1
--- 56,64 ----
  .nf
  DIP knows about the following commands:
  
! 	default  dial     get      goto     help           
! 	if       mode     print    port     reset
! 	send     sleep    speed    term     wait
  
  DIP> _
  .sp 1
***************
*** 211,221 ****
  main:
    # First of all, set up our name for this connection.
    # I am called "uwalt.hacktic.nl"  (== 193.78.33.238)
!   local uwalt.hacktic.nl
  
    # Next, set up the other side's name and address.
    # My dialin machine is called 'xs4all.hacktic.nl' (== 193.78.33.42)
!   remote xs4all.hacktic.nl
  
    # Set the desired serial port and speed.
    port cua0
--- 210,220 ----
  main:
    # First of all, set up our name for this connection.
    # I am called "uwalt.hacktic.nl"  (== 193.78.33.238)
!   get $local uwalt.hacktic.nl
  
    # Next, set up the other side's name and address.
    # My dialin machine is called 'xs4all.hacktic.nl' (== 193.78.33.42)
!   get $remote xs4all.hacktic.nl
  
    # Set the desired serial port and speed.
    port cua0
***************
*** 254,264 ****
    wait SOME-STRING 15
  
    # Set up the SLIP operating parameters.
!   mtu 1500
  
    # Say hello and fire up!
  done:
!   print CONNECTED to $host with address $ip
    mode SLIP
    goto exit
  error:
--- 253,268 ----
    wait SOME-STRING 15
  
    # Set up the SLIP operating parameters.
!   get $mtu 1500
  
+   # Set Destination net/address as type 'default' (vice an address).
+   # This is used by the 'route' command to set the kernel routing table.
+   # Some machines seem to require this be done for SLIP to work properly.
+   default
+ 
    # Say hello and fire up!
  done:
!   print CONNECTED to $remote with address $locip
    mode SLIP
    goto exit
  error:
diff -c ifconfig_old/dip/dip.c ifconfig/dip/dip.c
*** ifconfig_old/dip/dip.c	Tue Jun  8 08:52:54 1993
--- ifconfig/dip/dip.c	Wed Jun 30 02:50:32 1993
***************
*** 23,32 ****
  #include "dip.h"
  
  
! #define VERSION	"3.2.2"
  
  
! char *Version = "@(#) dip 3.2.2 (06/08/93)";
  
  
  struct protosw protosw[] = {
--- 23,32 ----
  #include "dip.h"
  
  
! #define VERSION	"3.2.2a"
  
  
! char *Version = "@(#) dip 3.2.2a (06/08/93)";
  
  
  struct protosw protosw[] = {
***************
*** 113,118 ****
--- 113,119 ----
    opt_t = 0;
    opt_v = 0;
    opt_i = 0;
+   route_default = 0;
  
    /* Scan command line for any arguments. */
    opterr = 0;
diff -c ifconfig_old/dip/dip.h ifconfig/dip/dip.h
*** ifconfig_old/dip/dip.h	Mon May 31 10:33:43 1993
--- ifconfig/dip/dip.h	Wed Jun 30 01:12:02 1993
***************
*** 112,117 ****
--- 112,118 ----
  #ifndef GLOBAL
  #   define GLOBAL	extern
  #endif
+ GLOBAL int	route_default;		/* flag: set route as default	*/
  GLOBAL int	opt_i;			/* flag: incoming connection	*/
  GLOBAL int	opt_t;			/* flag: dump incoming IP packs */
  GLOBAL int	opt_v;			/* flag: be verbose!		*/
diff -c ifconfig_old/dip/sample.dip ifconfig/dip/sample.dip
*** ifconfig_old/dip/sample.dip	Fri May 28 13:03:05 1993
--- ifconfig/dip/sample.dip	Wed Jun 30 04:20:02 1993
***************
*** 5,15 ****
  main:
    # First of all, set up our name for this connection.
    # I am called "uwalt.hacktic.nl"  (== 193.78.33.238)
!   local uwalt.hacktic.nl
  
    # Next, set up the other side's name and address.
    # My dialin machine is called 'xs4all.hacktic.nl' (== 193.78.33.42)
!   remote xs4all.hacktic.nl
  
    # Set the desired serial port and speed.
    port cua0
--- 5,15 ----
  main:
    # First of all, set up our name for this connection.
    # I am called "uwalt.hacktic.nl"  (== 193.78.33.238)
!   get $local uwalt.hacktic.nl
  
    # Next, set up the other side's name and address.
    # My dialin machine is called 'xs4all.hacktic.nl' (== 193.78.33.42)
!   get $remote xs4all.hacktic.nl
  
    # Set the desired serial port and speed.
    port cua0
***************
*** 50,58 ****
    # Set up the SLIP operating parameters.
    mtu 1500
  
    # Say hello and fire up!
  done:
!   print CONNECTED to $host with address $ip
    mode SLIP
    goto exit
  error:
--- 50,63 ----
    # Set up the SLIP operating parameters.
    mtu 1500
  
+   # Set Destination net/address as type 'default' (vice an address).
+   # This is used by the 'route' command to set the kernel routing table.
+   # Some machines seem to require this be done for SLIP to work properly.
+   default
+ 
    # Say hello and fire up!
  done:
!   print CONNECTED to $remote with address $locip
    mode SLIP
    goto exit
  error:
diff -c ifconfig_old/dip/serial.c ifconfig/dip/serial.c
*** ifconfig_old/dip/serial.c	Tue May 25 12:39:39 1993
--- ifconfig/dip/serial.c	Wed Jun 30 00:42:45 1993
***************
*** 243,249 ****
  	return(-errno);
    }
    if ((baud = set_baud(speed)) < 0) return(baud);
!   tty.c_cflag |= ((tty.c_cflag & ~CBAUD) | baud);
    if (ioctl(tty_fd, TCSETS, &tty) < 0) {
  	fprintf(stderr, "dip: cannot ioctl(%d, SETS): %d\n", tty_fd, errno);
  	return(-errno);
--- 243,249 ----
  	return(-errno);
    }
    if ((baud = set_baud(speed)) < 0) return(baud);
!   tty.c_cflag = ((tty.c_cflag & ~CBAUD) | baud);
    if (ioctl(tty_fd, TCSETS, &tty) < 0) {
  	fprintf(stderr, "dip: cannot ioctl(%d, SETS): %d\n", tty_fd, errno);
  	return(-errno);
++++++++++ CUT HERE ++++++++++
-- 
Jeff Uphoff -- "Uppie"     |  "The secret to good teaching is sincerity.  As
uphoff@astro.psu.edu       |  soon as you learn to fake that, you've got it
juphoff@nrao.edu           |  made."

--
Send submissions for comp.os.linux.announce to: linux-announce@tc.cornell.edu
