Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

SOA parser added

I need to do SOA queries, so here is a parser for them.

- ares_soa_reply: new struct
- ares_malloc_data/ares_free_soa: ARES_DATATYPE_SOA_REPLY
- ares_parse_soa_reply: actual function
  • Loading branch information...
commit 979bf951d3436bf7e86e690de26a174b39a081f8 1 parent 38b69b7
Marko Kreen authored June 15, 2012 bagder committed June 15, 2012
4  Makefile.inc
@@ -28,6 +28,7 @@ CSOURCES = ares__close_sockets.c	\
28 28
   ares_parse_naptr_reply.c		\
29 29
   ares_parse_ns_reply.c			\
30 30
   ares_parse_ptr_reply.c		\
  31
+  ares_parse_soa_reply.c		\
31 32
   ares_parse_srv_reply.c		\
32 33
   ares_parse_txt_reply.c		\
33 34
   ares_platform.c			\
@@ -97,6 +98,7 @@ MANPAGES = ares_cancel.3		\
97 98
   ares_parse_naptr_reply.3		\
98 99
   ares_parse_ns_reply.3			\
99 100
   ares_parse_ptr_reply.3		\
  101
+  ares_parse_soa_reply.3		\
100 102
   ares_parse_srv_reply.3		\
101 103
   ares_parse_txt_reply.3		\
102 104
   ares_process.3			\
@@ -136,6 +138,7 @@ HTMLPAGES = ares_cancel.html		\
136 138
   ares_parse_mx_reply.html		\
137 139
   ares_parse_ns_reply.html		\
138 140
   ares_parse_ptr_reply.html		\
  141
+  ares_parse_soa_reply.html		\
139 142
   ares_parse_srv_reply.html		\
140 143
   ares_parse_txt_reply.html		\
141 144
   ares_process.html			\
@@ -175,6 +178,7 @@ PDFPAGES = ares_cancel.pdf		\
175 178
   ares_parse_mx_reply.pdf		\
176 179
   ares_parse_ns_reply.pdf		\
177 180
   ares_parse_ptr_reply.pdf		\
  181
+  ares_parse_soa_reply.pdf		\
178 182
   ares_parse_srv_reply.pdf		\
179 183
   ares_parse_txt_reply.pdf		\
180 184
   ares_process.pdf			\
16  ares.h
@@ -476,6 +476,16 @@ struct ares_naptr_reply {
476 476
   unsigned short           preference;
477 477
 };
478 478
 
  479
+struct ares_soa_reply {
  480
+  char        *nsname;
  481
+  char        *hostmaster;
  482
+  unsigned int serial;
  483
+  unsigned int refresh;
  484
+  unsigned int retry;
  485
+  unsigned int expire;
  486
+  unsigned int minttl;
  487
+};
  488
