Commit c7f3bd2a authored by Simon Kelley's avatar Simon Kelley

Replace incoming EDNS0_OPTION_NOMDEVICEID and EDNS0_OPTION_NOMCPEID options.

parent 22fe2fd0
...@@ -824,7 +824,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n ...@@ -824,7 +824,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
/* Advertise our packet size limit in our reply */ /* Advertise our packet size limit in our reply */
if (have_pseudoheader) if (have_pseudoheader)
return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit); return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
return ansp - (unsigned char *)header; return ansp - (unsigned char *)header;
} }
......
...@@ -1523,7 +1523,7 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new); ...@@ -1523,7 +1523,7 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new);
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
size_t *len, unsigned char **p, int *is_sign, int *is_last); size_t *len, unsigned char **p, int *is_sign, int *is_last);
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit, size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do); unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace);
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit); size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit);
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit, size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
union mysockaddr *source, time_t now, int *check_subnet); union mysockaddr *source, time_t now, int *check_subnet);
......
...@@ -96,7 +96,7 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t ...@@ -96,7 +96,7 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t
} }
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit, size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do) unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace)
{ {
unsigned char *lenp, *datap, *p, *udp_len, *buff = NULL; unsigned char *lenp, *datap, *p, *udp_len, *buff = NULL;
int rdlen = 0, is_sign, is_last; int rdlen = 0, is_sign, is_last;
...@@ -120,7 +120,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l ...@@ -120,7 +120,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
if (set_do) if (set_do)
{ {
p -=2; p -= 2;
flags |= 0x8000; flags |= 0x8000;
PUTSHORT(flags, p); PUTSHORT(flags, p);
} }
...@@ -136,13 +136,36 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l ...@@ -136,13 +136,36 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
return plen; return plen;
/* check if option already there */ /* check if option already there */
for (i = 0; i + 4 < rdlen; i += len + 4) for (i = 0; i + 4 < rdlen;)
{ {
GETSHORT(code, p); GETSHORT(code, p);
GETSHORT(len, p); GETSHORT(len, p);
/* malformed option, delete the whole OPT RR and start again. */
if (i + len > rdlen)
{
rdlen = 0;
islast = 0;
break;
}
if (code == optno) if (code == optno)
return plen; {
p += len; if (!replace)
return plen;
/* delete option if we're to replace it. */
p -= 4;
rdlen -= len + 4;
memcpy(p, p+len+4, rdlen - i);
PUTSHORT(rdlen, lenp);
lenp -= 2;
}
else
{
p += len;
i += len + 4;
}
} }
/* If we're going to extend the RR, it has to be the last RR in the packet */ /* If we're going to extend the RR, it has to be the last RR in the packet */
...@@ -203,7 +226,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l ...@@ -203,7 +226,7 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit) size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit)
{ {
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, 0, NULL, 0, 1); return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, 0, NULL, 0, 1, 0);
} }
static unsigned char char64(unsigned char c) static unsigned char char64(unsigned char c)
...@@ -235,7 +258,7 @@ static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned ch ...@@ -235,7 +258,7 @@ static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned ch
encoder(mac+3, encode+4); encoder(mac+3, encode+4);
encode[8] = 0; encode[8] = 0;
} }
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, strlen(encode), 0); plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, strlen(encode), 0, 1);
} }
return plen; return plen;
...@@ -248,7 +271,7 @@ static size_t add_mac(struct dns_header *header, size_t plen, unsigned char *lim ...@@ -248,7 +271,7 @@ static size_t add_mac(struct dns_header *header, size_t plen, unsigned char *lim
unsigned char mac[DHCP_CHADDR_MAX]; unsigned char mac[DHCP_CHADDR_MAX];
if ((maclen = find_mac(l3, mac, 1, now)) != 0) if ((maclen = find_mac(l3, mac, 1, now)) != 0)
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_MAC, mac, maclen, 0); plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_MAC, mac, maclen, 0, 0);
return plen; return plen;
} }
...@@ -337,7 +360,7 @@ static size_t add_source_addr(struct dns_header *header, size_t plen, unsigned c ...@@ -337,7 +360,7 @@ static size_t add_source_addr(struct dns_header *header, size_t plen, unsigned c
struct subnet_opt opt; struct subnet_opt opt;
len = calc_subnet_opt(&opt, source); len = calc_subnet_opt(&opt, source);
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0); return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0, 0);
} }
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer) int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
...@@ -391,7 +414,7 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l ...@@ -391,7 +414,7 @@ size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *l
if (daemon->dns_client_id) if (daemon->dns_client_id)
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMCPEID, plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMCPEID,
(unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0); (unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0, 1);
if (option_bool(OPT_CLIENT_SUBNET)) if (option_bool(OPT_CLIENT_SUBNET))
{ {
......
...@@ -2171,7 +2171,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma ...@@ -2171,7 +2171,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
daemon->dns_client_id = opt_string_alloc(arg); daemon->dns_client_id = opt_string_alloc(arg);
break; break;
case LOPT_ADD_MAC: case LOPT_ADD_MAC: /* --add-mac */
if (!arg) if (!arg)
set_option_bool(OPT_ADD_MAC); set_option_bool(OPT_ADD_MAC);
else else
......
...@@ -1847,7 +1847,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, ...@@ -1847,7 +1847,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
/* Advertise our packet size limit in our reply */ /* Advertise our packet size limit in our reply */
if (have_pseudoheader) if (have_pseudoheader)
len = add_pseudoheader(header, len, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit); len = add_pseudoheader(header, len, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
if (ad_reqd && sec_data) if (ad_reqd && sec_data)
header->hb4 |= HB4_AD; header->hb4 |= HB4_AD;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment