* Stefan Siegl <[EMAIL PROTECTED]> [Oct 15 2007 23:57] wrote:
> > The whitespaces beetween -a and the ip are missing because -a, -g, -m,
> > -p, -A, -G have only optional arguments. If the argument is no passed
> > the value will be unset e.g. the gateway.
> 
> I'm afraid, but I don't think that's a good idea.  People are used to
> passing `-a 192.168.7.5' or similar and the provided IP addresses can be
> distinguished quite easily.
> 
> If a user provides the afore mentioned option, parse_opt is called with
> key == `a' and arg == NULL.  However ``state->argv[state->next]''
> provides a pointer to the IP address which should be examined in turn.
> Unless you consider the bit another option, i.e. you cannot consume it
> as some IP address, simply increment state->next.

now '-a 192.168.100.1' '-a192.168.100.1' '-a' are possible
so i didn't have to touch /etc/dhclient-script at all

> >  if [ x$reason = xPREINIT ]; then
> > -  settrans -afg /servers/socket/2 /hurd/pfinet --dhcp -i $interface
> >    exit_with_hooks 0
> >  fi
> 
> I'm unsure concerning this, but I think you should check whether there
> is some pfinet installed and set it in case not.

At this point the settrans call will never be called, when there is no
pfinet running. There will be the error 'Can't create addrlist socket'.

> > +  {"dhcp", 'd', 0        , 0, "Prepare pfinet for dhcp"},
> I don't think you should introduce the `--dhcp' option after all.

Removed.
 
> > +    /* Look for IPv6 default route (we use the first ifa->addr as
> > +       source address), but don't yet push it to the option stack. */
> 
> This comment doesn't fit here, at least not the latter part of the
> sentence.

Yep, that's right. ( Memo to myself: Copy and paste is evil)

> Last but not least I'd like to ask you to review your patch regarding
> whitespace changes.  There are quite a few hunks in it, resulting from
> those.  Especially there were no changes to timer-emul.c at all, apart
> from whitespace ones.

I hope it is a little bit better now.

> Thanks for your work, you know that lease-renew'ing dhcp-support has
> often been asked for.  And of course welcome on board :-)

Oh Captaion, my captain.

regards,
  didi

-- 
MSCHEISS:
  MicroSoft Certified Home Engineer for Intranet System Solutions
? cscope.out
? dhcp.patch
Index: ChangeLog
===================================================================
RCS file: /sources/hurd/hurd/pfinet/ChangeLog,v
retrieving revision 1.86
diff -p -u -r1.86 ChangeLog
--- ChangeLog	14 Oct 2007 02:26:10 -0000	1.86
+++ ChangeLog	22 Oct 2007 20:49:01 -0000
@@ -1,3 +1,28 @@
+2007-10-14  Christian Dietrich  <[EMAIL PROTECTED]>
+	* options.c (options): Marked -a, -g -m, -p, -A, -G
+	OPTION_ARG_OPTIONAL. Adding -d option.
+	(parse_interface_copy_device): New function.
+	(parse_opt): When selecting another interface with -i 
+	set the options from e.g. a prior fsysopts call as default
+	values. For -a, -g, -p, -g, -A, -G set the optional 
+	argument as value. When there is no argument, delete the
+	value (e.g. unset default gateway). Delete delete default gateways
+	only if the set gateway is on an interface modified in this call.
+	Add always an route for dhcp packages on all devices. By doing
+	this we can send dhcp renew packages.
+	(trivfs_append_args): Add --gateway only once.
+
+2007-10-14  Marco Gerards  <[EMAIL PROTECTED]>
+	* options.c (options): Add the option `dhcp'.
+	(parse_hook_add_interface): Initialize the `dhcp' member for the
+	parse hook.
+	(parse_opt): In case pfinet is started with the argument `--dhcp',
+	set the address to `0.0.0.0', the netmask to `255.0.0.0' and add
+	the route for `0.0.0.0' so broadcasting works.
+
+	* linux-src/net/ipv4/devinet.c (inet_insert_ifa) [_HURD_]: Don't
+	fail when the address is `0.0.0.0'.
+      
 2007-10-14  Stefan Siegl  <[EMAIL PROTECTED]>
 
 	* options.c (ipv6_get_dflt_router) [CONFIG_IPV6]: New function.