+
479 489
 /*
480 490
 ** Parse the buffer, starting at *abuf and of length alen bytes, previously
481 491
 ** obtained from an ares_search call.  Put the results in *host, if nonnull.
@@ -523,10 +533,16 @@ CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf,
523 533
                                         int alen,
524 534
                                         struct ares_naptr_reply** naptr_out);
525 535
 
  536
+CARES_EXTERN int ares_parse_soa_reply(const unsigned char* abuf,
  537
+				      int alen,
  538
+				      struct ares_soa_reply** soa_out);
  539
+
526 540
 CARES_EXTERN void ares_free_string(void *str);
527 541
 
528 542
 CARES_EXTERN void ares_free_hostent(struct hostent *host);
529 543
 
  544
+CARES_EXTERN void ares_free_soa(struct ares_soa_reply *soa);
  545
+
530 546
 CARES_EXTERN void ares_free_data(void *dataptr);
531 547
 
532 548
 CARES_EXTERN const char *ares_strerror(int code);
17  ares_data.c
@@ -106,6 +106,13 @@ void ares_free_data(void *dataptr)
106 106
           free(ptr->data.naptr_reply.replacement);
107 107
         break;
108 108
 
  109
+      case ARES_DATATYPE_SOA_REPLY:
  110
+        if (ptr->data.soa_reply.nsname)
  111
+          free(ptr->data.soa_reply.nsname);
  112
+        if (ptr->data.soa_reply.hostmaster)
  113
+          free(ptr->data.soa_reply.hostmaster);
  114
+	break;
  115
+
109 116
       default:
110 117
         return;
111 118
     }
@@ -172,6 +179,16 @@ void *ares_malloc_data(ares_datatype type)
172 179
         ptr->data.naptr_reply.preference = 0;
173 180
         break;
174 181
 
  182
+      case ARES_DATATYPE_SOA_REPLY:
  183
+        ptr->data.soa_reply.nsname = NULL;
  184
+        ptr->data.soa_reply.hostmaster = NULL;
  185
+        ptr->data.soa_reply.serial = 0;
  186
+        ptr->data.soa_reply.refresh = 0;
  187
+        ptr->data.soa_reply.retry = 0;
  188
+        ptr->data.soa_reply.expire = 0;
  189
+        ptr->data.soa_reply.minttl = 0;
  190
+	break;
  191
+
175 192
       default:
176 193
         free(ptr);
177 194
         return NULL;
2  ares_data.h
@@ -21,6 +21,7 @@ typedef enum {
21 21
   ARES_DATATYPE_ADDR_NODE,    /* struct ares_addr_node - introduced in 1.7.1 */
22 22
   ARES_DATATYPE_MX_REPLY,    /* struct ares_mx_reply   - introduced in 1.7.2 */
23 23
   ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */
  24
+  ARES_DATATYPE_SOA_REPLY,    /* struct ares_soa_reply - introduced in 1.x.x */
24 25
 #if 0
25 26
   ARES_DATATYPE_ADDR6TTL,     /* struct ares_addrttl   */
26 27
   ARES_DATATYPE_ADDRTTL,      /* struct ares_addr6ttl  */
@@ -59,6 +60,7 @@ struct ares_data {
59 60
     struct ares_addr_node   addr_node;
60 61
     struct ares_mx_reply    mx_reply;
61 62
     struct ares_naptr_reply naptr_reply;
  63
+    struct ares_soa_reply soa_reply;
62 64
   } data;
63 65
 };
64 66
 
8  ares_free_data.3
@@ -55,6 +55,11 @@ When used to free the data returned by ares_parse_txt_reply(3) this
55 55
 will free the whole linked list of ares_txt_reply structures returned
56 56
 by ares_parse_txt_reply(3), along with any additional storage
57 57
 associated with those structures.
  58
+.TP
  59
+.B ares_parse_soa_reply(3)
  60
+When used to free the data returned by ares_parse_soa_reply(3) this
  61
+will free the ares_soa_reply structure, along with any additional storage
  62
+associated with those structure.
58 63
 .SH RETURN VALUE
59 64
 The ares_free_data() function does not return a value.
60 65
 .SH AVAILABILITY
@@ -63,7 +68,8 @@ This function was first introduced in c-ares version 1.7.0.
63 68
 .BR ares_get_servers(3),
64 69
 .BR ares_parse_srv_reply(3),
65 70
 .BR ares_parse_mx_reply(3),
66  
-.BR ares_parse_txt_reply(3)
  71
+.BR ares_parse_txt_reply(3),
  72
+.BR ares_parse_soa_reply(3)
67 73
 .SH AUTHOR
68 74
 Yang Tse
69 75
 .PP
80  ares_parse_soa_reply.3
... ...
@@ -0,0 +1,80 @@
  1
+.\"
  2
+.\" Copyright 1998 by the Massachusetts Institute of Technology.
  3
+.\"
  4
+.\" Permission to use, copy, modify, and distribute this
  5
+.\" software and its documentation for any purpose and without
  6
+.\" fee is hereby granted, provided that the above copyright
  7
+.\" notice appear in all copies and that both that copyright
  8
+.\" notice and this permission notice appear in supporting
  9
+.\" documentation, and that the name of M.I.T. not be used in
  10
+.\" advertising or publicity pertaining to distribution of the
  11
