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