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