bug-zebra
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ipforward_solaris.c rewrite.


From: Jim Crumpler
Subject: ipforward_solaris.c rewrite.
Date: Mon, 10 Jun 2002 23:11:27 +1000

Hi, the existing ipforward_solaris.c had the following problems:

- it only checked ip forwarding, it didn't change it (ie, "no ip forwarding"
didn't work)
- it didn't log errors with the open of the ioctl commands.
- it supported IPv4 only.

I've found information on the format of the ND_SET command and I've
implemented it below..  I've also added support for ip forwarding support
for IPv6 when it is enabled one day - for the moment those lines are
harmless until HAVE_IPV6 is defined.

I've tested the code on Solaris 9 SPARC, Solaris 8 x86, Solaris 2.6 x86 so
far.  The code was diffed against the current CVS tree version of
ipfoward_solaris.c (10th June).

The "no ip forwarding" command now works on solaris.

Jim..

Index: ipforward_solaris.c
===================================================================
RCS file: /cvsroot/zebra/zebra/ipforward_solaris.c,v
retrieving revision 1.7
diff -r1.7 ipforward_solaris.c
23a24
> #include "log.h"
25c26,44
< #include "memory.h"
---
> /*
> ** Solaris should define IP_DEV_NAME in <inet/ip.h>, but we'll save
> ** configure.in changes for another day.  We can use the same device
> ** for both IPv4 and IPv6.
> */
>
> /* #include <inet/ip.h> */
>
> #ifndef IP_DEV_NAME
> #define IP_DEV_NAME "/dev/ip"
> #endif
>
> /*
> ** This is a limited ndd style function that operates one integer
> ** value only.  Errors return -1. ND_SET commands return 0 on
> ** success. ND_GET commands return the value on success (which could
> ** be -1 and be confused for an error).  The parameter is the string
> ** name of the parameter being referenced.
> */
27,28c46,47
< int
< ipforward ()
---
> static int
> solaris_nd(const int cmd, const char* parameter, const int value)
30,43c49,71
<   int fd, ret;
<   int ipforwarding = 0;
<   char forward[] = "ip_forwarding";
<   char *buf;
<   struct strioctl si;
<
<   buf = (char *) XMALLOC (MTYPE_TMP, sizeof forward + 1);
<   strcpy (buf, forward);
<
<   fd = open ("/dev/ip", O_RDWR);
<   if (fd < 0) {
<     free (buf);
<     /* need logging here */
<     /* "I can't get ipforwarding value because can't open /dev/ip" */
---
>
> #define ND_BUFFER_SIZE 1024
>
>   int fd;
>   char nd_buf[ND_BUFFER_SIZE];
>   struct strioctl strioctl;
>   const char* device = IP_DEV_NAME;
>   int retval;
>
>   memset(nd_buf, '\0', ND_BUFFER_SIZE);
>
>   /*
>   ** ND_SET takes a NULL delimited list of strings further terminated
>   ** buy a NULL.  ND_GET returns a list in a similar layout, although
>   ** here we only use the first result.
>   */
>
>   if (cmd == ND_SET) {
>     snprintf(nd_buf, ND_BUFFER_SIZE, "%s%c%d%c", parameter, '\0', value,
'\0');
>   } else if (cmd == ND_GET) {
>     snprintf(nd_buf, ND_BUFFER_SIZE, "%s", parameter);
>   } else {
>     zlog_err("internal error - inappropriate command given to solaris_nd()
%s:%d", __FILE__, __LINE__);
46,58c74,87
<
<   si.ic_cmd = ND_GET;
<   si.ic_timout = 0;
<   si.ic_len = strlen (buf) + 1;
<   si.ic_dp = (caddr_t) buf;
<
<   ret = ioctl (fd, I_STR, &si);
<   close (fd);
<
<   if (ret < 0) {
<     free (buf);
<     /* need logging here */
<     /* can't get ipforwarding value : ioctl failed */
---
>
>   strioctl.ic_cmd = cmd;
>   strioctl.ic_timout = 0;
>   strioctl.ic_len = ND_BUFFER_SIZE;
>   strioctl.ic_dp = nd_buf;
>
>   if ((fd = open (device, O_RDWR)) < 0) {
>     zlog_warn("failed to open device %s - %s", device, strerror(errno));
>     return -1;
>   }
>
>   if (ioctl (fd, I_STR, &strioctl) < 0) {
>     close (fd);
>     zlog_warn("ioctl I_STR failed on device %s - %s", device,
strerror(errno));
60a90,106
>
>   close(fd);
>
>   if (cmd == ND_GET) {
>     errno = 0;
>     retval = atoi(nd_buf);
>     if (errno) {
>       zlog_warn("failed to convert returned value to integer - %s",
strerror(errno));
>       retval = -1;
>     }
>   } else {
>     retval = 0;
>   }
>
>   return retval;
> }
>
62,64c108,121
<   ipforwarding = atoi (buf);
<   free (buf);
<   return ipforwarding;
---
> static int
> solaris_nd_set(const char* parameter, const int value) {
>   return solaris_nd(ND_SET, parameter, value);
> }
>
> static int
> solaris_nd_get(const char* parameter) {
>   return solaris_nd(ND_GET, parameter, 0);
> }
>
> int
> ipforward()
> {
>   return solaris_nd_get("ip_forwarding");
70c127,128
<   return 0;
---
>   (void) solaris_nd_set("ip_forwarding", 1);
>   return ipforward();
76c134,150
<   return 0;
---
>   (void) solaris_nd_set("ip_forwarding", 0);
>   return ipforward();
> }
>
> #ifdef HAVE_IPV6
>
> int ipforward_ipv6()
> {
>   return solaris_nd_get("ip6_fowarding");
>
> }
>
> int
> ipforward_ipv6_on ()
> {
>   (void) solaris_nd_set("ip6_forwarding", 1);
>   return ipforward_ipv6();
77a152,161
>
> int
> ipforward_ipv6_off ()
> {
>   (void) solaris_nd_set("ip6_forwarding", 0);
>   return ipforward_ipv6();
> }
>
> #endif /* HAVE_IPV6 */
>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]