]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/BsdSocketLib/res_mkupdate.c
2 * Copyright (c) 1996 by Internet Software Consortium.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
19 * Portions copyright (c) 1999, 2000
21 * All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
37 * This product includes software developed by Intel Corporation and
40 * 4. Neither the name of Intel Corporation or its contributors may be
41 * used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''
45 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE
48 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
54 * THE POSSIBILITY OF SUCH DAMAGE.
59 * Based on the Dynamic DNS reference implementation by Viraj Bais
60 * <viraj_bais@ccm.fm.intel.com>
63 #if !defined(lint) && !defined(SABER)
64 static char rcsid
[] = "$Id: res_mkupdate.c,v 1.1.1.1 2003/11/19 01:51:38 kyu3 Exp $";
67 #include <sys/types.h>
68 #include <sys/param.h>
70 #include <netinet/in.h>
71 #include <arpa/nameser.h>
72 #include <arpa/inet.h>
84 #include "res_config.h"
86 static int getnum_str(u_char
**, u_char
*);
87 static int getword_str(char *, int, u_char
**, u_char
*);
89 #define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2);
92 * Form update packets.
93 * Returns the size of the resulting packet if no error
95 * returns -1 if error in reading a word/number in rdata
96 * portion for update packets
97 * -2 if length of buffer passed is insufficient
98 * -3 if zone section is not the first section in
99 * the linked list, or section order has a problem
100 * -4 on a number overflow
101 * -5 unknown operation or no records
104 res_mkupdate(ns_updrec
*rrecp_in
, u_char
*buf
, int buflen
) {
105 ns_updrec
*rrecp_start
= rrecp_in
;
107 u_char
*cp
, *sp1
, *sp2
, *startp
, *endp
;
108 int n
, i
, soanum
, multiline
;
112 int section
, numrrs
= 0, counts
[ns_s_max
];
113 u_int16_t rtype
, rclass
;
115 u_char
*dnptrs
[20], **dpp
, **lastdnptr
;
117 if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1) {
118 h_errno
= NETDB_INTERNAL
;
123 * Initialize header fields.
125 if ((buf
== NULL
) || (buflen
< HFIXEDSZ
))
127 memset(buf
, 0, HFIXEDSZ
);
129 hp
->id
= htons(++_res
.id
);
130 hp
->opcode
= ns_o_update
;
132 sp1
= buf
+ 2*INT16SZ
; /* save pointer to zocount */
138 lastdnptr
= dnptrs
+ sizeof dnptrs
/ sizeof dnptrs
[0];
140 if (rrecp_start
== NULL
)
142 else if (rrecp_start
->r_section
!= S_ZONE
)
145 memset(counts
, 0, sizeof counts
);
146 for (rrecp
= rrecp_start
; rrecp
; rrecp
= rrecp
->r_grpnext
) {
148 section
= rrecp
->r_section
;
149 if (section
< 0 || section
>= ns_s_max
)
152 for (i
= section
+ 1; i
< ns_s_max
; i
++)
155 rtype
= rrecp
->r_type
;
156 rclass
= rrecp
->r_class
;
158 /* overload class and type */
159 if (section
== S_PREREQ
) {
161 switch (rrecp
->r_opcode
) {
177 if (rrecp
->r_size
== 0)
182 "res_mkupdate: incorrect opcode: %d\n",
187 } else if (section
== S_UPDATE
) {
188 switch (rrecp
->r_opcode
) {
190 rclass
= rrecp
->r_size
== 0 ? C_ANY
: C_NONE
;
196 "res_mkupdate: incorrect opcode: %d\n",
204 * XXX appending default domain to owner name is omitted,
205 * fqdn must be provided
207 if ((n
= dn_comp(rrecp
->r_dname
, cp
, buflen
, dnptrs
,
211 ShrinkBuffer(n
+ 2*INT16SZ
);
213 PUTSHORT(rclass
, cp
);
214 if (section
== S_ZONE
) {
215 if (numrrs
!= 1 || rrecp
->r_type
!= T_SOA
)
219 ShrinkBuffer(INT32SZ
+ INT16SZ
);
221 sp2
= cp
; /* save pointer to length byte */
223 if (rrecp
->r_size
== 0) {
224 if (section
== S_UPDATE
&& rclass
!= C_ANY
)
231 startp
= rrecp
->r_data
;
232 endp
= startp
+ rrecp
->r_size
- 1;
233 /* XXX this should be done centrally. */
234 switch (rrecp
->r_type
) {
236 if (!getword_str(buf2
, sizeof buf2
, &startp
, endp
))
238 if (!inet_aton(buf2
, &ina
))
240 n1
= ntohl(ina
.s_addr
);
241 ShrinkBuffer(INT32SZ
);
250 if (!getword_str(buf2
, sizeof buf2
, &startp
, endp
))
252 n
= dn_comp(buf2
, cp
, buflen
, dnptrs
, lastdnptr
);
261 for (i
= 0; i
< 2; i
++) {
262 if (!getword_str(buf2
, sizeof buf2
, &startp
,
265 n
= dn_comp(buf2
, cp
, buflen
,
272 if (rrecp
->r_type
== T_SOA
) {
273 ShrinkBuffer(5 * INT32SZ
);
274 while (isspace(*startp
) || !*startp
)
276 if (*startp
== '(') {
281 /* serial, refresh, retry, expire, minimum */
282 for (i
= 0; i
< 5; i
++) {
283 soanum
= getnum_str(&startp
, endp
);
289 while (isspace(*startp
) || !*startp
)
299 n
= getnum_str(&startp
, endp
);
303 ShrinkBuffer(INT16SZ
);
304 if (!getword_str(buf2
, sizeof buf2
, &startp
, endp
))
306 n
= dn_comp(buf2
, cp
, buflen
, dnptrs
, lastdnptr
);
313 n
= getnum_str(&startp
, endp
);
317 ShrinkBuffer(INT16SZ
);
318 for (i
= 0; i
< 2; i
++) {
319 if (!getword_str(buf2
, sizeof buf2
, &startp
,
322 n
= dn_comp(buf2
, cp
, buflen
, dnptrs
,
337 /* XXX - more fine tuning needed here */
338 ShrinkBuffer(rrecp
->r_size
);
339 memcpy(cp
, rrecp
->r_data
, rrecp
->r_size
);
345 n
= (u_int16_t
)((cp
- sp2
) - INT16SZ
);
349 hp
->qdcount
= htons(counts
[0]);
350 hp
->ancount
= htons(counts
[1]);
351 hp
->nscount
= htons(counts
[2]);
352 hp
->arcount
= htons(counts
[3]);
353 return ((int)(cp
- buf
));
357 * Get a whitespace delimited word from a string (not file)
358 * into buf. modify the start pointer to point after the
359 * word in the string.
362 getword_str(char *buf
, int size
, u_char
**startpp
, u_char
*endp
) {
366 for (cp
= buf
; *startpp
<= endp
; ) {
368 if (isspace(c
) || c
== '\0') {
369 if (cp
!= buf
) /* trailing whitespace */
371 else { /* leading whitespace */
377 if (cp
>= buf
+size
-1)
386 * Get a whitespace delimited number from a string (not file) into buf
387 * update the start pointer to point after the number in the string.
390 getnum_str(u_char
**startpp
, u_char
*endp
) {
396 for (n
= 0; *startpp
<= endp
; ) {
398 if (isspace(c
) || c
== '\0') {
399 if (seendigit
) /* trailing whitespace */
401 else { /* leading whitespace */
407 while ((*startpp
<= endp
) &&
408 ((c
= **startpp
) != '\n'))
415 if (c
== ')' && seendigit
) {
422 n
= n
* 10 + (c
- '0');
429 * Allocate a resource record buffer & save rr info.
432 res_mkupdrec(int section
, const char *dname
,
433 u_int
class, u_int type
, u_long ttl
) {
434 ns_updrec
*rrecp
= (ns_updrec
*)calloc(1, sizeof(ns_updrec
));
436 if (!rrecp
|| !(rrecp
->r_dname
= strdup(dname
)))
438 rrecp
->r_class
= (u_int16_t
)class;
439 rrecp
->r_type
= (u_int16_t
)type
;
440 rrecp
->r_ttl
= (u_int32_t
)ttl
;
441 rrecp
->r_section
= (u_int8_t
)section
;
446 * Free a resource record buffer created by res_mkupdrec.
449 res_freeupdrec(ns_updrec
*rrecp
) {
450 /* Note: freeing r_dp is the caller's responsibility. */
451 if (rrecp
->r_dname
!= NULL
)
452 free(rrecp
->r_dname
);