5 #include <arpa/nameser.h>
7 const struct _ns_flagdata _ns_flagdata[16] = {
26 unsigned ns_get16(const unsigned char *cp)
28 return cp[0]<<8 | cp[1];
31 unsigned long ns_get32(const unsigned char *cp)
33 return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
36 void ns_put16(unsigned s, unsigned char *cp)
42 void ns_put32(unsigned long l, unsigned char *cp)
50 int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
55 handle->_eom = msg + msglen;
56 if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
57 NS_GET16(handle->_id, msg);
58 NS_GET16(handle->_flags, msg);
59 for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
60 for (i = 0; i < ns_s_max; i++) {
61 if (handle->_counts[i]) {
62 handle->_sections[i] = msg;
63 r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]);
67 handle->_sections[i] = NULL;
70 if (msg != handle->_eom) goto bad;
71 handle->_sect = ns_s_max;
73 handle->_msg_ptr = NULL;
80 int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count)
82 const unsigned char *p = ptr;
86 r = dn_skipname(p, eom);
88 if (r + 2 * NS_INT16SZ > eom - p) goto bad;
89 p += r + 2 * NS_INT16SZ;
90 if (section != ns_s_qd) {
91 if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad;
94 if (r > eom - p) goto bad;
104 int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
108 if (section < 0 || section >= ns_s_max) goto bad;
109 if (section != handle->_sect) {
110 handle->_sect = section;
112 handle->_msg_ptr = handle->_sections[section];
114 if (rrnum == -1) rrnum = handle->_rrnum;
115 if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
116 if (rrnum < handle->_rrnum) {
118 handle->_msg_ptr = handle->_sections[section];
120 if (rrnum > handle->_rrnum) {
121 r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum);
122 if (r < 0) return -1;
123 handle->_msg_ptr += r;
124 handle->_rrnum = rrnum;
126 r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
127 if (r < 0) return -1;
128 handle->_msg_ptr += r;
129 if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
130 NS_GET16(rr->type, handle->_msg_ptr);
131 NS_GET16(rr->rr_class, handle->_msg_ptr);
132 if (section != ns_s_qd) {
133 if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
134 NS_GET32(rr->ttl, handle->_msg_ptr);
135 NS_GET16(rr->rdlength, handle->_msg_ptr);
136 if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size;
137 rr->rdata = handle->_msg_ptr;
138 handle->_msg_ptr += rr->rdlength;
145 if (handle->_rrnum > handle->_counts[section]) {
146 handle->_sect = section + 1;
147 if (handle->_sect == ns_s_max) {
149 handle->_msg_ptr = NULL;
163 int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
164 const unsigned char *src, char *dst, size_t dstsiz)
167 r = dn_expand(msg, eom, src, dst, dstsiz);
168 if (r < 0) errno = EMSGSIZE;