rfc3596.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "dns/rfc2671.h"
11 #include "dns/rfc3596.h"
12 #include "util.h"
13 
14 #if HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17 #if HAVE_MEMORY_H
18 #include <memory.h>
19 #endif
20 #if HAVE_ASSERT_H
21 #include <assert.h>
22 #endif
23 #if HAVE_NETINET_IN_H
24 #include <netinet/in.h>
25 #endif
26 #if HAVE_STRINGS_H
27 #include <strings.h>
28 #endif
29 
30 #ifndef SQUID_RFC1035_H
31 #error RFC3596 Library depends on RFC1035
32 #endif
33 
34 /*
35  * Low level DNS protocol routines
36  *
37  * Provides RFC3596 functions to handle purely IPv6 DNS.
38  * Adds AAAA and IPv6 PTR records.
39  * Other IPv6 records are not mentioned by this RFC.
40  *
41  * IPv4 equivalents are taken care of by the RFC1035 library.
42  * Where one protocol lookup must be followed by another, the caller
43  * is responsible for the order and handling of the lookups.
44  *
45  * KNOWN BUGS:
46  *
47  * UDP replies with TC set should be retried via TCP
48  */
49 
58 ssize_t
59 rfc3596BuildHostQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, int qtype, ssize_t edns_sz)
60 {
61  static rfc1035_message h;
62  size_t offset = 0;
63  memset(&h, '\0', sizeof(h));
64  h.id = qid;
65  h.qr = 0;
66  h.rd = 1;
67  h.opcode = 0; /* QUERY */
68  h.qdcount = (unsigned int) 1;
69  h.arcount = (edns_sz > 0 ? 1 : 0);
70  offset += rfc1035HeaderPack(buf + offset, sz - offset, &h);
71  offset += rfc1035QuestionPack(buf + offset,
72  sz - offset,
73  hostname,
74  qtype,
76  if (edns_sz > 0)
77  offset += rfc2671RROptPack(buf + offset, sz - offset, edns_sz);
78 
79  if (query) {
80  query->qtype = qtype;
81  query->qclass = RFC1035_CLASS_IN;
82  xstrncpy(query->name, hostname, sizeof(query->name));
83  }
84 
85  assert(offset <= sz);
86  return offset;
87 }
88 
97 ssize_t
98 rfc3596BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, ssize_t edns_sz)
99 {
100  return rfc3596BuildHostQuery(hostname, buf, sz, qid, query, RFC1035_TYPE_A, edns_sz);
101 }
102 
111 ssize_t
112 rfc3596BuildAAAAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, ssize_t edns_sz)
113 {
114  return rfc3596BuildHostQuery(hostname, buf, sz, qid, query, RFC1035_TYPE_AAAA, edns_sz);
115 }
116 
125 ssize_t
126 rfc3596BuildPTRQuery4(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, ssize_t edns_sz)
127 {
128  static char rev[RFC1035_MAXHOSTNAMESZ];
129  unsigned int i;
130 
131  i = (unsigned int) ntohl(addr.s_addr);
132  snprintf(rev, RFC1035_MAXHOSTNAMESZ, "%u.%u.%u.%u.in-addr.arpa.",
133  i & 255,
134  (i >> 8) & 255,
135  (i >> 16) & 255,
136  (i >> 24) & 255);
137 
138  return rfc3596BuildHostQuery(rev, buf, sz, qid, query, RFC1035_TYPE_PTR, edns_sz);
139 }
140 
141 ssize_t
142 rfc3596BuildPTRQuery6(const struct in6_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, ssize_t edns_sz)
143 {
144  static char rev[RFC1035_MAXHOSTNAMESZ];
145  const uint8_t* r = addr.s6_addr;
146  char* p = rev;
147  int i; /* NP: MUST allow signed for loop termination. */
148 
149  /* work from the raw addr field. anything else may have representation changes. */
150  /* The sin6_port and sin6_addr members shall be in network byte order. */
151  for (i = 15; i >= 0; i--, p+=4) {
152  snprintf(p, 5, "%1x.%1x.", ((r[i])&0xf), (r[i]>>4)&0xf );
153  }
154 
155  snprintf(p,10,"ip6.arpa.");
156 
157  return rfc3596BuildHostQuery(rev, buf, sz, qid, query, RFC1035_TYPE_PTR, edns_sz);
158 }
159 
unsigned int opcode
Definition: rfc1035.h:58
int rfc2671RROptPack(char *buf, size_t sz, ssize_t edns_sz)
Definition: rfc2671.cc:14
int rfc1035HeaderPack(char *buf, size_t sz, rfc1035_message *hdr)
Definition: rfc1035.cc:60
char * xstrncpy(char *dst, const char *src, size_t n)
Definition: xstring.cc:37
ssize_t rfc3596BuildPTRQuery6(const struct in6_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
Definition: rfc3596.cc:142
unsigned short qdcount
Definition: rfc1035.h:64
#define RFC1035_TYPE_A
Definition: rfc1035.h:93
#define RFC1035_MAXHOSTNAMESZ
Definition: rfc1035.h:32
ssize_t rfc3596BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
Definition: rfc3596.cc:98
#define RFC1035_TYPE_PTR
Definition: rfc1035.h:95
#define assert(EX)
Definition: assert.h:19
unsigned short qtype
Definition: rfc1035.h:50
void const char int sz
Definition: stub_cbdata.cc:16
#define RFC1035_TYPE_AAAA
Definition: rfc3596.h:53
unsigned short id
Definition: rfc1035.h:56
char name[RFC1035_MAXHOSTNAMESZ]
Definition: rfc1035.h:49
ssize_t rfc3596BuildPTRQuery4(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
Definition: rfc3596.cc:126
unsigned short qclass
Definition: rfc1035.h:51
unsigned int rd
Definition: rfc1035.h:61
int rfc1035QuestionPack(char *buf, const size_t sz, const char *name, const unsigned short type, const unsigned short _class)
Definition: rfc1035.cc:153
ssize_t rfc3596BuildHostQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, int qtype, ssize_t edns_sz)
Definition: rfc3596.cc:59
unsigned short arcount
Definition: rfc1035.h:67
#define RFC1035_CLASS_IN
Definition: rfc1035.h:96
ssize_t rfc3596BuildAAAAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, ssize_t edns_sz)
Definition: rfc3596.cc:112
unsigned int qr
Definition: rfc1035.h:57
int unsigned int
Definition: stub_fd.cc:19

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors