Annotation of embedaddon/dhcp/minires/ns_parse.c, revision 1.1.1.1.2.1
1.1 misho 1: /*
2: * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
3: * Copyright (c) 2004
4: * Copyright (c) 1996-2003 by Internet Software Consortium
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: *
18: * Internet Systems Consortium, Inc.
19: * 950 Charter Street
20: * Redwood City, CA 94063
21: * <info@isc.org>
22: * https://www.isc.org/
23: */
24:
25: #ifndef lint
1.1.1.1.2.1! misho 26: static const char rcsid[] = "$Id: ns_parse.c,v 1.1.1.1 2012/10/09 09:06:54 misho Exp $";
1.1 misho 27: #endif
28:
29: /* Import. */
30:
31: #include <sys/types.h>
32:
33: #include <netinet/in.h>
34: #include <sys/socket.h>
35:
36: #include <errno.h>
37: #include <string.h>
38:
39: #include "minires/minires.h"
40: #include "arpa/nameser.h"
41:
42: /* Forward. */
43:
44: static void setsection(ns_msg *msg, ns_sect sect);
45:
46: /* Macros. */
47:
48: /* Public. */
49:
50: /* These need to be in the same order as the nres.h:ns_flag enum. */
51: struct _ns_flagdata _ns_flagdata[16] = {
52: { 0x8000, 15 }, /* qr. */
53: { 0x7800, 11 }, /* opcode. */
54: { 0x0400, 10 }, /* aa. */
55: { 0x0200, 9 }, /* tc. */
56: { 0x0100, 8 }, /* rd. */
57: { 0x0080, 7 }, /* ra. */
58: { 0x0040, 6 }, /* z. */
59: { 0x0020, 5 }, /* ad. */
60: { 0x0010, 4 }, /* cd. */
61: { 0x000f, 0 }, /* rcode. */
62: { 0x0000, 0 }, /* expansion (1/6). */
63: { 0x0000, 0 }, /* expansion (2/6). */
64: { 0x0000, 0 }, /* expansion (3/6). */
65: { 0x0000, 0 }, /* expansion (4/6). */
66: { 0x0000, 0 }, /* expansion (5/6). */
67: { 0x0000, 0 }, /* expansion (6/6). */
68: };
69:
70: isc_result_t
71: ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count,
72: int *rc) {
73: const u_char *optr = ptr;
74:
75: for ((void)NULL; count > 0; count--) {
76: int b, rdlength;
77:
78: b = dn_skipname(ptr, eom);
79: if (b < 0)
80: return ISC_R_INCOMPLETE;
81: ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
82: if (section != ns_s_qd) {
83: if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
84: return ISC_R_INCOMPLETE;
85: ptr += NS_INT32SZ/*TTL*/;
86: rdlength = getUShort(ptr);
87: ptr += 2;
88: ptr += rdlength/*RData*/;
89: }
90: }
91: if (ptr > eom)
92: return ISC_R_INCOMPLETE;
93: if (rc)
94: *rc = ptr - optr;
95: return ISC_R_SUCCESS;
96: }
97:
98: isc_result_t
99: ns_initparse(const u_char *msg, unsigned msglen, ns_msg *handle) {
100: const u_char *eom = msg + msglen;
101: int i;
102:
103: memset(handle, 0x5e, sizeof *handle);
104: handle->_msg = msg;
105: handle->_eom = eom;
106: if (msg + NS_INT16SZ > eom)
107: return ISC_R_INCOMPLETE;
108: handle->_id = getUShort (msg);
109: msg += 2;
110: if (msg + NS_INT16SZ > eom)
111: return ISC_R_INCOMPLETE;
112: handle->_flags = getUShort (msg);
113: msg += 2;
114: for (i = 0; i < ns_s_max; i++) {
115: if (msg + NS_INT16SZ > eom)
116: return ISC_R_INCOMPLETE;
117: handle->_counts[i] = getUShort (msg);
118: msg += 2;
119: }
120: for (i = 0; i < ns_s_max; i++)
121: if (handle->_counts[i] == 0)
122: handle->_sections[i] = NULL;
123: else {
124: int b;
125: isc_result_t status =
126: ns_skiprr(msg, eom, (ns_sect)i,
127: handle->_counts[i], &b);
128:
129: if (status != ISC_R_SUCCESS)
130: return status;
131: handle->_sections[i] = msg;
132: msg += b;
133: }
134: if (msg != eom)
135: return ISC_R_INCOMPLETE;
136: setsection(handle, ns_s_max);
137: return ISC_R_SUCCESS;
138: }
139:
140: isc_result_t
141: ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
142: int b;
143: isc_result_t status;
144:
145: /* Make section right. */
1.1.1.1.2.1! misho 146: if (section >= ns_s_max)
1.1 misho 147: return ISC_R_NOTIMPLEMENTED;
148: if (section != handle->_sect)
149: setsection(handle, section);
150:
151: /* Make rrnum right. */
152: if (rrnum == -1)
153: rrnum = handle->_rrnum;
154: if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
155: return ISC_R_UNKNOWNATTRIBUTE;
156: if (rrnum < handle->_rrnum)
157: setsection(handle, section);
158: if (rrnum > handle->_rrnum) {
159: status = ns_skiprr(handle->_ptr, handle->_eom, section,
160: rrnum - handle->_rrnum, &b);
161:
162: if (status != ISC_R_SUCCESS)
163: return status;
164: handle->_ptr += b;
165: handle->_rrnum = rrnum;
166: }
167:
168: /* Do the parse. */
169: b = dn_expand(handle->_msg, handle->_eom,
170: handle->_ptr, rr->name, NS_MAXDNAME);
171: if (b < 0)
172: return ISC_R_FORMERR;
173: handle->_ptr += b;
174: if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
175: return ISC_R_INCOMPLETE;
176: rr->type = getUShort (handle->_ptr);
177: handle -> _ptr += 2;
178: rr->rr_class = getUShort (handle->_ptr);
179: handle -> _ptr += 2;
180: if (section == ns_s_qd) {
181: rr->ttl = 0;
182: rr->rdlength = 0;
183: rr->rdata = NULL;
184: } else {
185: if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
186: return ISC_R_INCOMPLETE;
187: rr->ttl = getULong (handle->_ptr);
188: handle -> _ptr += 4;
189: rr->rdlength = getUShort (handle->_ptr);
190: handle -> _ptr += 2;
191: if (handle->_ptr + rr->rdlength > handle->_eom)
192: return ISC_R_INCOMPLETE;
193: rr->rdata = handle->_ptr;
194: handle->_ptr += rr->rdlength;
195: }
196: if (++handle->_rrnum > handle->_counts[(int)section])
197: setsection(handle, (ns_sect)((int)section + 1));
198:
199: /* All done. */
200: return ISC_R_SUCCESS;
201: }
202:
203: /* Private. */
204:
205: static void
206: setsection(ns_msg *msg, ns_sect sect) {
207: msg->_sect = sect;
208: if (sect == ns_s_max) {
209: msg->_rrnum = -1;
210: msg->_ptr = NULL;
211: } else {
212: msg->_rrnum = 0;
213: msg->_ptr = msg->_sections[(int)sect];
214: }
215: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>