I have done this in a different way, namely by 'filtering' the variables
that are passed to /sbin/dhclient-script by using the
'script "/path/to/my/script"' option to run my own script, act on variables
I care about (dns and default gateway) and then calling /sbin/dhclient-script
in the event it still has something to do.

Honestly I think your approach is cleaner, and more likely to survive the
ever eminent promise from krw@ to remove the script entirely.

Thanks,

Penned by Stefan Sperling on 20110816  5:08.37, we have:
| In some networks (e.g. at public events using open wifi) I want
| traffic not destined for the local network to go through a VPN.
| 
| If the local network uses DHCP, I usually end up killing dhclient
| because it's impossible to renew the lease without changing the
| default route.
| 
| To be clear, I end up with a command sequence like:
| 
|  dhclient wpi0  # get a local address
|  netstat -rn -finet | grep ^default  # figure out local router
|  route delete default # don't use local router for everything
|  route add -host $VPN_SERVER_IP $LOCAL_ROUTER # just for this host
|  openvpn config-file # start VPN, i am too dumb for ipsec
|  route add default $ROUTER_BEHIND_VPN # use my trusted router as default
|  pkill -x dhclient # kill dhclient to avoid default route change later
| 
| The problem is that the lease expires at some point and things
| usually stop working until I perform the same tedious configuration
| dance again.
| 
| The patch below adds a new option to dhclient.conf (the VPN server is
| at 10.1.1.1 in this example):
| 
|   interface "wpi0" {
|           host-route 10.1.1.1;
|   }
| 
| Instead of adding a default route dhclient will add a host route
| to the specified address. So the above sequence becomes:
| 
|  dhclient wpi0  # get a local address, add route to VPN server
|  openvpn config-file # start VPN
|  route add default $ROUTER_BEHIND_VPN # use my trusted router as default
| 
| And the configuration remains stable.
| 
| Is this a good approach?
| Does anyone else think this is useful?
| 
| 
| Index: clparse.c
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/clparse.c,v
| retrieving revision 1.37
| diff -u -p -r1.37 clparse.c
| --- clparse.c 4 Apr 2011 11:14:52 -0000       1.37
| +++ clparse.c 12 Aug 2011 18:04:02 -0000
| @@ -151,7 +151,8 @@ read_client_leases(void)
|   *   interface-declaration |
|   *   TOK_LEASE client-lease-statement |
|   *   TOK_ALIAS client-lease-statement |
| - *   TOK_REJECT reject-statement
| + *   TOK_REJECT reject-statement |
| + *   TOK_HOST_ROUTE host-route-statement
|   */
|  void
|  parse_client_statement(FILE *cfile)
| @@ -234,6 +235,9 @@ parse_client_statement(FILE *cfile)
|       case TOK_REJECT:
|               parse_reject_statement(cfile);
|               return;
| +     case TOK_HOST_ROUTE:
| +             parse_host_route_statement(cfile);
| +             return;
|       default:
|               parse_warn("expecting a statement.");
|               skip_to_semi(cfile);
| @@ -739,6 +743,25 @@ parse_reject_statement(FILE *cfile)
|               token = next_token(&val, cfile);
|       } while (token == ',');
|  
| +     if (token != ';') {
| +             parse_warn("expecting semicolon.");
| +             skip_to_semi(cfile);
| +     }
| +}
| +
| +void
| +parse_host_route_statement(FILE *cfile)
| +{
| +     char *val;
| +     int token;
| +
| +     if (!parse_ip_addr(cfile, &config->host_route)) {
| +             parse_warn("expecting IP address.");
| +             skip_to_semi(cfile);
| +             return;
| +     }
| +
| +     token = next_token(&val, cfile);
|       if (token != ';') {
|               parse_warn("expecting semicolon.");
|               skip_to_semi(cfile);
| Index: conflex.c
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/conflex.c,v
| retrieving revision 1.13
| diff -u -p -r1.13 conflex.c
| --- conflex.c 17 Dec 2006 17:41:56 -0000      1.13
| +++ conflex.c 12 Aug 2011 18:00:51 -0000
| @@ -324,6 +324,7 @@ static const struct keywords {
|       { "filename",                           TOK_FILENAME },
|       { "fixed-address",                      TOK_FIXED_ADDR },
|       { "hardware",                           TOK_HARDWARE },
| +     { "host-route",                         TOK_HOST_ROUTE },
|       { "initial-interval",                   TOK_INITIAL_INTERVAL },
|       { "interface",                          TOK_INTERFACE },
|       { "lease",                              TOK_LEASE },
| Index: dhclient-script
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhclient-script,v
| retrieving revision 1.22
| diff -u -p -r1.22 dhclient-script
| --- dhclient-script   9 Apr 2011 19:53:00 -0000       1.22
| +++ dhclient-script   12 Aug 2011 18:06:00 -0000
| @@ -60,11 +60,16 @@ delete_old_routes() {
|  add_new_routes() {
|       route -q $rdomain -n flush -inet -iface $interface
|       for router in $new_routers; do
| -             if [ "$new_ip_address" = "$router" ]; then
| -                     route -q $rdomain add default -iface $router
| +             if [ -n "$host_route" -a "$host_route" != "0.0.0.0" ]; then
| +                     new_route="-host $host_route $router"
|               else
| -                     route -q $rdomain add default $router
| +                     if [ "$new_ip_address" = "$router" ]; then
| +                             new_route="default -iface $router"
| +                     else
| +                             new_route="default $router"
| +                     fi
|               fi
| +             route -q $rdomain add $new_route
|               # 2nd and subsequent default routers error out, so explicitly
|               # stop processing the list after the first one.
|               break
| Index: dhclient.c
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
| retrieving revision 1.141
| diff -u -p -r1.141 dhclient.c
| --- dhclient.c        11 May 2011 14:38:36 -0000      1.141
| +++ dhclient.c        12 Aug 2011 18:06:57 -0000
| @@ -1604,6 +1604,9 @@ supersede:
|       }
|       snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
|       script_set_env(prefix, "expiry", tbuf);
| +
| +     if (config->host_route.len)
| +             script_set_env("", "host_route", piaddr(config->host_route));
|  }
|  
|  void
| Index: dhclient.conf.5
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhclient.conf.5,v
| retrieving revision 1.21
| diff -u -p -r1.21 dhclient.conf.5
| --- dhclient.conf.5   9 Apr 2011 19:53:00 -0000       1.21
| +++ dhclient.conf.5   13 Aug 2011 19:18:56 -0000
| @@ -430,6 +430,13 @@ If no lease is acquired, the script is u
|  any, and also called once if no valid lease can be identified.
|  For more information, see
|  .Xr dhclient.leases 5 .
| +.It Ic host-route Ar ip-address ;
| +The
| +.Ic host-route
| +statement causes the DHCP client to install a host route to the specified
| +IP address instead of installing a default route.
| +This is useful if the default route points to a VPN tunnel terminated
| +at the specified IP address instead of a router on the local network.
|  .El
|  .Sh EXAMPLES
|  The following configuration file is used on a laptop
| Index: dhcpd.h
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v
| retrieving revision 1.73
| diff -u -p -r1.73 dhcpd.h
| --- dhcpd.h   11 May 2011 14:38:36 -0000      1.73
| +++ dhcpd.h   12 Aug 2011 18:03:23 -0000
| @@ -150,6 +150,7 @@ struct client_config {
|       enum { IGNORE, ACCEPT, PREFER }
|                                bootp_policy;
|       struct iaddrlist        *reject_list;
| +     struct iaddr             host_route;
|  };
|  
|  struct client_state {
| @@ -344,3 +345,4 @@ void parse_client_lease_declaration(FILE
|  int parse_option_decl(FILE *, struct option_data *);
|  void parse_string_list(FILE *, struct string_list **, int);
|  void parse_reject_statement(FILE *);
| +void parse_host_route_statement(FILE *);
| Index: dhctoken.h
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhctoken.h,v
| retrieving revision 1.5
| diff -u -p -r1.5 dhctoken.h
| --- dhctoken.h        15 May 2006 08:10:57 -0000      1.5
| +++ dhctoken.h        12 Aug 2011 18:03:38 -0000
| @@ -79,6 +79,7 @@
|  #define TOK_REJECT           292
|  #define TOK_FDDI             293
|  #define TOK_LINK_TIMEOUT     294
| +#define TOK_HOST_ROUTE               295
|  
|  #define is_identifier(x)     ((x) >= TOK_FIRST_TOKEN &&      \
|                                (x) != TOK_STRING &&   \

-- 
Todd Fries .. t...@fries.net

 _____________________________________________
|                                             \  1.636.410.0632 (voice)
| Free Daemon Consulting, LLC                 \  1.405.227.9094 (voice)
| http://FreeDaemonConsulting.com             \  1.866.792.3418 (FAX)
| 2525 NW Expy #525, Oklahoma City, OK 73112  \  sip:freedae...@ekiga.net
| "..in support of free software solutions."  \  sip:4052279...@ekiga.net
 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                                                 
              37E7 D3EB 74D0 8D66 A68D  B866 0326 204E 3F42 004A
                        http://todd.fries.net/pgp.txt

Reply via email to