xref: /netbsd-src/sbin/ifconfig/carp.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /* $NetBSD: carp.c,v 1.1 2006/05/18 09:05:50 liamjfoy 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 = (caddr_t)&carpr;
66 
67 	if (ioctl(s, SIOCGVH, (caddr_t)&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 = (caddr_t)&carpr;
91 
92 	if (ioctl(s, SIOCGVH, (caddr_t)&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, (caddr_t)&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 = (caddr_t)&carpr;
123 
124 	if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
125 		err(EXIT_FAILURE, "SIOCGVH");
126 
127 	carpr.carpr_vhid = vhid;
128 
129 	if (ioctl(s, SIOCSVH, (caddr_t)&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 = (caddr_t)&carpr;
154 
155 	if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
156 		err(EXIT_FAILURE, "SIOCGVH");
157 
158 	carpr.carpr_advskew = advskew;
159 
160 	if (ioctl(s, SIOCSVH, (caddr_t)&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 = (caddr_t)&carpr;
185 
186 	if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
187 		err(EXIT_FAILURE, "SIOCGVH");
188 
189 	carpr.carpr_advbase = advbase;
190 
191 	if (ioctl(s, SIOCSVH, (caddr_t)&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 	bzero((char *)&carpr, sizeof(struct carpreq));
203 	ifr.ifr_data = (caddr_t)&carpr;
204 
205 	if (ioctl(s, SIOCGVH, (caddr_t)&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, (caddr_t)&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 	bzero((char *)&carpr, sizeof(struct carpreq));
226 	ifr.ifr_data = (caddr_t)&carpr;
227 
228 	if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
229 		err(EXIT_FAILURE, "SIOCGVH");
230 
231 	strlcpy(carpr.carpr_carpdev, val, sizeof(carpr.carpr_carpdev));
232 
233 	if (ioctl(s, SIOCSVH, (caddr_t)&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 	bzero((char *)&carpr, sizeof(struct carpreq));
243 	ifr.ifr_data = (caddr_t)&carpr;
244 
245 	if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
246 		err(EXIT_FAILURE, "SIOCGVH");
247 
248 	bzero((char *)&carpr.carpr_carpdev, sizeof(carpr.carpr_carpdev));
249 
250 	if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1)
251 		err(EXIT_FAILURE, "SIOCSVH");
252 }
253