1pub const NS_MAXDNAME_V: usize = 1025;
7const NS_INT16SZ_V: usize = 2;
8const NS_INT32SZ_V: usize = 4;
9const NS_S_MAX_V: usize = 4;
10
11#[repr(C)]
12pub struct NsMsg {
13 pub _msg: *const u8,
14 pub _eom: *const u8,
15 pub _id: u16,
16 pub _flags: u16,
17 pub _counts: [u16; NS_S_MAX_V],
18 pub _sections: [*const u8; NS_S_MAX_V],
19 pub _sect: c_int,
20 pub _rrnum: c_int,
21 pub _msg_ptr: *const u8,
22}
23
24#[repr(C)]
25pub struct NsRr {
26 pub name: [c_char; NS_MAXDNAME_V],
27 pub type_: u16,
28 pub rr_class: u16,
29 pub ttl: u32,
30 pub rdlength: u16,
31 __pad: u16,
32 pub rdata: *const u8,
33}
34
35#[no_mangle]
36pub static _ns_flagdata: [[c_int; 2]; 16] = [
37 [0x8000, 15],
38 [0x7800, 11],
39 [0x0400, 10],
40 [0x0200, 9],
41 [0x0100, 8],
42 [0x0080, 7],
43 [0x0040, 6],
44 [0x0020, 5],
45 [0x0010, 4],
46 [0x000f, 0],
47 [0x0000, 0],
48 [0x0000, 0],
49 [0x0000, 0],
50 [0x0000, 0],
51 [0x0000, 0],
52 [0x0000, 0],
53];
54
55unsafe fn ns_skiprr_inner(ptr: *const u8, eom: *const u8, section: c_int, mut count: c_int) -> c_int {
56 let mut p = ptr;
57 while count > 0 {
58 count -= 1;
59 let r = dn_skipname(p, eom);
60 if r < 0 { return -1; }
61 if r as usize + 2 * NS_INT16SZ_V > eom as usize - p as usize { return -1; }
62 p = p.add(r as usize + 2 * NS_INT16SZ_V);
63 if section != 0 {
64 if NS_INT32SZ_V + NS_INT16SZ_V > eom as usize - p as usize { return -1; }
65 p = p.add(NS_INT32SZ_V);
66 let rdlen = ns_get16(p) as usize;
67 p = p.add(NS_INT16SZ_V);
68 if rdlen > eom as usize - p as usize { return -1; }
69 p = p.add(rdlen);
70 }
71 }
72 (p as usize - ptr as usize) as c_int
73}
74
75#[no_mangle]
76pub unsafe extern "C" fn ns_skiprr(ptr: *const u8, eom: *const u8, section: c_int, count: c_int) -> c_int {
77 let r = ns_skiprr_inner(ptr, eom, section, count);
78 if r < 0 { ERRNO!() = 90; } r
80}
81
82#[no_mangle]
83pub unsafe extern "C" fn ns_initparse(msg: *const u8, msglen: c_int, handle: *mut NsMsg) -> c_int {
84 if msg.is_null() || handle.is_null() || msglen < 0 {
85 ERRNO!() = 90;
86 return -1;
87 }
88 (*handle)._msg = msg;
89 (*handle)._eom = msg.add(msglen as usize);
90 if (msglen as usize) < (2 + NS_S_MAX_V) * NS_INT16SZ_V {
91 ERRNO!() = 90;
92 return -1;
93 }
94 let mut p = msg;
95 (*handle)._id = ns_get16(p) as u16;
96 p = p.add(2);
97 (*handle)._flags = ns_get16(p) as u16;
98 p = p.add(2);
99 for i in 0..NS_S_MAX_V {
100 (*handle)._counts[i] = ns_get16(p) as u16;
101 p = p.add(2);
102 }
103 for i in 0..NS_S_MAX_V {
104 if (*handle)._counts[i] != 0 {
105 (*handle)._sections[i] = p;
106 let r = ns_skiprr_inner(p, (*handle)._eom, i as c_int, (*handle)._counts[i] as c_int);
107 if r < 0 {
108 ERRNO!() = 90;
109 return -1;
110 }
111 p = p.add(r as usize);
112 } else {
113 (*handle)._sections[i] = core::ptr::null();
114 }
115 }
116 if p != (*handle)._eom {
117 ERRNO!() = 90;
118 return -1;
119 }
120 (*handle)._sect = NS_S_MAX_V as c_int;
121 (*handle)._rrnum = -1;
122 (*handle)._msg_ptr = core::ptr::null();
123 0
124}
125
126#[no_mangle]
127pub unsafe extern "C" fn ns_name_uncompress(
128 msg: *const u8,
129 eom: *const u8,
130 src: *const u8,
131 dst: *mut c_char,
132 dstsiz: usize,
133) -> c_int {
134 let r = crate::dn_expand(msg, eom, src, dst, dstsiz as c_int);
135 if r < 0 { ERRNO!() = 90; }
136 r
137}
138
139#[no_mangle]
140pub unsafe extern "C" fn ns_parserr(handle: *mut NsMsg, section: c_int, rrnum_in: c_int, rr: *mut NsRr) -> c_int {
141 if handle.is_null() || rr.is_null() || section < 0 || section >= NS_S_MAX_V as c_int {
142 ERRNO!() = 19; return -1;
144 }
145 let sec = section as usize;
146 if section != (*handle)._sect {
147 (*handle)._sect = section;
148 (*handle)._rrnum = 0;
149 (*handle)._msg_ptr = (*handle)._sections[sec];
150 }
151 let mut rrnum = rrnum_in;
152 if rrnum == -1 { rrnum = (*handle)._rrnum; }
153 if rrnum < 0 || rrnum >= (*handle)._counts[sec] as c_int {
154 ERRNO!() = 19;
155 return -1;
156 }
157 if rrnum < (*handle)._rrnum {
158 (*handle)._rrnum = 0;
159 (*handle)._msg_ptr = (*handle)._sections[sec];
160 }
161 if rrnum > (*handle)._rrnum {
162 let r = ns_skiprr_inner(
163 (*handle)._msg_ptr,
164 (*handle)._eom,
165 section,
166 rrnum - (*handle)._rrnum,
167 );
168 if r < 0 {
169 ERRNO!() = 90;
170 return -1;
171 }
172 (*handle)._msg_ptr = (*handle)._msg_ptr.add(r as usize);
173 (*handle)._rrnum = rrnum;
174 }
175 let r = ns_name_uncompress(
176 (*handle)._msg,
177 (*handle)._eom,
178 (*handle)._msg_ptr,
179 (*rr).name.as_mut_ptr(),
180 NS_MAXDNAME_V,
181 );
182 if r < 0 { return -1; }
183 (*handle)._msg_ptr = (*handle)._msg_ptr.add(r as usize);
184 if 2 * NS_INT16SZ_V > (*handle)._eom as usize - (*handle)._msg_ptr as usize {
185 ERRNO!() = 90;
186 return -1;
187 }
188 (*rr).type_ = ns_get16((*handle)._msg_ptr) as u16;
189 (*handle)._msg_ptr = (*handle)._msg_ptr.add(2);
190 (*rr).rr_class = ns_get16((*handle)._msg_ptr) as u16;
191 (*handle)._msg_ptr = (*handle)._msg_ptr.add(2);
192 if section != 0 {
193 if NS_INT32SZ_V + NS_INT16SZ_V > (*handle)._eom as usize - (*handle)._msg_ptr as usize {
194 ERRNO!() = 90;
195 return -1;
196 }
197 (*rr).ttl = ns_get32((*handle)._msg_ptr) as u32;
198 (*handle)._msg_ptr = (*handle)._msg_ptr.add(4);
199 (*rr).rdlength = ns_get16((*handle)._msg_ptr) as u16;
200 (*handle)._msg_ptr = (*handle)._msg_ptr.add(2);
201 if (*rr).rdlength as usize > (*handle)._eom as usize - (*handle)._msg_ptr as usize {
202 ERRNO!() = 90;
203 return -1;
204 }
205 (*rr).rdata = (*handle)._msg_ptr;
206 (*handle)._msg_ptr = (*handle)._msg_ptr.add((*rr).rdlength as usize);
207 } else {
208 (*rr).ttl = 0;
209 (*rr).rdlength = 0;
210 (*rr).rdata = core::ptr::null();
211 }
212 (*handle)._rrnum += 1;
213 if (*handle)._rrnum > (*handle)._counts[sec] as c_int {
214 (*handle)._sect = section + 1;
215 if (*handle)._sect == NS_S_MAX_V as c_int {
216 (*handle)._rrnum = -1;
217 (*handle)._msg_ptr = core::ptr::null();
218 } else {
219 (*handle)._rrnum = 0;
220 }
221 }
222 0
223}