]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/BsdSocketLib/ns_parse.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / StdLib / BsdSocketLib / ns_parse.c
CommitLineData
1ba76449 1/** @file\r
2 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
3 This program and the accompanying materials are licensed and made available under\r
4 the terms and conditions of the BSD License that accompanies this distribution.\r
5 The full text of the license may be found at\r
6 http://opensource.org/licenses/bsd-license.php.\r
7\r
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
d7ce7006 10\r
d7ce7006 11 * Portions copyright (c) 1999, 2000\r
12 * Intel Corporation.\r
13 * All rights reserved.\r
14 * \r
15 * Redistribution and use in source and binary forms, with or without\r
16 * modification, are permitted provided that the following conditions\r
17 * are met:\r
18 * \r
19 * 1. Redistributions of source code must retain the above copyright\r
20 * notice, this list of conditions and the following disclaimer.\r
21 * \r
22 * 2. Redistributions in binary form must reproduce the above copyright\r
23 * notice, this list of conditions and the following disclaimer in the\r
24 * documentation and/or other materials provided with the distribution.\r
25 * \r
26 * 3. All advertising materials mentioning features or use of this software\r
27 * must display the following acknowledgement:\r
28 * \r
29 * This product includes software developed by Intel Corporation and\r
30 * its contributors.\r
31 * \r
32 * 4. Neither the name of Intel Corporation or its contributors may be\r
33 * used to endorse or promote products derived from this software\r
34 * without specific prior written permission.\r
35 * \r
36 * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
37 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
39 * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
40 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
43 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
44 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
46 * THE POSSIBILITY OF SUCH DAMAGE.\r
47 * \r
1ba76449 48 * Copyright (c) 1996 by Internet Software Consortium.\r
49 *\r
50 * Permission to use, copy, modify, and distribute this software for any\r
51 * purpose with or without fee is hereby granted, provided that the above\r
52 * copyright notice and this permission notice appear in all copies.\r
53 *\r
54 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
55 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
56 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
57 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
58 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
59 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
60 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
61 * SOFTWARE.\r
62**/\r
d7ce7006 63\r
d7ce7006 64#include <sys/types.h>\r
65\r
66#include <netinet/in.h>\r
67#include <arpa/nameser.h>\r
68\r
69#include <errno.h>\r
70#include <resolv.h>\r
71#include <string.h>\r
72\r
73/* These need to be in the same order as the nres.h:ns_flag enum. */\r
74struct _ns_flagdata _ns_flagdata[16] = {\r
75 { 0x8000, 15 }, /* qr. */\r
76 { 0x7800, 11 }, /* opcode. */\r
77 { 0x0400, 10 }, /* aa. */\r
78 { 0x0200, 9 }, /* tc. */\r
79 { 0x0100, 8 }, /* rd. */\r
80 { 0x0080, 7 }, /* ra. */\r
81 { 0x0040, 6 }, /* z. */\r
82 { 0x0020, 5 }, /* ad. */\r
83 { 0x0010, 4 }, /* cd. */\r
84 { 0x000f, 0 }, /* rcode. */\r
85 { 0x0000, 0 }, /* expansion (1/6). */\r
86 { 0x0000, 0 }, /* expansion (2/6). */\r
87 { 0x0000, 0 }, /* expansion (3/6). */\r
88 { 0x0000, 0 }, /* expansion (4/6). */\r
89 { 0x0000, 0 }, /* expansion (5/6). */\r
90 { 0x0000, 0 }, /* expansion (6/6). */\r
91};\r
92\r
93static int\r
94skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {\r
95 const u_char *optr = ptr;\r
96\r
97 for ((void)NULL; count > 0; count--) {\r
98 int b, rdlength;\r
99\r
100 b = dn_skipname(ptr, eom);\r
101 if (b < 0)\r
102 goto emsgsize;\r
103 ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;\r
104 if (section != ns_s_qd) {\r
105 if (ptr + NS_INT32SZ > eom)\r
106 goto emsgsize;\r
107 ptr += NS_INT32SZ/*TTL*/;\r
108 if (ptr + NS_INT16SZ > eom)\r
109 goto emsgsize;\r
110 NS_GET16(rdlength, ptr);\r
111 ptr += rdlength/*RData*/;\r
112 }\r
113 }\r
114 if (ptr > eom)\r
115 goto emsgsize;\r
116 return ((int)(ptr - optr));\r
117 emsgsize:\r
118 errno = EMSGSIZE;\r
119 return (-1);\r
120}\r
121\r
122int\r
123ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {\r
124 const u_char *eom = msg + msglen;\r
125 int i;\r
126\r
127 memset(handle, 0x5e, sizeof *handle);\r
128 handle->_msg = msg;\r
129 handle->_eom = eom;\r
130 if (msg + NS_INT16SZ > eom)\r
131 goto emsgsize;\r
132 NS_GET16(handle->_id, msg);\r
133 if (msg + NS_INT16SZ > eom)\r
134 goto emsgsize;\r
135 NS_GET16(handle->_flags, msg);\r
136 for (i = 0; i < ns_s_max; i++) {\r
137 if (msg + NS_INT16SZ > eom)\r
138 goto emsgsize;\r
139 NS_GET16(handle->_counts[i], msg);\r
140 }\r
141 for (i = 0; i < ns_s_max; i++)\r
142 if (handle->_counts[i] == 0)\r
143 handle->_sections[i] = NULL;\r
144 else {\r
145 int b = skiprr(msg, eom, (ns_sect)i,\r
146 handle->_counts[i]);\r
147\r
148 if (b < 0)\r
149 return (-1);\r
150 handle->_sections[i] = msg;\r
151 msg += b;\r
152 }\r
153 if (msg != eom)\r
154 goto emsgsize;\r
155 handle->_sect = ns_s_max;\r
156 handle->_rrnum = -1;\r
157 handle->_msg_ptr = NULL;\r
158 return (0);\r
159 emsgsize:\r
160 errno = EMSGSIZE;\r
161 return (-1);\r
162}\r
163\r
164int\r
165ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {\r
166 int b;\r
167\r
168 /* Make section right. */\r
1ba76449 169 if ((unsigned int)section >= ns_s_max)\r
d7ce7006 170 goto enodev;\r
171 if ((int)section != (int)handle->_sect) {\r
172 handle->_sect = section;\r
173 handle->_rrnum = 0;\r
174 handle->_msg_ptr = handle->_sections[(int)section];\r
175 }\r
176\r
177 /* Make rrnum right. */\r
178 if (rrnum == -1)\r
179 rrnum = handle->_rrnum;\r
180 if (rrnum < 0 || rrnum >= handle->_counts[(int)section])\r
181 goto enodev;\r
182 if (rrnum < handle->_rrnum) {\r
183 handle->_rrnum = 0;\r
184 handle->_msg_ptr = handle->_sections[(int)section];\r
185 }\r
186 \r
187 b = skiprr(handle->_msg, handle->_eom, section,\r
188 rrnum - handle->_rrnum);\r
189 if (b < 0)\r
190 return (-1);\r
191 handle->_msg_ptr += b;\r
192 handle->_rrnum = rrnum;\r
193\r
194 /* Do the parse. */\r
195 b = dn_expand(handle->_msg, handle->_eom,\r
196 handle->_msg_ptr, rr->name, NS_MAXDNAME);\r
197 if (b < 0)\r
198 return (-1);\r
199 handle->_msg_ptr += b;\r
200 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)\r
201 goto emsgsize;\r
202 NS_GET16(rr->type, handle->_msg_ptr);\r
203 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)\r
204 goto emsgsize;\r
205 NS_GET16(rr->rr_class, handle->_msg_ptr);\r
206 if (section == ns_s_qd) {\r
207 rr->ttl = 0;\r
208 rr->rdlength = 0;\r
209 rr->rdata = NULL;\r
210 } else {\r
211 if (handle->_msg_ptr + NS_INT32SZ > handle->_eom)\r
212 goto emsgsize;\r
213 NS_GET32(rr->ttl, handle->_msg_ptr);\r
214 if (handle->_msg_ptr + NS_INT16SZ > handle->_eom)\r
215 goto emsgsize;\r
216 NS_GET16(rr->rdlength, handle->_msg_ptr);\r
217 if (handle->_msg_ptr + rr->rdlength > handle->_eom)\r
218 goto emsgsize;\r
219 rr->rdata = handle->_msg_ptr;\r
220 handle->_msg_ptr += rr->rdlength;\r
221 }\r
222 handle->_rrnum++;\r
223\r
224 /* All done. */\r
225 return (0);\r
226 enodev:\r
227 errno = ENODEV;\r
228 return (-1);\r
229 emsgsize:\r
230 errno = EMSGSIZE;\r
231 return (-1);\r
232}\r