]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * ipforward value get function for solaris. | |
3 | * Copyright (C) 1997 Kunihiro Ishiguro | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
269c67c5 | 24 | #include "log.h" |
edd7c245 | 25 | #include "prefix.h" |
718e3744 | 26 | |
9bcdb638 | 27 | #include "privs.h" |
a1ac18c4 | 28 | #include "zebra/ipforward.h" |
9bcdb638 | 29 | |
269c67c5 | 30 | /* |
31 | ** Solaris should define IP_DEV_NAME in <inet/ip.h>, but we'll save | |
32 | ** configure.in changes for another day. We can use the same device | |
33 | ** for both IPv4 and IPv6. | |
34 | */ | |
35 | /* #include <inet/ip.h> */ | |
36 | #ifndef IP_DEV_NAME | |
37 | #define IP_DEV_NAME "/dev/ip" | |
38 | #endif | |
9bcdb638 | 39 | |
edd7c245 | 40 | |
41 | extern struct zebra_privs_t zserv_privs; | |
42 | ||
9bcdb638 | 43 | /* This is a limited ndd style function that operates one integer |
269c67c5 | 44 | ** value only. Errors return -1. ND_SET commands return 0 on |
45 | ** success. ND_GET commands return the value on success (which could | |
46 | ** be -1 and be confused for an error). The parameter is the string | |
47 | ** name of the parameter being referenced. | |
48 | */ | |
718e3744 | 49 | |
269c67c5 | 50 | static int |
51 | solaris_nd(const int cmd, const char* parameter, const int value) | |
718e3744 | 52 | { |
269c67c5 | 53 | #define ND_BUFFER_SIZE 1024 |
54 | int fd; | |
55 | char nd_buf[ND_BUFFER_SIZE]; | |
56 | struct strioctl strioctl; | |
57 | const char* device = IP_DEV_NAME; | |
58 | int retval; | |
59 | memset(nd_buf, '\0', ND_BUFFER_SIZE); | |
60 | /* | |
61 | ** ND_SET takes a NULL delimited list of strings further terminated | |
62 | ** buy a NULL. ND_GET returns a list in a similar layout, although | |
63 | ** here we only use the first result. | |
64 | */ | |
66e9488c | 65 | if (cmd == ND_SET) |
269c67c5 | 66 | snprintf(nd_buf, ND_BUFFER_SIZE, "%s%c%d%c", parameter, '\0', value,'\0'); |
66e9488c | 67 | else if (cmd == ND_GET) |
269c67c5 | 68 | snprintf(nd_buf, ND_BUFFER_SIZE, "%s", parameter); |
66e9488c | 69 | else { |
70 | zlog_err("internal error - inappropriate command given to " | |
71 | "solaris_nd()%s:%d", __FILE__, __LINE__); | |
718e3744 | 72 | return -1; |
73 | } | |
edd7c245 | 74 | |
269c67c5 | 75 | strioctl.ic_cmd = cmd; |
76 | strioctl.ic_timout = 0; | |
77 | strioctl.ic_len = ND_BUFFER_SIZE; | |
78 | strioctl.ic_dp = nd_buf; | |
edd7c245 | 79 | |
80 | if ( zserv_privs.change (ZPRIVS_RAISE) ) | |
81 | zlog_err ("solaris_nd: Can't raise privileges"); | |
82 | if ((fd = open (device, O_RDWR)) < 0) | |
83 | { | |
6099b3b5 | 84 | zlog_warn("failed to open device %s - %s", device, safe_strerror(errno)); |
edd7c245 | 85 | if ( zserv_privs.change (ZPRIVS_LOWER) ) |
86 | zlog_err ("solaris_nd: Can't lower privileges"); | |
87 | return -1; | |
88 | } | |
89 | if (ioctl (fd, I_STR, &strioctl) < 0) | |
90 | { | |
4460e7a4 | 91 | int save_errno = errno; |
edd7c245 | 92 | if ( zserv_privs.change (ZPRIVS_LOWER) ) |
93 | zlog_err ("solaris_nd: Can't lower privileges"); | |
94 | close (fd); | |
4460e7a4 | 95 | zlog_warn("ioctl I_STR failed on device %s - %s", |
96 | device, safe_strerror(save_errno)); | |
edd7c245 | 97 | return -1; |
98 | } | |
269c67c5 | 99 | close(fd); |
edd7c245 | 100 | if ( zserv_privs.change (ZPRIVS_LOWER) ) |
101 | zlog_err ("solaris_nd: Can't lower privileges"); | |
102 | ||
103 | if (cmd == ND_GET) | |
104 | { | |
105 | errno = 0; | |
106 | retval = atoi(nd_buf); | |
107 | if (errno) | |
108 | { | |
109 | zlog_warn("failed to convert returned value to integer - %s", | |
6099b3b5 | 110 | safe_strerror(errno)); |
edd7c245 | 111 | retval = -1; |
112 | } | |
113 | } | |
114 | else | |
115 | { | |
116 | retval = 0; | |
269c67c5 | 117 | } |
269c67c5 | 118 | return retval; |
119 | } | |
718e3744 | 120 | |
269c67c5 | 121 | static int |
122 | solaris_nd_set(const char* parameter, const int value) { | |
123 | return solaris_nd(ND_SET, parameter, value); | |
124 | } | |
125 | static int | |
126 | solaris_nd_get(const char* parameter) { | |
127 | return solaris_nd(ND_GET, parameter, 0); | |
128 | } | |
129 | int | |
a1ac18c4 | 130 | ipforward(void) |
269c67c5 | 131 | { |
132 | return solaris_nd_get("ip_forwarding"); | |
718e3744 | 133 | } |
134 | ||
135 | int | |
a1ac18c4 | 136 | ipforward_on (void) |
718e3744 | 137 | { |
269c67c5 | 138 | (void) solaris_nd_set("ip_forwarding", 1); |
139 | return ipforward(); | |
718e3744 | 140 | } |
141 | ||
142 | int | |
a1ac18c4 | 143 | ipforward_off (void) |
718e3744 | 144 | { |
269c67c5 | 145 | (void) solaris_nd_set("ip_forwarding", 0); |
146 | return ipforward(); | |
147 | } | |
148 | #ifdef HAVE_IPV6 | |
a1ac18c4 | 149 | int ipforward_ipv6(void) |
269c67c5 | 150 | { |
66e9488c | 151 | return solaris_nd_get("ip6_forwarding"); |
269c67c5 | 152 | } |
153 | int | |
a1ac18c4 | 154 | ipforward_ipv6_on (void) |
269c67c5 | 155 | { |
156 | (void) solaris_nd_set("ip6_forwarding", 1); | |
157 | return ipforward_ipv6(); | |
158 | } | |
159 | int | |
a1ac18c4 | 160 | ipforward_ipv6_off (void) |
269c67c5 | 161 | { |
162 | (void) solaris_nd_set("ip6_forwarding", 0); | |
163 | return ipforward_ipv6(); | |
718e3744 | 164 | } |
269c67c5 | 165 | #endif /* HAVE_IPV6 */ |