+.\" software without specific, written prior permission.
  12
+.\" M.I.T. makes no representations about the suitability of
  13
+.\" this software for any purpose.  It is provided "as is"
  14
+.\" without express or implied warranty.
  15
+.\"
  16
+.TH ARES_PARSE_SOA_REPLY 3 "29 May 2012"
  17
+.SH NAME
  18
+ares_parse_soa_reply \- Parse a reply to a DNS query of type SOA
  19
+.SH SYNOPSIS
  20
+.nf
  21
+.B #include <ares.h>
  22
+.PP
  23
+.B int ares_parse_soa_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
  24
+.B				struct ares_soa_reply** \fIsoa_out\fP);
  25
+.fi
  26
+.SH DESCRIPTION
  27
+The
  28
+.B ares_parse_soa_reply
  29
+function parses the response to a query of type SOA into a
  30
+.IR struct\ ares_soa_reply .
  31
+The parameters
  32
+.I abuf
  33
+and
  34
+.I alen
  35
+give the contents of the response.  The result is stored in allocated
  36
+memory and a pointer to it stored into the variable pointed to by
  37
+.IR soa_out .
  38
+It is the caller's responsibility to free the resulting
  39
+.IR soa_out
  40
+structure when it is no longer needed using the function
  41
+.B ares_free_data
  42
+.PP
  43
+The structure 
  44
+.I ares_soa_reply
  45
+contains the following fields:
  46
+.sp
  47
+.in +4n
  48
+.nf
  49
+struct ares_soa_reply {
  50
+	char *nsname;
  51
+	char *hostmaster;
  52
+	unsigned int serial;
  53
+	unsigned int refresh;
  54
+	unsigned int retry;
  55
+	unsigned int expire;
  56
+	unsigned int minttl;
  57
+};
  58
+.fi
  59
+.in
  60
+.PP
  61
+.SH RETURN VALUES
  62
+.B ares_parse_soa_reply
  63
+can return any of the following values:
  64
+.TP 15
  65
+.B ARES_SUCCESS
  66
+The response was successfully parsed.
  67
+.TP 15
  68
+.B ARES_EBADRESP
  69
+The response was malformatted.
  70
+.TP 15
  71
+.B ARES_ENODATA
  72
+The response did not contain an answer to the query.
  73
+.TP 15
  74
+.B ARES_ENOMEM
  75
+Memory was exhausted.
  76
+.SH AVAILABILITY
  77
+This function was first introduced in c-ares version 1.9.0.
  78
+.SH SEE ALSO
  79
+.BR ares_query (3)
  80
+.BR ares_free_data (3)
135  ares_parse_soa_reply.c
... ...
@@ -0,0 +1,135 @@
  1
+
  2
+/* Copyright 1998 by the Massachusetts Institute of Technology.
  3
+ * Copyright (C) 2012 Marko Kreen <markokr@gmail.com>
  4
+ *
  5
+ * Permission to use, copy, modify, and distribute this
  6
+ * software and its documentation for any purpose and without
  7
+ * fee is hereby granted, provided that the above copyright
  8
+ * notice appear in all copies and that both that copyright
  9
+ * notice and this permission notice appear in supporting
  10
+ * documentation, and that the name of M.I.T. not be used in
  11
+ * advertising or publicity pertaining to distribution of the
  12
+ * software without specific, written prior permission.
  13
+ * M.I.T. makes no representations about the suitability of
  14
+ * this software for any purpose.  It is provided "as is"
  15
+ * without express or implied warranty.
  16
+ */
  17
+
  18
+#include "ares_setup.h"
  19
+
  20
+#ifdef HAVE_SYS_SOCKET_H
  21
+#  include <sys/socket.h>
  22
+#endif
  23
+#ifdef HAVE_NETINET_IN_H
  24
+#  include <netinet/in.h>
  25
+#endif
  26
+#ifdef HAVE_NETDB_H
  27
+#  include <netdb.h>
  28
+#endif
  29
+#ifdef HAVE_ARPA_INET_H
  30
+#  include <arpa/inet.h>
  31
