[Top][All Lists]
[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 */
>
- ipforward_solaris.c rewrite.,
Jim Crumpler <=