carp.c revision 1.3 1 /* $NetBSD: carp.c,v 1.3 2008/04/21 02:10:45 dyoung Exp $ */
2
3 /*
4 * Copyright (c) 2002 Michael Shalayeff. All rights reserved.
5 * Copyright (c) 2003 Ryan McBride. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30 #include <sys/ioctl.h>
31 #include <sys/socket.h>
32 #include <sys/sockio.h>
33
34 #include <net/if.h>
35 #include <netinet/ip_carp.h>
36 #include <net/route.h>
37
38 #include <stdio.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <err.h>
43 #include <errno.h>
44
45 #include "extern.h"
46
47 void carp_status(void);
48 void setcarp_advbase(const char *,int);
49 void setcarp_advskew(const char *, int);
50 void setcarp_passwd(const char *, int);
51 void setcarp_vhid(const char *, int);
52 void setcarp_state(const char *, int);
53 void setcarpdev(const char *, int);
54 void unsetcarpdev(const char *, int);
55
56 static const char *carp_states[] = { CARP_STATES };
57
58 void
59 carp_status(void)
60 {
61 const char *state;
62 struct carpreq carpr;
63
64 memset((char *)&carpr, 0, sizeof(struct carpreq));
65 ifr.ifr_data = &carpr;
66
67 if (ioctl(s, SIOCGVH, &ifr) == -1)
68 return;
69
70 if (carpr.carpr_vhid > 0) {
71 if (carpr.carpr_state > CARP_MAXSTATE)
72 state = "<UNKNOWN>";
73 else
74 state = carp_states[carpr.carpr_state];
75
76 printf("\tcarp: %s carpdev %s vhid %d advbase %d advskew %d\n",
77 state, carpr.carpr_carpdev[0] != '\0' ?
78 carpr.carpr_carpdev : "none", carpr.carpr_vhid,
79 carpr.carpr_advbase, carpr.carpr_advskew);
80 }
81 }
82
83 /* ARGSUSED */
84 void
85 setcarp_passwd(const char *val, int d)
86 {
87 struct carpreq carpr;
88
89 memset((char *)&carpr, 0, sizeof(struct carpreq));
90 ifr.ifr_data = &carpr;
91
92 if (ioctl(s, SIOCGVH, &ifr) == -1)
93 err(EXIT_FAILURE, "SIOCGVH");
94
95 /* XXX Should hash the password into the key here, perhaps? */
96 strlcpy((char *)carpr.carpr_key, val, CARP_KEY_LEN);
97
98 if (ioctl(s, SIOCSVH, &ifr) == -1)
99 err(EXIT_FAILURE, "SIOCSVH");
100 }
101
102 /* ARGSUSED */
103 void
104 setcarp_vhid(const char *val, int d)
105 {
106 struct carpreq carpr;
107 long tmp;
108 char *ep;
109 int vhid;
110
111 errno = 0;
112 tmp = strtol(val, &ep, 10);
113
114 if (*ep != '\0' || tmp < 0 || tmp > 255
115 || errno == ERANGE)
116 errx(EXIT_FAILURE, "vhid: %s: must be between 0 and 255",
117 val);
118
119 vhid = (int)tmp;
120
121 memset((char *)&carpr, 0, sizeof(struct carpreq));
122 ifr.ifr_data = &carpr;
123
124 if (ioctl(s, SIOCGVH, &ifr) == -1)
125 err(EXIT_FAILURE, "SIOCGVH");
126
127 carpr.carpr_vhid = vhid;
128
129 if (ioctl(s, SIOCSVH, &ifr) == -1)
130 err(EXIT_FAILURE, "SIOCSVH");
131 }
132
133 /* ARGSUSED */
134 void
135 setcarp_advskew(const char *val, int d)
136 {
137 struct carpreq carpr;
138 long tmp;
139 char *ep;
140 int advskew;
141
142 errno = 0;
143 tmp = strtol(val, &ep, 10);
144
145 if (*ep != '\0' || tmp < 0 || tmp > 254
146 || errno == ERANGE)
147 errx(EXIT_FAILURE, "advskew: %s: must be between 0 and 254",
148 val);
149
150 advskew = (int)tmp;
151
152 memset((char *)&carpr, 0, sizeof(struct carpreq));
153 ifr.ifr_data = &carpr;
154
155 if (ioctl(s, SIOCGVH, &ifr) == -1)
156 err(EXIT_FAILURE, "SIOCGVH");
157
158 carpr.carpr_advskew = advskew;
159
160 if (ioctl(s, SIOCSVH, &ifr) == -1)
161 err(EXIT_FAILURE, "SIOCSVH");
162 }
163
164 /* ARGSUSED */
165 void
166 setcarp_advbase(const char *val, int d)
167 {
168 struct carpreq carpr;
169 long tmp;
170 char *ep;
171 int advbase;
172
173 errno = 0;
174 tmp = strtol(val, &ep, 10);
175
176 if (*ep != '\0' || tmp < 0 || tmp > 255
177 || errno == ERANGE)
178 errx(EXIT_FAILURE, "advbase: %s: must be between 0 and 255",
179 val);
180
181 advbase = (int)tmp;
182
183 memset((char *)&carpr, 0, sizeof(struct carpreq));
184 ifr.ifr_data = &carpr;
185
186 if (ioctl(s, SIOCGVH, &ifr) == -1)
187 err(EXIT_FAILURE, "SIOCGVH");
188
189 carpr.carpr_advbase = advbase;
190
191 if (ioctl(s, SIOCSVH, &ifr) == -1)
192 err(EXIT_FAILURE, "SIOCSVH");
193 }
194
195 /* ARGSUSED */
196 void
197 setcarp_state(const char *val, int d)
198 {
199 struct carpreq carpr;
200 int i;
201
202 memset(&carpr, 0, sizeof(carpr));
203 ifr.ifr_data = &carpr;
204
205 if (ioctl(s, SIOCGVH, &ifr) == -1)
206 err(EXIT_FAILURE, "SIOCGVH");
207
208 for (i = 0; i <= CARP_MAXSTATE; i++) {
209 if (!strcasecmp(val, carp_states[i])) {
210 carpr.carpr_state = i;
211 break;
212 }
213 }
214
215 if (ioctl(s, SIOCSVH, &ifr) == -1)
216 err(EXIT_FAILURE, "SIOCSVH");
217 }
218
219 /* ARGSUSED */
220 void
221 setcarpdev(const char *val, int d)
222 {
223 struct carpreq carpr;
224
225 memset(&carpr, 0, sizeof(carpr));
226 ifr.ifr_data = &carpr;
227
228 if (ioctl(s, SIOCGVH, &ifr) == -1)
229 err(EXIT_FAILURE, "SIOCGVH");
230
231 strlcpy(carpr.carpr_carpdev, val, sizeof(carpr.carpr_carpdev));
232
233 if (ioctl(s, SIOCSVH, &ifr) == -1)
234 err(EXIT_FAILURE, "SIOCSVH");
235 }
236
237 void
238 unsetcarpdev(const char *val, int d)
239 {
240 struct carpreq carpr;
241
242 memset(&carpr, 0, sizeof(carpr));
243 ifr.ifr_data = &carpr;
244
245 if (ioctl(s, SIOCGVH, &ifr) == -1)
246 err(EXIT_FAILURE, "SIOCGVH");
247
248 memset(&carpr.carpr_carpdev, 0, sizeof(carpr.carpr_carpdev));
249
250 if (ioctl(s, SIOCSVH, &ifr) == -1)
251 err(EXIT_FAILURE, "SIOCSVH");
252 }
253