+#endif
  32
+#ifdef HAVE_ARPA_NAMESER_H
  33
+#  include <arpa/nameser.h>
  34
+#else
  35
+#  include "nameser.h"
  36
+#endif
  37
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
  38
+#  include <arpa/nameser_compat.h>
  39
+#endif
  40
+
  41
+#include <stdlib.h>
  42
+#include <string.h>
  43
+#include "ares.h"
  44
+#include "ares_dns.h"
  45
+#include "ares_data.h"
  46
+#include "ares_private.h"
  47
+
  48
+int
  49
+ares_parse_soa_reply(const unsigned char *abuf, int alen,
  50
+		     struct ares_soa_reply **soa_out)
  51
+{
  52
+  const unsigned char *aptr;
  53
+  long len;
  54
+  char *qname = NULL, *rr_name = NULL;
  55
+  struct ares_soa_reply *soa = NULL;
  56
+  int qdcount, ancount;
  57
+  int status;
  58
+
  59
+  if (alen < HFIXEDSZ)
  60
+    return ARES_EBADRESP;
  61
+
  62
+  /* parse message header */
  63
+  qdcount = DNS_HEADER_QDCOUNT(abuf);
  64
+  ancount = DNS_HEADER_ANCOUNT(abuf);
  65
+  if (qdcount != 1 || ancount != 1)
  66
+    return ARES_EBADRESP;
  67
+  aptr = abuf + HFIXEDSZ;
  68
+
  69
+  /* query name */
  70
+  status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len);
  71
+  if (status != ARES_SUCCESS)
  72
+    goto failed_stat;
  73
+  aptr += len;
  74
+
  75
+  /* skip qtype & qclass */
  76
+  if (aptr + QFIXEDSZ > abuf + alen)
  77
+    goto failed;
  78
+  aptr += QFIXEDSZ;
  79
+
  80
+  /* rr_name */
  81
+  status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len);
  82
+  if (status != ARES_SUCCESS)
  83
+    goto failed_stat;
  84
+  aptr += len;
  85
+
  86
+  /* skip rr_type, rr_class, rr_ttl, rr_rdlen */
  87
+  if (aptr + RRFIXEDSZ > abuf + alen)
  88
+    goto failed;
  89
+  aptr += RRFIXEDSZ;
  90
+
  91
+  /* allocate result struct */
  92
+  soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY);
  93
+  if (!soa)
  94
+    return ARES_ENOMEM;
  95
+
  96
+  /* nsname */
  97
+  status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, &len);
  98
+  if (status != ARES_SUCCESS)
  99
+    goto failed_stat;
  100
+  aptr += len;
  101
+
  102
+  /* hostmaster */
  103
+  status = ares__expand_name_for_response(aptr, abuf, alen, &soa->hostmaster, &len);
  104
+  if (status != ARES_SUCCESS)
  105
+    goto failed_stat;
  106
+  aptr += len;
  107
+
  108
+  /* integer fields */
  109
+  if (aptr + 5 * 4 > abuf + alen)
  110
+    goto failed;
  111
+  soa->serial = DNS__32BIT(aptr + 0 * 4);
  112
+  soa->refresh = DNS__32BIT(aptr + 1 * 4);
  113
+  soa->retry = DNS__32BIT(aptr + 2 * 4);
  114
+  soa->expire = DNS__32BIT(aptr + 3 * 4);
  115
+  soa->minttl = DNS__32BIT(aptr + 4 * 4);
  116
+
  117
+  free(qname);
  118
+  free(rr_name);
  119
+
  120
+  *soa_out = soa;
  121
+
  122
+  return ARES_SUCCESS;
  123
+
  124
+failed:
  125
+  status = ARES_EBADRESP;
  126
+
  127
+failed_stat:
  128
+  ares_free_data(soa);
  129
+  if (qname)
  130
+    free(qname);
  131
+  if (rr_name)
  132
+    free(rr_name);
  133
+  return status;
  134
+}
  135
+

0 notes on commit 979bf95

Please sign in to comment.
Something went wrong with that request. Please try again.