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
;