]> git.proxmox.com Git - mirror_edk2.git/blob - StdLib/BsdSocketLib/ns_parse.c
Add Socket Libraries.
[mirror_edk2.git] / StdLib / BsdSocketLib / ns_parse.c
1 /*
2 * Copyright (c) 1996 by Internet Software Consortium.
3 *
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.
7 *
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
15 * SOFTWARE.
16 */
17
18 /*
19 * Portions copyright (c) 1999, 2000
20 * Intel Corporation.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 *
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.
33 *
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 *
37 * This product includes software developed by Intel Corporation and
38 * its contributors.
39 *
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.
43 *
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.
55 *
56 */
57
58 #ifndef lint
59 static char rcsid[] = "$Id: ns_parse.c,v 1.1.1.1 2003/11/19 01:51:33 kyu3 Exp $";
60 #endif
61
62 #include <sys/types.h>
63
64 #include <netinet/in.h>
65 #include <arpa/nameser.h>
66
67 #include <errno.h>
68 #include <resolv.h>
69 #include <string.h>
70
71 /* These need to be in the same order as the nres.h:ns_flag enum. */
72 struct _ns_flagdata _ns_flagdata[16] = {
73 { 0x8000, 15 }, /* qr. */
74 { 0x7800, 11 }, /* opcode. */
75 { 0x0400, 10 }, /* aa. */
76 { 0x0200, 9 }, /* tc. */
77 { 0x0100, 8 }, /* rd. */
78 { 0x0080, 7 }, /* ra. */
79 { 0x0040, 6 }, /* z. */
80 { 0x0020, 5 }, /* ad. */
81 { 0x0010, 4 }, /* cd. */
82 { 0x000f, 0 }, /* rcode. */
83 { 0x0000, 0 }, /* expansion (1/6). */
84 { 0x0000, 0 }, /* expansion (2/6). */
85 { 0x0000, 0 }, /* expansion (3/6). */
86 { 0x0000, 0 }, /* expansion (4/6). */
87 { 0x0000, 0 }, /* expansion (5/6). */
88 { 0x0000, 0 }, /* expansion (6/6). */
89 };
90
91 static int
92 skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
93 const u_char *optr = ptr;
94
95 for ((void)NULL; count > 0; count--) {
96 int b, rdlength;
97
98 b = dn_skipname(ptr, eom);
99 if (b < 0)
100 goto emsgsize;
101 ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
102 if (section != ns_s_qd) {
103 if (ptr + NS_INT32SZ > eom)
104 goto emsgsize;
105 ptr += NS_INT32SZ/*TTL*/;
106 if (ptr + NS_INT16SZ > eom)
107 goto emsgsize;
108 NS_GET16(rdlength, ptr);
109 ptr += rdlength/*RData*/;
110 }
111 }
112 if (ptr > eom)
113 goto emsgsize;
114 return ((int)(ptr - optr));
115 emsgsize:
116 errno = EMSGSIZE;
117 return (-1);
118 }
119
120 int
121 ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
122 const u_char *eom = msg + msglen;
123 int i;
124
125 memset(handle, 0x5e, sizeof *handle);
126 handle->_msg = msg;
127 handle->_eom = eom;
128 if (msg + NS_INT16SZ > eom)
129 goto emsgsize;
130 NS_GET16(handle->_id, msg);
131 if (msg + NS_INT16SZ > eom)
132 goto emsgsize;
133 NS_GET16(handle->_flags, msg);
134 for (i = 0; i < ns_s_max; i++) {
135 if (msg + NS_INT16SZ > eom)
136 goto emsgsize;
137 NS_GET16(handle->_counts[i], msg);
138 }
139 for (i = 0; i < ns_s_max; i++)
140 if (handle->_counts[i] == 0)
141 handle->_sections[i] = NULL;
142 else {
143 int b = skiprr(msg, eom, (ns_sect)i,
144 handle->_counts[i]);
145
146 if (b < 0)
147 return (-1);
148 handle->_sections[i] = msg;
149 msg += b;
150 }
151 if (msg != eom)
152 goto emsgsize;
153 handle->_sect = ns_s_max;
154 handle->_rrnum = -1;
155 handle->_msg_ptr = NULL;
156 return (0);
157 emsgsize:
158 errno = EMSGSIZE;
159 return (-1);
160 }
161
162 int
163 ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
164 int b;
165
166 /* Make section right. */
167 if (section < 0 || section >= ns_s_max)
168 goto enodev;
169 if ((int)section != (int)handle->_sect) {
170 handle->_sect = section;
171 handle->_rrnum = 0;
172 handle->_msg_ptr = handle->_sections[(int)section];
173 }
174
175 /* Make rrnum right. */
176 if (rrnum == -1)
177 rrnum = handle->_rrnum;
178 if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
179 goto enodev;
180 if (rrnum < handle->_rrnum) {
181 handle->_rrnum = 0;
182 handle->_msg_ptr = handle->_sections[(int)section];
183 }
184
185 b = skiprr(handle->_msg, handle->_eom, section,
186 rrnum - handle->_rrnum);
187 if (b < 0)
188 return (-1);
189 handle->_msg_ptr += b;
190 handle->_rrnum = rrnum;
191
192 /* Do the parse. */
193 b = dn_expand(handle->_msg, handle->_eom,
194 handle->_msg_ptr, rr->name, NS_MAXDNAME);
195 if (b < 0)
196 return (-1);
197 handle->_msg_ptr += b;
198 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)
199 goto emsgsize;
200 NS_GET16(rr->type, handle->_msg_ptr);
201 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)
202 goto emsgsize;
203 NS_GET16(rr->rr_class, handle->_msg_ptr);
204 if (section == ns_s_qd) {
205 rr->ttl = 0;
206 rr->rdlength = 0;
207 rr->rdata = NULL;
208 } else {
209 if (handle->_msg_ptr + NS_INT32SZ > handle->_eom)
210 goto emsgsize;
211 NS_GET32(rr->ttl, handle->_msg_ptr);
212 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)
213 goto emsgsize;
214 NS_GET16(rr->rdlength, handle->_msg_ptr);
215 if (handle->_msg_ptr + rr->rdlength > handle->_eom)
216 goto emsgsize;
217 rr->rdata = handle->_msg_ptr;
218 handle->_msg_ptr += rr->rdlength;
219 }
220 handle->_rrnum++;
221
222 /* All done. */
223 return (0);
224 enodev:
225 errno = ENODEV;
226 return (-1);
227 emsgsize:
228 errno = EMSGSIZE;
229 return (-1);
230 }