dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * CDDL HEADER START
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * The contents of this file are subject to the terms of the
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Common Development and Distribution License (the "License").
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * You may not use this file except in compliance with the License.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * or http://www.opensolaris.org/os/licensing.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * See the License for the specific language governing permissions
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * and limitations under the License.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * When distributing Covered Code, include this CDDL HEADER in each
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * If applicable, add the following below this CDDL HEADER, with the
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * fields enclosed by brackets "[]" replaced with your own identifying
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * information: Portions Copyright [yyyy] [name of copyright owner]
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * CDDL HEADER END
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Use is subject to license terms.
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <stdio.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <unistd.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <stdlib.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <strings.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <sys/types.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <sys/socket.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <netinet/in.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <arpa/inet.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <netdb.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <errno.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <ctype.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <assert.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <limits.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <libilb.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include <libilb_impl.h>
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#include "ilbadm.h"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra#define PORT_SEP ':'
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misratypedef enum {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra numeric = 1,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra non_numeric
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra} addr_type_t;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_val_type_t algo_types[] = {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {(int)ILB_ALG_ROUNDROBIN, "roundrobin", "rr"},
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {(int)ILB_ALG_HASH_IP, "hash-ip", "hip"},
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {(int)ILB_ALG_HASH_IP_SPORT, "hash-ip-port", "hipp"},
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {(int)ILB_ALG_HASH_IP_VIP, "hash-ip-vip", "hipv"},
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {ILBD_BAD_VAL, NULL, NULL}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra};
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_val_type_t topo_types[] = {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {(int)ILB_TOPO_DSR, "DSR", "d"},
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {(int)ILB_TOPO_NAT, "NAT", "n"},
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {(int)ILB_TOPO_HALF_NAT, "HALF-NAT", "h"},
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra {ILBD_BAD_VAL, NULL, NULL}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra};
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misravoid
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misraip2str(ilb_ip_addr_t *ip, char *buf, size_t sz, int flags)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int len;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (ip->ia_af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*(uint32_t *)&ip->ia_v4 == 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra buf[0] = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) inet_ntop(AF_INET, (void *)&ip->ia_v4, buf, sz);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET6:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (IN6_IS_ADDR_UNSPECIFIED(&ip->ia_v6)) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra buf[0] = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (!(flags & V6_ADDRONLY))
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *buf++ = '[';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sz--;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) inet_ntop(ip->ia_af, (void *)&ip->ia_v6, buf, sz);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (!(flags & V6_ADDRONLY)) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra len = strlen(buf);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra buf[len] = ']';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra buf[++len] = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra default: buf[0] = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrachar *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_str_from_val(int val, ilbadm_val_type_t *types)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_val_type_t *v;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra for (v = types; v->v_type != ILBD_BAD_VAL; v++) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (v->v_type == val)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* we return this in all cases */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (v->v_name);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misraint
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_val_from_str(char *name, ilbadm_val_type_t *types)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_val_type_t *v;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra for (v = types; v->v_type != ILBD_BAD_VAL; v++) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (strncasecmp(name, v->v_name, sizeof (v->v_name)) == 0 ||
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra strncasecmp(name, v->v_alias, sizeof (v->v_alias)) == 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* we return this in all cases */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (v->v_type);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_key_code_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_match_key(char *key, ilbadm_key_name_t *keylist)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_key_name_t *t_key;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra for (t_key = keylist; t_key->k_key != ILB_KEY_BAD; t_key++) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (strncasecmp(key, t_key->k_name,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sizeof (t_key->k_name)) == 0 ||
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra strncasecmp(key, t_key->k_alias,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sizeof (t_key->k_alias)) == 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (t_key->k_key);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * try to match:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 1) IPv4 address
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 2) IPv6 address
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 3) a hostname
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic ilbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_match_onehost(const char *val, ilb_ip_addr_t *ip, addr_type_t *a_type)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct addrinfo *ai = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct addrinfo hints;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra addr_type_t at = numeric;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) memset((void *)&hints, 0, sizeof (hints));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra hints.ai_flags |= AI_NUMERICHOST;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * if *a_type == numeric, we only want to check whether this
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * is a (valid) numeric IP address. If we do and it is NOT,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we return _ENOENT.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (getaddrinfo(val, NULL, &hints, &ai) != 0) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (a_type != NULL && (*a_type == numeric))
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_INVAL_ADDR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra at = non_numeric;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (getaddrinfo(val, NULL, NULL, &ai) != 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_INVAL_ADDR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip->ia_af = ai->ai_family;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (ip->ia_af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET: {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct sockaddr_in sa;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra assert(ai->ai_addrlen == sizeof (sa));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) memcpy(&sa, ai->ai_addr, sizeof (sa));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip->ia_v4 = sa.sin_addr;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET6: {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct sockaddr_in6 sa;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra assert(ai->ai_addrlen == sizeof (sa));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) memcpy(&sa, ai->ai_addr, sizeof (sa));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip->ia_v6 = sa.sin6_addr;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra default:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_INVAL_AF);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (a_type != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *a_type = at;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic ilbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_store_serverID(void *store, char *val)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_servnode_t *s = (ilbadm_servnode_t *)store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_server_data_t *sn = &s->s_spec;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we shouldn't need to check for length here, as a name that's
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * too long won't exist in the system anyway.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) strlcpy(sn->sd_srvID, val, sizeof (sn->sd_srvID));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic struct in_addr
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_next_in_addr(struct in_addr *a, int dir)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct in_addr new_in;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra uint32_t iah;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra iah = ntohl(a->s_addr);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (dir == 1)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra iah++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra iah--;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra new_in.s_addr = htonl(iah);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (new_in);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic ilbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_expand_ipv4range(ilbadm_sgroup_t *sg, ilb_server_data_t *srv,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t *ip1, ilb_ip_addr_t *ip2)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct in_addr *a1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_servnode_t *sn_new;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t new_ip;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra a1 = &ip1->ia_v4;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra new_ip.ia_af = AF_INET;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra new_ip.ia_v4 = i_next_in_addr(a1, 1);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra while (ilb_cmp_ipaddr(&new_ip, ip2, NULL) < 1) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new = i_new_sg_elem(sg);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new->s_spec.sd_addr = new_ip;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new->s_spec.sd_minport = srv->sd_minport;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new->s_spec.sd_maxport = srv->sd_maxport;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra new_ip.ia_v4 = i_next_in_addr(&new_ip.ia_v4, 1);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic struct in6_addr
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_next_in6_addr(struct in6_addr *a, int dir)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct in6_addr ia6;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra uint64_t al, ah;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ah = INV6_N2H_MSB64(a);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra al = INV6_N2H_LSB64(a);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (dir == 1) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* overflow */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (++al == 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ah++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra } else {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* underflow */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (--al == 0xffffffff)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ah--;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra INV6_H2N_MSB64(&ia6, ah);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra INV6_H2N_LSB64(&ia6, al);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ia6);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic ilbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_expand_ipv6range(ilbadm_sgroup_t *sg, ilb_server_data_t *srv,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t *ip1, ilb_ip_addr_t *ip2)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct in6_addr *a1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_servnode_t *sn_new;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t new_ip;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra a1 = &ip1->ia_v6;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra new_ip.ia_af = AF_INET6;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra new_ip.ia_v6 = i_next_in6_addr(a1, 1);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra while (ilb_cmp_ipaddr(&new_ip, ip2, NULL) < 1) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new = i_new_sg_elem(sg);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new->s_spec.sd_addr = new_ip;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new->s_spec.sd_minport = srv->sd_minport;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sn_new->s_spec.sd_maxport = srv->sd_maxport;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra new_ip.ia_v6 = i_next_in6_addr(&new_ip.ia_v6, 1);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we create a list node in the servergroup for every ip address
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * in the range [ip1, ip2], where we interpret the ip addresses as
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * numbers
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * the first ip address is already stored in "sn"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic ilbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_expand_iprange(ilbadm_sgroup_t *sg, ilb_server_data_t *sr,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t *ip1, ilb_ip_addr_t *ip2)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int cmp;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int64_t delta;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (ip2->ia_af == 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (ip1->ia_af != ip2->ia_af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("IP address mismatch"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_LIBERR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* if ip addresses are the same, we're done */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if ((cmp = ilb_cmp_ipaddr(ip1, ip2, &delta)) == 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (cmp == 1) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("starting IP address is must be less"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " than ending ip address in ip range specification"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_LIBERR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* if the implicit number of IPs is too large, stop */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (abs((int)delta) > MAX_IP_SPREAD)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_TOOMANYIPADDR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (ip1->ia_af) {
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik case AF_INET:
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik return (i_expand_ipv4range(sg, sr, ip1, ip2));
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik case AF_INET6:
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik return (i_expand_ipv6range(sg, sr, ip1, ip2));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_INVAL_AF);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * parse a port spec (number or by service name) and
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * return the numeric port in *host* byte order
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Upon return, *flags contains ILB_FLAGS_SRV_PORTNAME if a service name matches
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic int
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_parseport(char *port, char *proto, int *flags)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct servent *se;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* assumption: port names start with a non-digit */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (isdigit(port[0])) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (flags != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *flags &= ~ILB_FLAGS_SRV_PORTNAME;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return ((int)strtol(port, NULL, 10));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra se = getservbyname(port, proto);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (se == NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (-1);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (flags != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *flags |= ILB_FLAGS_SRV_PORTNAME;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we need to convert to host byte order to be in sync with
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * numerical ports. since result needs to be compared, this
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * is preferred to returning NW byte order
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return ((int)(ntohs(se->s_port)));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * matches one hostname or IP address and stores it in "store".
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * space must have been pre-allocated to accept data
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * "sg" != NULL only for cases where ip ranges may be coming in.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic ilbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_match_hostorip(void *store, ilbadm_sgroup_t *sg, char *val,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int flags, ilbadm_key_code_t keyword)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t is_ip_range_ok = flags & OPT_IP_RANGE;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t is_addr_numeric = flags & OPT_NUMERIC_ONLY;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t is_ports_ok = flags & OPT_PORTS;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t ports_only = flags & OPT_PORTS_ONLY;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t is_nat_src = flags & OPT_NAT;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra char *port_pref, *dash;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra char *port1p, *port2p, *host2p, *host1p;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra char *close1, *close2;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t ip2store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t *ip1, *ip2;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int p1, p2;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_server_data_t *s = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_status_t rc = ILBADM_OK;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int af = AF_INET;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra addr_type_t at = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int p_flg;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct in6_addr v6nameaddr;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra port1p = port2p = host2p = host1p = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra port_pref = dash = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra close1 = close2 = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra errno = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (is_nat_src) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip1 = &rd->r_nat_src_start;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip2 = &rd->r_nat_src_end;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra } else {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_servnode_t *sn = (ilbadm_servnode_t *)store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra s = &sn->s_spec;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip1 = &s->sd_addr;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip2 = &ip2store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra bzero(ip2, sizeof (*ip2));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (ports_only) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra is_ports_ok = B_TRUE;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra port_pref = val - 1; /* we increment again later on */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto ports;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we parse the syntax ip[-ip][:port[-port]]
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * since IPv6 addresses contain ':'s as well, they need to be
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * enclosed in "[]" to be distinct from a potential port spec.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * therefore, we need to first check whether we're dealing with
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * IPv6 addresses before we can go search for the port seperator
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * and ipv6 range could look like this: [ff::0]-[ff::255]:80
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if ((keyword == ILB_KEY_SERVER) && (strchr(val, ':') != NULL) &&
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (*val != '[') && ((inet_pton(AF_INET6, val, &v6nameaddr)) != 0)) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * V6 addresses must be enclosed within
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * brackets when specifying server addresses
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_SYNTAX;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*val == '[') {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra af = AF_INET6;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra host1p = val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra close1 = strchr(val, (int)']');
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (close1 == NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_SYNTAX;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *close1 = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra at = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_onehost(host1p, ip1, &at);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (at != numeric) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_ADDR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (ip1->ia_af != af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_AF;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val = close1 + 1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*val == PORT_SEP) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra port_pref = val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto ports;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*val == '-') {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra dash = val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (!is_ip_range_ok) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("port ranges not allowed"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*val != '[') {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_SYNTAX;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra close2 = strchr(val, (int)']');
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (close2 == NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_SYNTAX;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *close2 = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra host2p = val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra at = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_onehost(host2p, ip2, &at);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (at != numeric) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_ADDR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (ip2->ia_af != af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_AF;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val = close2+1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* ports always potentially allow ranges - XXXms: check? */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra port_pref = strchr(val, (int)PORT_SEP);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misraports:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (port_pref != NULL && is_ports_ok) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra port1p = port_pref + 1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *port_pref = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra dash = strchr(port1p, (int)'-');
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (dash != NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra port2p = dash + 1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *dash = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (port1p != NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra p1 = i_parseport(port1p, NULL, &p_flg);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (p1 == -1 || p1 == 0 || p1 > ILB_MAX_PORT) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("invalid port value %s"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " specified"), port1p);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra s->sd_minport = htons((in_port_t)p1);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (p_flg & ILB_FLAGS_SRV_PORTNAME)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra s->sd_flags |= ILB_FLAGS_SRV_PORTNAME;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (port2p != NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* ranges are only allowed for numeric ports */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (p_flg & ILB_FLAGS_SRV_PORTNAME) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("ranges are only allowed"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " for numeric ports"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra p2 = i_parseport(port2p, NULL, &p_flg);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (p2 == -1 || p2 <= p1 || p2 > ILB_MAX_PORT ||
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (p_flg & ILB_FLAGS_SRV_PORTNAME) ==
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ILB_FLAGS_SRV_PORTNAME) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("invalid port value %s"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " specified"), port2p);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra s->sd_maxport = htons((in_port_t)p2);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we fill the '-' back in, but not the port seperator,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * as the \0 in its place terminates the ip address(es)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (dash != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *dash = '-';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (ports_only)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (af == AF_INET6)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we need to handle these situations for hosts:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * a. ip address
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * b. ip address range (ip1-ip2)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * c. a hostname (may include '-' or start with a digit)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * We want to do hostname lookup only if we're quite sure that
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we actually are looking at neither a single IP address nor a
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * range of same, as this can hang if name service is not set up
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * (sth. likely in a LB environment).
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * here's how we proceed:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 1. try to match numeric only. If that succeeds, we're done.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * (getaddrinfo, which we call in i_match_onehost(), fails if
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * it encounters a '-')
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 2. search for a '-'; if we find one, try numeric match for
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * both sides. if this fails:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 3. re-insert '-' and try for a legal hostname.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 1. */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra at = numeric;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_onehost(val, ip1, &at);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc == ILBADM_OK)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 2. */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra dash = strchr(val, (int)'-');
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (dash != NULL && is_ip_range_ok) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra host2p = dash + 1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *dash = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra at = numeric;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_onehost(host2p, ip2, &at);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK || at != numeric) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *dash = '-';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra dash = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra bzero(ip2, sizeof (*ip2));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto hostname;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * if the RHS of '-' is an IP but LHS is not, we might
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * have a hostname of form x-y where y is just a number
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * (this seems a valid IPv4 address), so we need to
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * try a complete hostname
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_onehost(val, ip1, &at);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK || at != numeric) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *dash = '-';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra dash = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto hostname;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrahostname:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 3. */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (is_addr_numeric)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra at = numeric;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra at = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_onehost(val, ip1, &at);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (s != NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra s->sd_flags |= ILB_FLAGS_SRV_HOSTNAME;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* XXX: todo: save hostname for re-display for admin */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misraout:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (dash != NULL && !is_nat_src) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_expand_iprange(sg, s, ip1, ip2);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto err_out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (is_nat_src && host2p == NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *ip2 = *ip1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misraerr_out:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we re-insert what we overwrote, especially in the error case
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (close2 != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *close2 = ']';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (close1 != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *close1 = '[';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (dash != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *dash = '-';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (port_pref != NULL && !ports_only)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *port_pref = PORT_SEP;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (rc);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * type-agnostic helper function to return a pointer to a
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * pristine (and maybe freshly allocated) piece of storage
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * ready for something fitting "key"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic void *
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_new_storep(void *store, ilbadm_key_code_t key)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra void *res;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (key) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVER:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVRANGE:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVERID:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra res = (void *) i_new_sg_elem(store);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra default: res = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (res);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * make sure everything that needs to be there is there
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_check_rule_spec(ilb_rule_data_t *rd)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int32_t vip_af = rd->r_vip.ia_af;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t *prxy_src;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (vip_af != AF_INET && vip_af != AF_INET6)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_INVAL_AF);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*rd->r_sgname == '\0')
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_ENOSGNAME);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rd->r_algo == 0 || rd->r_topo == 0) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("lbalg or type is unspecified"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_LIBERR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rd->r_topo == ILB_TOPO_NAT) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra prxy_src = &rd->r_nat_src_start;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (prxy_src->ia_af != vip_af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("proxy-src is either missing"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " or its address family does not"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " match that of the VIP address"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_LIBERR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* extend as necessary */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * in parameter "sz" describes size (in bytes) of mask
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic int
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misramask_to_prefixlen(const uchar_t *mask, const int sz)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra uchar_t c;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int i, j;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int len = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int tmask;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * for every byte in the mask, we start with most significant
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * bit and work our way down to the least significant bit; as
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * long as we find the bit set, we add 1 to the length. the
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * first unset bit we encounter terminates this process
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra for (i = 0; i < sz; i++) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra c = mask[i];
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra tmask = 1 << 7;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra for (j = 7; j >= 0; j--) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if ((c & tmask) == 0)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (len);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra len++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra tmask >>= 1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (len);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misraint
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_mask_to_prefixlen(ilb_ip_addr_t *ip)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int af = ip->ia_af;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int len = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra assert(af == AF_INET || af == AF_INET6);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra len = mask_to_prefixlen((uchar_t *)&ip->ia_v4.s_addr,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sizeof (ip->ia_v4));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET6:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra len = mask_to_prefixlen((uchar_t *)&ip->ia_v6.s6_addr,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sizeof (ip->ia_v6));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (len);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/* copied from ifconfig.c, changed to return symbolic constants */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Convert a prefix length to a mask.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Returns 1 if ok. 0 otherwise.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Assumes the mask array is zero'ed by the caller.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic boolean_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrain_prefixlentomask(int prefixlen, int maxlen, uchar_t *mask)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (prefixlen < 0 || prefixlen > maxlen)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (B_FALSE);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra while (prefixlen > 0) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (prefixlen >= 8) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *mask++ = 0xFF;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra prefixlen -= 8;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra continue;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *mask |= 1 << (8 - prefixlen);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra prefixlen--;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (B_TRUE);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_set_netmask(char *val, ilb_ip_addr_t *ip, int af)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int prefixlen, maxval;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t r;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra char *end;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra assert(af == AF_INET || af == AF_INET6);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra maxval = (af == AF_INET) ? 32 : 128;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*val == '/')
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra prefixlen = strtol(val, &end, 10);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if ((val == end) || (*end != '\0')) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("invalid pmask provided"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_LIBERR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (prefixlen < 1 || prefixlen > maxval) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("invalid pmask provided (AF mismatch?)"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_LIBERR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra r = in_prefixlentomask(prefixlen, maxval,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (uchar_t *)&ip->ia_v4.s_addr);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case AF_INET6:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra r = in_prefixlentomask(prefixlen, maxval,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (uchar_t *)&ip->ia_v6.s6_addr);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (r != B_TRUE) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("cannot convert %s to a netmask"), val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_LIBERR);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ip->ia_af = af;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_OK);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrastatic ilbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_store_val(char *val, void *store, ilbadm_key_code_t keyword)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_status_t rc = ILBADM_OK;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra void *storep = store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_rule_data_t *rd = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_sgroup_t *sg = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_hc_info_t *hc_info = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct protoent *pe;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int64_t tmp_val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*val == '\0')
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_NOKEYWORD_VAL);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* some types need new storage, others don't */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (keyword) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVER:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVERID:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sg = (ilbadm_sgroup_t *)store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra storep = i_new_storep(store, keyword);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HEALTHCHECK:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVERGROUP:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd = (ilb_rule_data_t *)store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_VIP: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_PORT: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HCPORT: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_CONNDRAIN: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_NAT_TO: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_STICKY_TO: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_PROTOCOL: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_ALGORITHM: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_STICKY: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_TYPE: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SRC: /* fallthrough */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd = (ilb_rule_data_t *)store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_TEST:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_COUNT:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_INTERVAL:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_TIMEOUT:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra hc_info = (ilb_hc_info_t *)store;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra default: /* do nothing */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra switch (keyword) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SRC:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * the proxy-src keyword is only valid for full NAT topology
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * the value is either a single or a range of IP addresses.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rd->r_topo != ILB_TOPO_NAT) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_PROXY;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_hostorip(storep, sg, val, OPT_NUMERIC_ONLY |
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra OPT_IP_RANGE | OPT_NAT, ILB_KEY_SRC);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVER:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_hostorip(storep, sg, val,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra OPT_IP_RANGE | OPT_PORTS, ILB_KEY_SERVER);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVERID:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (val[0] != ILB_SRVID_PREFIX)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_SRVID;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_store_serverID(storep, val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_VIP: {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilb_ip_addr_t *vip = &rd->r_vip;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra addr_type_t at = numeric;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra char *close = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * we duplicate some functionality of i_match_hostorip
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * here; that function is geared to mandate '[]' for IPv6
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * addresses, which we want to relax here, so as not to
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * make i_match_hostorip even longer, we do what we need
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * here.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (*val == '[') {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if ((close = strchr(val, (int)']')) == NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_SYNTAX;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *close = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_onehost(val, vip, &at);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* re-assemble string as we found it */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (close != NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *close = ']';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc == ILBADM_OK && vip->ia_af != AF_INET6) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("use of '[]' only valid"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " with IPv6 addresses"));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_CONNDRAIN:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra tmp_val = strtoll(val, NULL, 10);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (tmp_val <= 0 || tmp_val > UINT_MAX) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_EINVAL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_conndrain = tmp_val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_NAT_TO:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra tmp_val = strtoll(val, NULL, 10);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (tmp_val < 0 || tmp_val > UINT_MAX) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_EINVAL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_nat_timeout = tmp_val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_STICKY_TO:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra tmp_val = strtoll(val, NULL, 10);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (tmp_val <= 0 || tmp_val > UINT_MAX) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_EINVAL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_sticky_timeout = tmp_val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_PORT:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (isdigit(*val)) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_servnode_t sn;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra bzero(&sn, sizeof (sn));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_match_hostorip((void *)&sn, sg, val,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra OPT_PORTS_ONLY, ILB_KEY_PORT);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_minport = sn.s_spec.sd_minport;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_maxport = sn.s_spec.sd_maxport;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra } else {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra struct servent *se;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra se = getservbyname(val, NULL);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (se == NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_ENOSERVICE;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_minport = se->s_port;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_maxport = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HCPORT:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (isdigit(*val)) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int hcport = atoi(val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (hcport < 1 || hcport > 65535) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("illegal number for"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra " hcport %s"), val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_hcport = htons(hcport);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_hcpflag = ILB_HCI_PROBE_FIX;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra } else if (strcasecmp(val, "ANY") == 0) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_hcport = 0;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_hcpflag = ILB_HCI_PROBE_ANY;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra } else {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_EINVAL);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_PROTOCOL:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra pe = getprotobyname(val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (pe == NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_ENOPROTO;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_proto = pe->p_proto;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_ALGORITHM:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_algo = i_val_from_str(val, &algo_types[0]);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rd->r_algo == ILBD_BAD_VAL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_ALG;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_STICKY:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_flags |= ILB_FLAGS_RULE_STICKY;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * CAVEAT: the use of r_vip.ia_af implies that the VIP
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * *must* be specified on the commandline *before*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * the sticky mask.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (AF_UNSPEC == rd->r_vip.ia_af) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("option '%s' requires that VIP be "
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra "specified first"), ilbadm_key_to_opt(keyword));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ilbadm_set_netmask(val, &rd->r_stickymask,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_vip.ia_af);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_TYPE:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rd->r_topo = i_val_from_str(val, &topo_types[0]);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rd->r_topo == ILBD_BAD_VAL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_INVAL_OPER;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_SERVERGROUP:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) strlcpy(rd->r_sgname, (char *)val,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sizeof (rd->r_sgname));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HEALTHCHECK:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) strlcpy(rd->r_hcname, (char *)val,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sizeof (rd->r_hcname));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_TEST:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra (void) strlcpy(hc_info->hci_test, (char *)val,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra sizeof (hc_info->hci_test));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_COUNT:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (isdigit(*val))
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra hc_info->hci_count = atoi(val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_EINVAL);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_INTERVAL:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (isdigit(*val))
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra hc_info->hci_interval = atoi(val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_EINVAL);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra case ILB_KEY_HC_TIMEOUT:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (isdigit(*val))
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra hc_info->hci_timeout = atoi(val);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra else
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (ILBADM_EINVAL);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra default: rc = ILBADM_INVAL_KEYWORD;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra break;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (rc);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra/*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * generic parsing function.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * parses "key=value[,value]" strings in "arg". keylist determines the
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * list of valid keys in the LHS. keycode determines interpretation and
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * storage in store
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * XXXms: looks like "key=value[,value]" violates spec. needs a fix
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrailbadm_status_t
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misrai_parse_optstring(char *arg, void *store, ilbadm_key_name_t *keylist,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int flags, int *count)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra{
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_status_t rc = ILBADM_OK;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra char *comma = NULL, *equals = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra char *key, *nextkey, *val;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_key_code_t keyword;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t is_value_list = flags & OPT_VALUE_LIST;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra boolean_t assign_seen = B_FALSE;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra int n;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra key = arg;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra n = 1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /*
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * Algorithm:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 1. find any commas indicating and seperating current value
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * from a following value
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 2. if we're expecting a list of values (seperated by commas)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * and have already seen the assignment, then
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * get the next "value"
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 3. else (we're looking at the first element of the RHS)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 4. find the '='
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 5. match the keyword to the list we were passed in
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra * 6. store the value.
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra while (key != NULL && *key != '\0') {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra comma = equals = NULL;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 2 */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra nextkey = strchr(key, (int)',');
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (nextkey != NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra comma = nextkey++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *comma = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 3a */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (is_value_list && assign_seen) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val = key;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 3b */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra } else {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 4 */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra equals = strchr(key, (int)'=');
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (equals == NULL) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err("%s: %s", key,
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_errstr(ILBADM_ASSIGNREQ));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra val = equals + 1;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *equals = '\0';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra assign_seen = B_TRUE;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 5 */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra keyword = i_match_key(key, keylist);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (keyword == ILB_KEY_BAD) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err(gettext("bad keyword %s"), key);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* 6 */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = i_store_val(val, store, keyword);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (rc != ILBADM_OK) {
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra ilbadm_err("%s: %s", key, ilbadm_errstr(rc));
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra /* Change to ILBADM_ILBERR to avoid more err msgs. */
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra rc = ILBADM_LIBERR;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra goto out;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra key = nextkey;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra n++;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra }
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misraout:
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (comma != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *comma = ',';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (equals != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *equals = '=';
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra if (count != NULL)
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra *count = n;
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra return (rc);
dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9Sangeeta Misra}