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
free_encode(ENCODE * ecp)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
free_encode_list(ENCODE * ecp)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 *
make_encode(uchar_t cat,ushort_t code,uchar_t len,void * data,int copy_flag)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 *
find_encode(ENCODE * eclp,uchar_t cat,ushort_t code)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 *
dup_encode(ENCODE * ecp)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 *
dup_encode_list(ENCODE * ecp)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 *
combine_encodes(ENCODE * first_ecp,ENCODE * second_ecp,int flags)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
replace_encode(ENCODE ** elistpp,ENCODE * rp,int flags)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 *
vendor_encodes(MACRO * mp,char * class)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