1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate /* 25*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 26*0Sstevel@tonic-gate * Use is subject to license terms. 27*0Sstevel@tonic-gate */ 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <stdio.h> 30*0Sstevel@tonic-gate #include <stdlib.h> 31*0Sstevel@tonic-gate #include <unistd.h> 32*0Sstevel@tonic-gate #include <stdarg.h> 33*0Sstevel@tonic-gate #include <sys/types.h> 34*0Sstevel@tonic-gate #include <errno.h> 35*0Sstevel@tonic-gate #include <assert.h> 36*0Sstevel@tonic-gate #include <string.h> 37*0Sstevel@tonic-gate #include <sys/syslog.h> 38*0Sstevel@tonic-gate #include <sys/socket.h> 39*0Sstevel@tonic-gate #include <netinet/in.h> 40*0Sstevel@tonic-gate #include <arpa/inet.h> 41*0Sstevel@tonic-gate #include <netinet/dhcp.h> 42*0Sstevel@tonic-gate #include "hash.h" 43*0Sstevel@tonic-gate #include "dhcpd.h" 44*0Sstevel@tonic-gate #include "per_dnet.h" 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate /* 47*0Sstevel@tonic-gate * This file contains the code which creates, manipulates, and frees encode 48*0Sstevel@tonic-gate * structures. 49*0Sstevel@tonic-gate */ 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate /* 52*0Sstevel@tonic-gate * Free an individual encode structure, including data. 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate void 55*0Sstevel@tonic-gate free_encode(ENCODE *ecp) 56*0Sstevel@tonic-gate { 57*0Sstevel@tonic-gate if (ecp != NULL) { 58*0Sstevel@tonic-gate if (ecp->data) 59*0Sstevel@tonic-gate free(ecp->data); 60*0Sstevel@tonic-gate free(ecp); 61*0Sstevel@tonic-gate } 62*0Sstevel@tonic-gate } 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate /* 65*0Sstevel@tonic-gate * Dump an entire encode list, including data. 66*0Sstevel@tonic-gate */ 67*0Sstevel@tonic-gate void 68*0Sstevel@tonic-gate free_encode_list(ENCODE *ecp) 69*0Sstevel@tonic-gate { 70*0Sstevel@tonic-gate ENCODE *tmp; 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate while (ecp != NULL) { 73*0Sstevel@tonic-gate tmp = ecp; 74*0Sstevel@tonic-gate ecp = ecp->next; 75*0Sstevel@tonic-gate free_encode(tmp); 76*0Sstevel@tonic-gate } 77*0Sstevel@tonic-gate } 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate /* 80*0Sstevel@tonic-gate * Allocate an ENCODE structure, and fill it in with the passed data. 81*0Sstevel@tonic-gate * 82*0Sstevel@tonic-gate * Doesn't copy data if copy_flag is not set. 83*0Sstevel@tonic-gate * 84*0Sstevel@tonic-gate * Returns: ptr for success. Doesn't return if a failure occurs. 85*0Sstevel@tonic-gate */ 86*0Sstevel@tonic-gate ENCODE * 87*0Sstevel@tonic-gate make_encode(uchar_t cat, ushort_t code, uchar_t len, void *data, 88*0Sstevel@tonic-gate int copy_flag) 89*0Sstevel@tonic-gate { 90*0Sstevel@tonic-gate ENCODE *ecp; 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate ecp = (ENCODE *)smalloc(sizeof (ENCODE)); 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate ecp->category = cat; 95*0Sstevel@tonic-gate ecp->code = code; 96*0Sstevel@tonic-gate ecp->len = len; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate if (data != NULL && len != 0) { 99*0Sstevel@tonic-gate if (copy_flag == ENC_COPY) { 100*0Sstevel@tonic-gate ecp->data = (uchar_t *)smalloc(len); 101*0Sstevel@tonic-gate (void) memcpy(ecp->data, data, len); 102*0Sstevel@tonic-gate } else 103*0Sstevel@tonic-gate ecp->data = data; 104*0Sstevel@tonic-gate } 105*0Sstevel@tonic-gate return (ecp); 106*0Sstevel@tonic-gate } 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate /* 109*0Sstevel@tonic-gate * Find a specific code in the ENCODE list. Doesn't consider class. 110*0Sstevel@tonic-gate * 111*0Sstevel@tonic-gate * Returns: ptr if successful, NULL otherwise. 112*0Sstevel@tonic-gate */ 113*0Sstevel@tonic-gate ENCODE * 114*0Sstevel@tonic-gate find_encode(ENCODE *eclp, uchar_t cat, ushort_t code) 115*0Sstevel@tonic-gate { 116*0Sstevel@tonic-gate for (; eclp != NULL; eclp = eclp->next) { 117*0Sstevel@tonic-gate if (eclp->category == cat && eclp->code == code) 118*0Sstevel@tonic-gate return (eclp); 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate return (NULL); 121*0Sstevel@tonic-gate } 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * Duplicate the passed encode structure. 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate ENCODE * 127*0Sstevel@tonic-gate dup_encode(ENCODE *ecp) 128*0Sstevel@tonic-gate { 129*0Sstevel@tonic-gate assert(ecp != NULL); 130*0Sstevel@tonic-gate return (make_encode(ecp->category, ecp->code, ecp->len, ecp->data, 131*0Sstevel@tonic-gate ENC_COPY)); 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate /* 135*0Sstevel@tonic-gate * Duplicate an encode list. May be called with NULL as a convenience. 136*0Sstevel@tonic-gate */ 137*0Sstevel@tonic-gate ENCODE * 138*0Sstevel@tonic-gate dup_encode_list(ENCODE *ecp) 139*0Sstevel@tonic-gate { 140*0Sstevel@tonic-gate ENCODE *pp, *np, *headp; 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate if (ecp == NULL) 143*0Sstevel@tonic-gate return (NULL); 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate /* 146*0Sstevel@tonic-gate * Note: pp/np are used as placeholders in parallel list. 147*0Sstevel@tonic-gate */ 148*0Sstevel@tonic-gate pp = headp = NULL; 149*0Sstevel@tonic-gate for (; ecp != NULL; ecp = ecp->next) { 150*0Sstevel@tonic-gate np = dup_encode(ecp); 151*0Sstevel@tonic-gate if (pp == NULL) { 152*0Sstevel@tonic-gate headp = np; 153*0Sstevel@tonic-gate np->prev = NULL; 154*0Sstevel@tonic-gate } else { 155*0Sstevel@tonic-gate pp->next = np; 156*0Sstevel@tonic-gate np->prev = pp; 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate pp = np; 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate return (headp); 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate /* 164*0Sstevel@tonic-gate * Given two ENCODE lists, produce NEW ENCODE list by "OR"ing the first 165*0Sstevel@tonic-gate * encode list with the second. Note that the settings in the second encode 166*0Sstevel@tonic-gate * list override any identical code settings in the first encode list. 167*0Sstevel@tonic-gate * 168*0Sstevel@tonic-gate * The primary list is copied if flags argument is ENC_COPY. Class is not 169*0Sstevel@tonic-gate * considered. 170*0Sstevel@tonic-gate * 171*0Sstevel@tonic-gate * Returns a ptr to the merged list for success, NULL ptr otherwise. 172*0Sstevel@tonic-gate */ 173*0Sstevel@tonic-gate ENCODE * 174*0Sstevel@tonic-gate combine_encodes(ENCODE *first_ecp, ENCODE *second_ecp, int flags) 175*0Sstevel@tonic-gate { 176*0Sstevel@tonic-gate ENCODE *ep; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate if (first_ecp != NULL) { 179*0Sstevel@tonic-gate if (flags == ENC_COPY) 180*0Sstevel@tonic-gate first_ecp = dup_encode_list(first_ecp); 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate for (ep = second_ecp; ep != NULL; ep = ep->next) 183*0Sstevel@tonic-gate replace_encode(&first_ecp, ep, ENC_COPY); 184*0Sstevel@tonic-gate } else { 185*0Sstevel@tonic-gate first_ecp = dup_encode_list(second_ecp); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate return (first_ecp); 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate /* 191*0Sstevel@tonic-gate * Replace/add the encode matching the code value of the second ENCODE 192*0Sstevel@tonic-gate * parameter in the list represented by the first ENCODE parameter. 193*0Sstevel@tonic-gate */ 194*0Sstevel@tonic-gate void 195*0Sstevel@tonic-gate replace_encode(ENCODE **elistpp, ENCODE *rp, int flags) 196*0Sstevel@tonic-gate { 197*0Sstevel@tonic-gate ENCODE *wp; 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate assert(elistpp != NULL && rp != NULL); 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate if (flags == ENC_COPY) 202*0Sstevel@tonic-gate rp = dup_encode(rp); 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate if (*elistpp == NULL) { 205*0Sstevel@tonic-gate *elistpp = rp; 206*0Sstevel@tonic-gate return; 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate wp = find_encode(*elistpp, rp->category, rp->code); 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate if (wp == NULL) { 211*0Sstevel@tonic-gate rp->next = *elistpp; 212*0Sstevel@tonic-gate rp->next->prev = rp; 213*0Sstevel@tonic-gate *elistpp = rp; 214*0Sstevel@tonic-gate rp->prev = NULL; 215*0Sstevel@tonic-gate } else { 216*0Sstevel@tonic-gate if (wp->prev == NULL) { 217*0Sstevel@tonic-gate rp->next = wp->next; 218*0Sstevel@tonic-gate *elistpp = rp; 219*0Sstevel@tonic-gate rp->prev = NULL; 220*0Sstevel@tonic-gate } else { 221*0Sstevel@tonic-gate rp->next = wp->next; 222*0Sstevel@tonic-gate rp->prev = wp->prev; 223*0Sstevel@tonic-gate wp->prev->next = rp; 224*0Sstevel@tonic-gate } 225*0Sstevel@tonic-gate if (wp->next != NULL) 226*0Sstevel@tonic-gate wp->next->prev = rp; 227*0Sstevel@tonic-gate free_encode(wp); 228*0Sstevel@tonic-gate } 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate /* 232*0Sstevel@tonic-gate * Given a MACRO and a class name, return the ENCODE list for 233*0Sstevel@tonic-gate * that class name, or null if a ENCODE list by that class doesn't exist. 234*0Sstevel@tonic-gate */ 235*0Sstevel@tonic-gate ENCODE * 236*0Sstevel@tonic-gate vendor_encodes(MACRO *mp, char *class) 237*0Sstevel@tonic-gate { 238*0Sstevel@tonic-gate VNDLIST **tvpp; 239*0Sstevel@tonic-gate int i; 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate assert(mp != NULL && class != NULL); 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate for (tvpp = mp->list, i = 0; tvpp != NULL && i < mp->classes; i++) { 244*0Sstevel@tonic-gate if (strcmp(tvpp[i]->class, class) == 0) 245*0Sstevel@tonic-gate return (tvpp[i]->head); 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate return (NULL); 248*0Sstevel@tonic-gate } 249