Index: options.c
===================================================================
RCS file: /sources/hurd/hurd/pfinet/options.c,v
retrieving revision 1.14
diff -p -u -r1.14 options.c
--- options.c	14 Oct 2007 02:26:10 -0000	1.14
+++ options.c	22 Oct 2007 20:49:02 -0000
@@ -60,23 +60,27 @@ extern struct inet6_dev *ipv6_find_idev 
 extern int inet6_addr_add (int ifindex, struct in6_addr *pfx, int plen);
 extern int inet6_addr_del (int ifindex, struct in6_addr *pfx, int plen);
 
+#ifdef CONFIG_IPV6
+static struct rt6_info * ipv6_get_dflt_router (void);
+#endif
+
 
 /* Pfinet options.  Used for both startup and runtime.  */
 static const struct argp_option options[] =
 {
-  {"interface", 'i', "DEVICE",  0,  "Network interface to use", 1},
+  {"interface", 'i', "DEVICE",   0,  "Network interface to use", 1},
   {0,0,0,0,"These apply to a given interface:", 2},
-  {"address",   'a', "ADDRESS", 0, "Set the network address"},
-  {"netmask",   'm', "MASK",    0, "Set the netmask"},
-  {"peer",      'p', "ADDRESS", 0, "Set the peer address"},
-  {"gateway",   'g', "ADDRESS", 0, "Set the default gateway"},
-  {"ipv4",      '4', "NAME",    0, "Put active IPv4 translator on NAME"},
+  {"address",   'a', "ADDRESS",  OPTION_ARG_OPTIONAL, "Set the network address"},
+  {"netmask",   'm', "MASK",     OPTION_ARG_OPTIONAL, "Set the netmask"},
+  {"peer",      'p', "ADDRESS",  OPTION_ARG_OPTIONAL, "Set the peer address"},
+  {"gateway",   'g', "ADDRESS",  OPTION_ARG_OPTIONAL, "Set the default gateway"},
+  {"ipv4",      '4', "NAME",     0, "Put active IPv4 translator on NAME"},
 #ifdef CONFIG_IPV6  
-  {"ipv6",      '6', "NAME",    0, "Put active IPv6 translator on NAME"},
-  {"address6",  'A', "ADDR/LEN",0, "Set the global IPv6 address"},
-  {"gateway6",  'G', "ADDRESS", 0, "Set the IPv6 default gateway"},
+  {"ipv6",      '6', "NAME",     0, "Put active IPv6 translator on NAME"},
+  {"address6",  'A', "ADDR/LEN", OPTION_ARG_OPTIONAL, "Set the global IPv6 address"},
+  {"gateway6",  'G', "ADDRESS",  OPTION_ARG_OPTIONAL, "Set the IPv6 default gateway"},
 #endif
-  {"shutdown",  's', 0,         0, "Shut it down"},
+  {"shutdown",  's', 0,          0, "Shut it down"},
   {0}
 };
 
@@ -112,6 +116,50 @@ struct parse_hook
   struct parse_interface *curint;
 };
 
+static void
+parse_interface_copy_device(struct device *src,
+                            struct parse_interface *dst)
+{
+  uint32_t broad;
+  struct rt_key key = { 0 };
+  struct inet6_dev *idev = NULL;
+  struct fib_result res;
+
+  inquire_device (src, &dst->address, &dst->netmask, 
+                  &dst->peer, &broad);
+  /* Get gateway */
+  dst->gateway = INADDR_NONE;
+  key.oif = src->ifindex;
+  if (! main_table->tb_lookup (main_table, &key, &res)
+      && FIB_RES_GW(res) != INADDR_ANY)
+    dst->gateway = FIB_RES_GW (res);
+#ifdef CONFIG_IPV6
+  if (trivfs_protid_portclasses[PORTCLASS_INET6] != MACH_PORT_NULL)
+    idev = ipv6_find_idev(src);
+
+  if (idev)
+  {
+    struct inet6_ifaddr *ifa = idev->addr_list;
+    
+    /* Look for IPv6 default router and add it to the interface,
+     * if it belongs to it.
+     */
+    struct rt6_info *rt6i = ipv6_get_dflt_router();
+    if(rt6i->rt6i_dev == src) 
+      memcpy(&dst->gateway6, &rt6i->rt6i_gateway, sizeof(struct in6_addr));
+    /* Search for global address and set it in dst */
+    do 
+    {
+      if(!IN6_IS_ADDR_LINKLOCAL(&ifa->addr)) {
+        memcpy(&dst->address6, ifa, sizeof(struct inet6_ifaddr));
+        break;
+      }
+    }
+    while ((ifa = ifa->if_next));
+  }
+#endif
+}
+
 /* Adds an empty interface slot to H, and sets H's current interface to it, or
    returns an error. */
 static error_t
@@ -185,8 +233,7 @@ parse_opt (int opt, char *arg, struct ar
 
   switch (opt)
     {
-      struct parse_interface *in;
-      uint32_t gateway;
+      struct parse_interface *in, *gw4_in;
 #ifdef CONFIG_IPV6
       struct parse_interface *gw6_in;
       char *ptr;
@@ -216,31 +263,64 @@ parse_opt (int opt, char *arg, struct ar
 	err = find_device (arg, &in->device);
       if (err)
 	FAIL (err, 10, err, "%s", arg);
-
+      /* Set old interface values */
+      parse_interface_copy_device(in->device, in);
       break;
 
     case 'a':
-      h->curint->address = ADDR (arg, "address");
-      if (!IN_CLASSA (ntohl (h->curint->address))
-	  && !IN_CLASSB (ntohl (h->curint->address))
-	  && !IN_CLASSC (ntohl (h->curint->address)))
-	{
-	  if (IN_MULTICAST (ntohl (h->curint->address)))
-	    FAIL (EINVAL, 1, 0,
-		  "%s: Cannot set interface address to multicast address",
-		  arg);
-	  else
-	    FAIL (EINVAL, 1, 0,
-		  "%s: Illegal or undefined network address", arg);
-	}
+      if (arg || ((state->next < state->argc) 
+                  && (*state->argv[state->next] != '-') 
+                  ? (arg = state->argv[state->next++]) : 0))
+      {
+        h->curint->address = ADDR (arg, "address");
+        if (!IN_CLASSA (ntohl (h->curint->address))
+            && !IN_CLASSB (ntohl (h->curint->address))
+            && !IN_CLASSC (ntohl (h->curint->address)))
+          {
+            if (IN_MULTICAST (ntohl (h->curint->address)))
+              FAIL (EINVAL, 1, 0,
+                    "%s: Cannot set interface address to multicast address",
+                    arg);
+            else
+              FAIL (EINVAL, 1, 0,
+                    "%s: Illegal or undefined network address", arg);
+          }
+      } else { 
+        h->curint->address = ADDR ("0.0.0.0", "address");
+        h->curint->netmask = ADDR ("255.0.0.0", "netmask");
+        h->curint->gateway = INADDR_NONE;
+      }
       break;
     case 'm':
-      h->curint->netmask = ADDR (arg, "netmask"); break;
+      if (arg || ((state->next < state->argc) 
+                  && (*state->argv[state->next] != '-') 
+                  ? (arg = state->argv[state->next++]) : 0))
+        h->curint->netmask = ADDR (arg, "netmask"); 
+      else 
+        h->curint->netmask = INADDR_NONE;
+      break;
     case 'p':
-      h->curint->peer = ADDR (arg, "peer"); break;
+      if (arg || ((state->next < state->argc) 
+                  && (*state->argv[state->next] != '-') 
+                  ? (arg = state->argv[state->next++]) : 0))
+        h->curint->peer = ADDR (arg, "peer"); 
+      else 
+        h->curint->peer = INADDR_NONE;
+      break;
     case 'g':
-      h->curint->gateway = ADDR (arg, "gateway"); break;
-
+      if (arg || ((state->next < state->argc) 
+                  && (*state->argv[state->next] != '-') 
+                  ? (arg = state->argv[state->next++]) : 0))
+      {
+        /* Remove an possible other default gateway */ 
+        for (in = h->interfaces; in < h->interfaces + h->num_interfaces; 
+             in++)
+          in->gateway = INADDR_NONE;
+        h->curint->gateway = ADDR (arg, "gateway");
+      }
+      else 
+        h->curint->gateway = INADDR_NONE;
+      break;
     case '4':
       pfinet_bind (PORTCLASS_INET, arg);
 
@@ -254,36 +334,48 @@ parse_opt (int opt, char *arg, struct ar
       break;
 
     case 'A':
-      if ((ptr = strchr (arg, '/'))) 
-	{
-	  h->curint->address6.prefix_len = atoi (ptr + 1);
-	  if (h->curint->address6.prefix_len > 128) 
-	    FAIL (EINVAL, 1, 0, "%s: The prefix-length is invalid", arg);
-
-	  *ptr = 0;
-	}
-      else
-	{
-	  h->curint->address6.prefix_len = 64;
-	  fprintf (stderr, "No prefix-length given, defaulting to %s/64.\n",
-		   arg);
-	}
-
-      if (inet_pton (AF_INET6, arg, &h->curint->address6.addr) <= 0)
-	PERR (EINVAL, "Malformed address");
-
-      if (IN6_IS_ADDR_MULTICAST (&h->curint->address6.addr))
-	FAIL (EINVAL, 1, 0, "%s: Cannot set interface address to "
-	      "multicast address", arg);
+      if (arg || ((state->next < state->argc) 
+                  && (*state->argv[state->next] != '-') 
+                  ? (arg = state->argv[state->next++]) : 0))
+      {
+        if ((ptr = strchr (arg, '/'))) 
+          {
+            h->curint->address6.prefix_len = atoi (ptr + 1);
+            if (h->curint->address6.prefix_len > 128) 
+              FAIL (EINVAL, 1, 0, "%s: The prefix-length is invalid", arg);
+
+            *ptr = 0;
+          }
+        else
+          {
+            h->curint->address6.prefix_len = 64;
+            fprintf (stderr, "No prefix-length given, defaulting to %s/64.\n",
+                     arg);
+          }
+
+        if (inet_pton (AF_INET6, arg, &h->curint->address6.addr) <= 0)
+          PERR (EINVAL, "Malformed address");
+
+        if (IN6_IS_ADDR_MULTICAST (&h->curint->address6.addr))
+          FAIL (EINVAL, 1, 0, "%s: Cannot set interface address to "
+                "multicast address", arg);
+      } else
+        memset (&h->curint->address6, 0, sizeof (struct inet6_ifaddr));
       break;
 
     case 'G':
-      if (inet_pton (AF_INET6, arg, &h->curint->gateway6) <= 0)
-	PERR (EINVAL, "Malformed gateway");
+      if (arg || ((state->next < state->argc) 
+                  && (*state->argv[state->next] != '-') 
+                  ? (arg = state->argv[state->next++]) : 0))
+      {
+        if (inet_pton (AF_INET6, arg, &h->curint->gateway6) <= 0)
+          PERR (EINVAL, "Malformed gateway");
 
-      if (IN6_IS_ADDR_MULTICAST (&h->curint->gateway6))
-	FAIL (EINVAL, 1, 0, "%s: Cannot set gateway to "
-	      "multicast address", arg);
+        if (IN6_IS_ADDR_MULTICAST (&h->curint->gateway6))
+          FAIL (EINVAL, 1, 0, "%s: Cannot set gateway to "
+                "multicast address", arg);
+      } else
+        memset (&h->curint->gateway6, 0, sizeof (struct in6_addr));
       break;
 #endif /* CONFIG_IPV6 */
 
@@ -323,20 +415,19 @@ parse_opt (int opt, char *arg, struct ar
 	  /* Specifying a netmask for an address-less interface is a no-no.  */
 	  FAIL (EDESTADDRREQ, 14, 0, "Cannot set netmask");
 #endif
-
-      gateway = INADDR_NONE;
 #ifdef CONFIG_IPV6
       gw6_in = NULL;
 #endif
+      gw4_in = NULL;
       for (in = h->interfaces; in < h->interfaces + h->num_interfaces; in++)
 	{
+          /* delete interface if it doesn't match the actual netmask */
+          if (! ( (h->curint->address & h->curint->netmask) 
+                  == (h->curint->gateway & h->curint->netmask))) 
+            h->curint->gateway = INADDR_NONE;
+
 	  if (in->gateway != INADDR_NONE)
-	    {
-	      if (gateway != INADDR_NONE)
-		FAIL (err, 15, 0, "Cannot have multiple default gateways");
-	      gateway = in->gateway;
-	      in->gateway = INADDR_NONE;
-	    }
+              gw4_in = in;
 
 #ifdef CONFIG_IPV6
 	  if (!IN6_IS_ADDR_UNSPECIFIED (&in->gateway6))
@@ -377,24 +468,24 @@ parse_opt (int opt, char *arg, struct ar
 	    continue;
 
 	  /* First let's remove all non-local addresses. */
-	  struct inet6_ifaddr *ifa = idev->addr_list;
-
-	  while (ifa)
-	    {
-	      struct inet6_ifaddr *c_ifa = ifa;
-	      ifa = ifa->if_next;
-
-	      if (IN6_ARE_ADDR_EQUAL (&c_ifa->addr, &in->address6.addr))
-		memset (&in->address6, 0, sizeof (struct inet6_ifaddr));
-
-	      else if (!IN6_IS_ADDR_LINKLOCAL (&c_ifa->addr)
-		       && !IN6_IS_ADDR_SITELOCAL (&c_ifa->addr))
-		inet6_addr_del (in->device->ifindex, &c_ifa->addr,
-				c_ifa->prefix_len);
-	    }
-
-	  if (!IN6_IS_ADDR_UNSPECIFIED (&in->address6.addr))
-	    {
+ 	  struct inet6_ifaddr *ifa = idev->addr_list;
+ 
+ 	  while (ifa)
+  	    {
+ 	      struct inet6_ifaddr *c_ifa = ifa;
+ 	      ifa = ifa->if_next;
+ 
+ 	      if (IN6_ARE_ADDR_EQUAL (&c_ifa->addr, &in->address6.addr))
+ 		memset (&in->address6, 0, sizeof (struct inet6_ifaddr));
+  
+ 	      else if (!IN6_IS_ADDR_LINKLOCAL (&c_ifa->addr)
+ 		       && !IN6_IS_ADDR_SITELOCAL (&c_ifa->addr))
+ 		inet6_addr_del (in->device->ifindex, &c_ifa->addr,
+ 				c_ifa->prefix_len);
+ 	    }
+ 
+ 	  if (!IN6_IS_ADDR_UNSPECIFIED (&in->address6.addr))
+ 	    {
 	      /* Now assign the new address */
 	      inet6_addr_add (in->device->ifindex, &in->address6.addr,
 			      in->address6.prefix_len);
@@ -418,33 +509,40 @@ parse_opt (int opt, char *arg, struct ar
 	req.nlh.nlmsg_seq = 0;
 	req.nlh.nlmsg_len = NLMSG_LENGTH (sizeof req.rtm);
 
-	bzero (&req.rtm, sizeof req.rtm);
-	bzero (&rta, sizeof rta);
+	memset (&req.rtm, 0, sizeof req.rtm);
+	memset (&rta, 0, sizeof rta);
 	req.rtm.rtm_scope = RT_SCOPE_UNIVERSE;
 	req.rtm.rtm_type = RTN_UNICAST;
 	req.rtm.rtm_protocol = RTPROT_STATIC;
-	rta.rta_gw = &gateway;
 
-	if (gateway == INADDR_NONE)
+	if (!gw4_in)
 	  {
-	    /* Delete any existing default route.  */
-	    req.nlh.nlmsg_type = RTM_DELROUTE;
-	    req.nlh.nlmsg_flags = 0;
-	    tb = fib_get_table (req.rtm.rtm_table);
-	    if (tb)
-	      {
-		err = - (*tb->tb_delete) (tb, &req.rtm, &rta, &req.nlh, 0);
-		if (err && err != ESRCH)
-		  {
-		    __mutex_unlock (&global_lock);
-		    FAIL (err, 17, 0, "cannot remove old default gateway");
-		  }
-		err = 0;
-	      }
+	    /* Delete any existing default route on configured devices  */
+            for (in = h->interfaces; in < h->interfaces + h->num_interfaces;
+                 in++) {
+              req.nlh.nlmsg_type = RTM_DELROUTE;
+              req.nlh.nlmsg_flags = 0;
+              rta.rta_oif = &in->device->ifindex;
+              tb = fib_get_table (req.rtm.rtm_table);
+              if (tb)
+                {
+                  err = - (*tb->tb_delete) 
+                    (tb, &req.rtm, &rta, &req.nlh, 0);
+                  if (err && err != ESRCH)
+                    {
+                      __mutex_unlock (&global_lock);
+                      FAIL (err, 17, 0, 
+                            "cannot remove old default gateway");
+                    }
+                  err = 0;
+                }
+            }
 	  }
 	else
 	  {
 	    /* Add a default route, replacing any existing one.  */
+            rta.rta_oif = &gw4_in->device->ifindex;
+            rta.rta_gw = &gw4_in->gateway;
 	    req.nlh.nlmsg_type = RTM_NEWROUTE;
 	    req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE;
 	    tb = fib_new_table (req.rtm.rtm_table);
@@ -467,13 +565,73 @@ parse_opt (int opt, char *arg, struct ar
 	  if (!gw6_in || rt6i->rt6i_dev != gw6_in->device
 	      || !IN6_ARE_ADDR_EQUAL (&rt6i->rt6i_gateway, &gw6_in->gateway6))
 	    {
-	      rt6_purge_dflt_routers (0);
+              /* Delete any existing default route on configured devices  */
+              for (in = h->interfaces; in < h->interfaces 
+                   + h->num_interfaces; in++) 
+                if (rt6i->rt6i_dev == in->device || gw6_in )
+                  rt6_purge_dflt_routers (0);
+
 	      if (gw6_in)
 		rt6_add_dflt_router (&gw6_in->gateway6, gw6_in->device);
 	    }
 	}
 #endif       
 
+      /*  Setup the routing required for DHCP. */
+      for (in = h->interfaces; in < h->interfaces + h->num_interfaces; in++)
+      {
+        struct kern_rta rta;
+        struct
+        {
+          struct nlmsghdr nlh;
+          struct rtmsg rtm;
+        } req;
+        struct fib_table *tb;
+        struct rtentry route;
+        struct sockaddr_in *dst;
+        struct device *dev;
+
+        dst = (struct sockaddr_in *) &route.rt_dst;
+        if (!in->device->name) 
+        {
+          __mutex_unlock (&global_lock);
+          FAIL (ENODEV, 17, 0, "unknown device");
+        }
+        dev = dev_get (in->device->name);
+        if (!dev)
+        {
+          __mutex_unlock (&global_lock);
+          FAIL (ENODEV, 17, 0, "unknown device");
+        }
+
+        /* Simulate the SIOCADDRT behavior.  */
+        memset (&route, 0, sizeof (struct rtentry));
+        memset (&req.rtm, 0, sizeof req.rtm);
+        memset (&rta, 0, sizeof rta);
+        req.nlh.nlmsg_type = RTM_NEWROUTE;
+        /* Append this routing for 0.0.0.0. By this way we can send always
+         * dhcp messages (e.g dhcp renew).
+         */
+        req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE
+          | NLM_F_APPEND;
+        req.rtm.rtm_protocol = RTPROT_BOOT;
+        req.rtm.rtm_scope = RT_SCOPE_LINK;
+        req.rtm.rtm_type = RTN_UNICAST;
+        rta.rta_dst = &dst->sin_addr.s_addr;
+        rta.rta_oif = &dev->ifindex;
+        tb = fib_new_table (req.rtm.rtm_table);
+        if (tb)
+          err = tb->tb_insert (tb, &req.rtm, &rta, &req.nlh, NULL);
+        else
+          err = ENOBUFS;
+
+        if (err)
+        {
+          __mutex_unlock (&global_lock);
+          FAIL (err, 17, 0, "cannot add route");
+        }
+      }
+
       __mutex_unlock (&global_lock);
 
       /* Fall through to free hook.  */
@@ -526,8 +684,9 @@ trivfs_append_args (struct trivfs_contro
         ADD_ADDR_OPT ("netmask", mask);
       if (peer != addr)
 	ADD_ADDR_OPT ("peer", peer);
-      key.iif = dev->ifindex;
-      if (! main_table->tb_lookup (main_table, &key, &res)) 
+      key.oif = dev->ifindex;
+      if (! main_table->tb_lookup (main_table, &key, &res)
+          && FIB_RES_GW(res) != INADDR_ANY)
 	ADD_ADDR_OPT ("gateway", FIB_RES_GW (res));
 
 #undef ADD_ADDR_OPT
Index: linux-src/net/ipv4/devinet.c
===================================================================
RCS file: /sources/hurd/hurd/pfinet/linux-src/net/ipv4/devinet.c,v
retrieving revision 1.8
diff -p -u -r1.8 devinet.c
--- linux-src/net/ipv4/devinet.c	18 Jul 2001 17:37:13 -0000	1.8
+++ linux-src/net/ipv4/devinet.c	22 Oct 2007 20:49:04 -0000
@@ -214,10 +214,12 @@ inet_insert_ifa(struct in_device *in_dev
 {
 	struct in_ifaddr *ifa1, **ifap, **last_primary;
 
+#ifndef _HURD_
 	if (ifa->ifa_local == 0) {
 		inet_free_ifa(ifa);
 		return 0;
 	}
+#endif
 
 	ifa->ifa_flags &= ~IFA_F_SECONDARY;
 	last_primary = &in_dev->ifa_list;
#!/bin/sh

FSYSOPTS=/bin/fsysopts
DSOCKET=/servers/socket/2
PFINET=/hurd/pfinet
DEFAULT_INTERFACE=eth0

# test if there is an pfinet on /servers/socket/2 
if ! $FSYSOPTS $DSOCKET | grep -q pfinet; then
  settrans -fga $DSOCKET $PFINET -i $DEFAULT_INTERFACE -a 0.0.0.0 \
    -m 255.255.255.0
  $FSYSOPTS $DSOCKET -i $DEFAULT_INTERFACE -6 ${DSOCKET}6
fi



usage() {
  echo "$0 [-6] INTERFACE IP  -  set the ip (or ipv6) address of this device"
  echo "$0 [-6] INTERFACE gateway IP - set the default gateway of this device"
  echo "$0 INTERFACE nm MASK - set the netmask of this device"
  echo "$0 [-6] INTERFACE down - unset global ip of this device"
}

ipv4() {
  echo "$1" | grep -q "^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$"
}

ipv6() {
  echo "$1" | grep -q "^[0-9a-fA-F]*:[0-9a-fA-F]*"
}

get_interfaces() {
  $FSYSOPTS $DSOCKET | tr ' ' '\n' | sed -n 's/--interface=\([^ ]*\)/\1/p'
}
show_interface() {
  echo $1
  $FSYSOPTS $DSOCKET |  tr ' ' '\n' | \
    sed -n '/^--interface='"$1"'$/,/--interface/ {
      s/^--address=\([^ ]*\)/  Address: \1/p
      s/^--gateway=\([^ ]*\)/  Default Gateway: \1/p
      s/^--netmask=\([^ ]*\)/  Netmask: \1/p
      s/^--address6=\(fe80[^ ]*\)/  inet6 address: \1 (link local)/p
      s/^--address6=\([^ ]*\)/  inet6 address: \1 (global)/p
      s/^--gateway6=\([^ ]*\)/  inet6 gateway: \1/p
    }
    '
}

if [ "x$1" = "x--help" -o "x$1" = "x-h" ]; then
  usage
  exit 0
fi

if [ -z "$1" ]; then
  for ifname in `get_interfaces`; do
    show_interface $ifname
  done
else
  if [ "x$1" = "x-6" ]; then
    V6=true
    shift
  fi
  ifname="$1"
  if [ -z "$2" ]; then
    show_interface $ifname
  elif [ "x$2" = "xgateway" -o "x$2" = "xgw" ]; then
    if [ "x$V6" = "xtrue" ]; then
      if ipv6 "$3"; then
        $FSYSOPTS $DSOCKET -i $ifname -G$3
      else
        echo "No valid address"
      fi
    else
      if ipv4 "$3"; then
        $FSYSOPTS $DSOCKET -i $ifname -g$3
      else
        echo "No valid address"
      fi
    fi
  elif [ "x$2" = "xnetmask" -o "x$2" = "xnm" ]; then
    if ipv4 "$3"; then
      $FSYSOPTS $DSOCKET -i $ifname -m$3
    else
      if [ "x$V6" = "xtrue" ]; then
        echo "There are no real netmasks in ipv6"
      else
        echo "No valid netmask"
      fi
    fi
  elif [ "x$2" = "xup" ]; then
    if [ "x$V6" = "xtrue" ]; then
      $FSYSOPTS $DSOCKET -i $ifname -6 /servers/socket/26
    fi
  elif [ "x$2" = "xdown" ]; then
    if [ "x$V6" = "xtrue" ]; then
      $FSYSOPTS $DSOCKET -i $ifname -A
    else
      $FSYSOPTS $DSOCKET -i $ifname -a 0.0.0.0 -m 255.255.255.0
    fi
  elif ipv4 "$2"; then
      $FSYSOPTS $DSOCKET -i $ifname -a$2
  elif ipv6 "$2"; then
      $FSYSOPTS $DSOCKET -i $ifname -A$2
  else
    echo "invalid options"
  fi
fi
_______________________________________________
Bug-hurd mailing list
Bug-hurd@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-hurd

Reply via email to