dns.c revision 1ffedb586bd2fb6daa3970304fac7c5b415cd38f
1ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering/* $Id$ */ 2ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering 3ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering/*** 4ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering This file is part of avahi. 5ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering 6ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering avahi is free software; you can redistribute it and/or modify it 7ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering under the terms of the GNU Lesser General Public License as 8ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering published by the Free Software Foundation; either version 2.1 of the 9ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering License, or (at your option) any later version. 10ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering 11ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering avahi is distributed in the hope that it will be useful, but WITHOUT 12ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering Public License for more details. 15ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering 16ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering You should have received a copy of the GNU Lesser General Public 17ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering License along with avahi; if not, write to the Free Software 18ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering USA. 20ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering***/ 21ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering 22eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering#ifdef HAVE_CONFIG_H 23eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering#include <config.h> 24eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering#endif 25eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering 26a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering#include <netinet/in.h> 27a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <stdlib.h> 294ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <string.h> 304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <stdio.h> 314f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include <assert.h> 324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 335ebf655c85076f200955458673a8bbf0dd927407Lennart Poettering#include <avahi-common/domain.h> 344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include <avahi-common/malloc.h> 354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 364ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include "dns.h" 374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include "log.h" 384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 394f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new(unsigned mtu) { 407dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t max_size; 42c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 43602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (mtu <= 0) 447dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering max_size = AVAHI_DNS_PACKET_MAX_SIZE; 45b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering else if (mtu >= AVAHI_DNS_PACKET_EXTRA_SIZE) 46b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering max_size = mtu - AVAHI_DNS_PACKET_EXTRA_SIZE; 47602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering else 48602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering max_size = 0; 49602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 50602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (max_size < AVAHI_DNS_PACKET_HEADER_SIZE) 517dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering max_size = AVAHI_DNS_PACKET_HEADER_SIZE; 52c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_malloc(sizeof(AvahiDnsPacket) + max_size))) 544f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return p; 554f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 567dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering p->size = p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 57c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->max_size = max_size; 584ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering p->name_table = NULL; 59c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 607dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memset(AVAHI_DNS_PACKET_DATA(p), 0, p->size); 61c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 62c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 63c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 644f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_query(unsigned mtu) { 657dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 66c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 707dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); 71c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 72c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 73c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 744f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_response(unsigned mtu, int aa) { 757dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 76c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 774f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 794f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 808d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(1, 0, aa, 0, 0, 0, 0, 0, 0, 0)); 814ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return p; 824ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 844f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_reply(AvahiDnsPacket* p, unsigned mtu, int copy_queries, int aa) { 85602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiDnsPacket *r; 864f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 87602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 884f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(r = avahi_dns_packet_new_response(mtu, aa))) 894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 90602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 91602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (copy_queries) { 924f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned saved_rindex; 934f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint32_t n; 94602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 95602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering saved_rindex = p->rindex; 96602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 97602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 98602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT); n > 0; n--) { 99602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiKey *k; 1004f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int unicast_response; 101602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 102602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if ((k = avahi_dns_packet_consume_key(p, &unicast_response))) { 103602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_append_key(r, k, unicast_response); 104602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_key_unref(k); 105602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 106602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 107602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 108602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = saved_rindex; 109602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 110602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_QDCOUNT, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT)); 111602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 112602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 113602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_ID, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ID)); 114602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 115602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_FLAGS, 116602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering (avahi_dns_packet_get_field(r, AVAHI_DNS_FIELD_FLAGS) & ~AVAHI_DNS_FLAG_OPCODE) | 1178d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_OPCODE)); 118602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 119602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering return r; 120602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering} 121602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 122602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 1237dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poetteringvoid avahi_dns_packet_free(AvahiDnsPacket *p) { 1244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1254ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1264ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (p->name_table) 1274f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_free(p->name_table); 1284ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1294f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_free(p); 1304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1324f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_set_field(AvahiDnsPacket *p, unsigned idx, uint16_t v) { 1334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 1354ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering ((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx] = htons(v); 1374ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1394f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint16_t avahi_dns_packet_get_field(AvahiDnsPacket *p, unsigned idx) { 1404f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 1424ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return ntohs(((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx]); 1444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_inc_field(AvahiDnsPacket *p, unsigned idx) { 1474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1484f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 149af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 15066142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_dns_packet_set_field(p, idx, avahi_dns_packet_get_field(p, idx) + 1); 151af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering} 152af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 1534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_name(AvahiDnsPacket *p, const char *name) { 1544f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d, *saved_ptr = NULL; 1554f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t saved_size; 1564ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1584f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(name); 1594ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 160c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering saved_size = p->size; 1617dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering saved_ptr = avahi_dns_packet_extend(p, 0); 1624c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering 1634e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering while (*name) { 1644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* prev; 1654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const char *pname; 1664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char label[64], *u; 1674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 1684ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1694ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering /* Check whether we can compress this name. */ 1704ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1714f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->name_table && (prev = avahi_hashmap_lookup(p->name_table, name))) { 1724f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned idx; 1734ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1744f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(prev >= AVAHI_DNS_PACKET_DATA(p)); 1754f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering idx = (unsigned) (prev - AVAHI_DNS_PACKET_DATA(p)); 1764ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1774f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < p->size); 1784ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 17966142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx < 0x4000) { 1804f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t *t; 1814f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(t = (uint16_t*) avahi_dns_packet_extend(p, sizeof(uint16_t)))) 1824ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering return NULL; 1834ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1844f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *t = htons((0xC000 | idx)); 1854c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 1864ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 1874ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 1884e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 1894e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering pname = name; 1904ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 191a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering if (!(avahi_unescape_label(&name, label, sizeof(label)))) 192c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 1934ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1947dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_append_string(p, label))) 1954e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering goto fail; 1964c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering 1974ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (!p->name_table) 198a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering /* This works only for normalized domain names */ 1994f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->name_table = avahi_hashmap_new(avahi_string_hash, avahi_string_equal, avahi_free, NULL); 2004ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 2014f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(u = avahi_strdup(pname))) 2024f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_log_error("avahi_strdup() failed."); 2034f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering else 2044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_insert(p->name_table, u, d); 2054ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 2064ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2077dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, 1))) 208c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 209c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2104e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering *d = 0; 2114ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2124c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 213c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 214c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poetteringfail: 215c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->size = saved_size; 216c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 2174ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2184ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2194f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_uint16(AvahiDnsPacket *p, uint16_t v) { 2204f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2214f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2224ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint16_t)))) 224c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 2254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *((uint16_t*) d) = htons(v); 2274ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 2284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2294ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2304f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_uint32(AvahiDnsPacket *p, uint32_t v) { 2314f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2324f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 233c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint32_t)))) 235c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 236c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *((uint32_t*) d) = htonl(v); 23854247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 23954247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 24054247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 24154247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_bytes(AvahiDnsPacket *p, const void *b, size_t l) { 2434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 24454247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2454f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(b); 2474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l); 2484aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 2497dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, l))) 250c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 25154247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 252c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering memcpy(d, b, l); 25354247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 25454247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 25554247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2564f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_string(AvahiDnsPacket *p, const char *s) { 2574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 2584f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 259a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2604f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2614f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 262a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 263a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if ((k = strlen(s)) >= 255) 264a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering k = 255; 265a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2667dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, k+1))) 267a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 268a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *d = (uint8_t) k; 270a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering memcpy(d+1, s, k); 271a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 272a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return d; 273a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 274a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2754f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_extend(AvahiDnsPacket *p, size_t l) { 2764f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2774ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2794ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 280c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering if (p->size+l > p->max_size) 281c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 282c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2837dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering d = AVAHI_DNS_PACKET_DATA(p) + p->size; 2844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->size += l; 2854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2864ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 2874ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2884ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2891ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid(AvahiDnsPacket *p) { 2904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t flags; 2914f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2924ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2931ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (p->size < AVAHI_DNS_PACKET_HEADER_SIZE) 2944ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 2954ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2967dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 2971ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 2981ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_OPCODE) 2991ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 3001ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3011ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return 0; 3021ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering} 3031ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3041ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid_multicast(AvahiDnsPacket *p) { 3051ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering uint16_t flags; 3061ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering assert(p); 3074ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3081ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (avahi_dns_packet_check_valid(p) < 0) 3091ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 3101ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3111ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 3121ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3131ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_RCODE) 3144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3154ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3164ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 3174ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3184ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3191ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3204f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_query(AvahiDnsPacket *p) { 3214f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 3224ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3237dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return !(avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_QR); 3244ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic int consume_labels(AvahiDnsPacket *p, unsigned idx, char *ret_name, size_t l) { 3274f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int ret = 0; 3284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int compressed = 0; 3294ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int first_label = 1; 3304f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p && ret_name && l); 3314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering for (;;) { 3334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t n; 3344ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 33566142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+1 > p->size) 3364ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3374ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 33866142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = AVAHI_DNS_PACKET_DATA(p)[idx]; 3394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3404ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!n) { 34166142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3424ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3434ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 3444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (l < 1) 3464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *ret_name = 0; 3484ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3494ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return ret; 3504ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3514ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if (n <= 63) { 3524ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Uncompressed label */ 35366142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3544ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3554ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 3564ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 35766142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx + n > p->size) 3584ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3594ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3604f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((size_t) n + 1 > l) 3614ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3624ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3634ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!first_label) { 3644ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *(ret_name++) = '.'; 3654ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering l--; 3664ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 3674ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering first_label = 0; 3684ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 36966142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (!(avahi_escape_label(AVAHI_DNS_PACKET_DATA(p) + idx, n, &ret_name, &l))) 3704e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering return -1; 3714e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 37266142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx += n; 3734ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3744ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3754ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += n; 3764ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if ((n & 0xC0) == 0xC0) { 3774ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Compressed label */ 3784ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 37966142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+2 > p->size) 3804ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3814ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3824f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering idx = ((unsigned) (AVAHI_DNS_PACKET_DATA(p)[idx] & ~0xC0)) << 8 | AVAHI_DNS_PACKET_DATA(p)[idx+1]; 3834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += 2; 3864ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3874ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering compressed = 1; 3884ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 3894ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3904ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 3914ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3924ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3934f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_name(AvahiDnsPacket *p, char *ret_name, size_t l) { 3944f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int r; 3954ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3964ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if ((r = consume_labels(p, p->rindex, ret_name, l)) < 0) 3974ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3984ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3994ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += r; 4004ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4024ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4034f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint16(AvahiDnsPacket *p, uint16_t *ret_v) { 4044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4054f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4064ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4074f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint16_t) > p->size) 4084ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4094ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *ret_v = ntohs(*((uint16_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex))); 4114f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint16_t); 4124ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4134ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4154ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4164f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint32(AvahiDnsPacket *p, uint32_t *ret_v) { 4174f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4184f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4194ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4204f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint32_t) > p->size) 4214ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4224ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *ret_v = ntohl(*((uint32_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex))); 4244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint32_t); 4254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4264ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4274ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4294f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_bytes(AvahiDnsPacket *p, void * ret_data, size_t l) { 4304f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4314f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_data); 4324f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 4334ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4344ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + l > p->size) 4354ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4364ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4377dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_data, AVAHI_DNS_PACKET_DATA(p) + p->rindex, l); 4384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += l; 4394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4404ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4414ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4424ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_string(AvahiDnsPacket *p, char *ret_string, size_t l) { 4444f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 445a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_string); 4484f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 449a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 450a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex >= p->size) 451a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 452a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4537dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering k = AVAHI_DNS_PACKET_DATA(p)[p->rindex]; 454a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 455a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex+1+k > p->size) 456a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 457a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 458a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (l > k+1) 459a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering l = k+1; 460a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4617dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_string, AVAHI_DNS_PACKET_DATA(p)+p->rindex+1, l-1); 462a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering ret_string[l-1] = 0; 463a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 464a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering p->rindex += 1+k; 465a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 466a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return 0; 467a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 468a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringconst void* avahi_dns_packet_get_rptr(AvahiDnsPacket *p) { 4704f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 471f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 472a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex > p->size) 473f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 474f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4757dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return AVAHI_DNS_PACKET_DATA(p) + p->rindex; 476f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 477f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_skip(AvahiDnsPacket *p, size_t length) { 4794f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4804ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4814ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + length > p->size) 4824ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += length; 4854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4864ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 487f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4884f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiRecord* avahi_dns_packet_consume_record(AvahiDnsPacket *p, int *ret_cache_flush) { 4894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char name[257], buf[257]; 4904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t type, class; 4914f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint32_t ttl; 4924f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t rdlength; 4937dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiRecord *r = NULL; 4944f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const void* start; 495f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4964f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 497f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 498c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("consume_record()"); */ 499a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5007dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 5017dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 5027dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0 || 5037dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint32(p, &ttl) < 0 || 5047dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &rdlength) < 0 || 505a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering p->rindex + rdlength > p->size) 506a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 507a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 508c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("name = %s, rdlength = %u", name, rdlength); */ 509b8c78f5c0da93d92aa28d3ef3757e78d03141f41Lennart Poettering 5101ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (ret_cache_flush) 5111ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering *ret_cache_flush = !!(class & AVAHI_DNS_CACHE_FLUSH); 5127dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering class &= ~AVAHI_DNS_CACHE_FLUSH; 513a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5147dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering start = avahi_dns_packet_get_rptr(p); 515b8c78f5c0da93d92aa28d3ef3757e78d03141f41Lennart Poettering 5164f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(r = avahi_record_new_full(name, class, type, ttl))) 5174f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 518a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 519c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering switch (type) { 5207dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 5217dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_CNAME: 522a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 523c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("ptr"); */ 524a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5257dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 526a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 527a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5284f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.ptr.name = avahi_strdup(buf); 529a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 530a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 531c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5327dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 533a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 534c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("srv"); */ 535a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5367dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_uint16(p, &r->data.srv.priority) < 0 || 5377dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.weight) < 0 || 5387dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.port) < 0 || 5397dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 540a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 541a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.srv.name = avahi_strdup(buf); 543a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 544a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5457dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 546a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 547c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("hinfo"); */ 548a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5497dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 550a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 551a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5524f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.cpu = avahi_strdup(buf); 553a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5547dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 555a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 556a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.os = avahi_strdup(buf); 558c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 559c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5607dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: 561a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 562c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("txt"); */ 563c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 564a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (rdlength > 0) { 5657dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering r->data.txt.string_list = avahi_string_list_parse(avahi_dns_packet_get_rptr(p), rdlength); 566a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5677dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 568a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 569fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering } else 570fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering r->data.txt.string_list = NULL; 571c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 572a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 573a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5747dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 575a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 576c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("A"); */ 577c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5787dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.a.address, sizeof(AvahiIPv4Address)) < 0) 579a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 580a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 581a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 582a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5837dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 584a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 585c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("aaaa"); */ 586a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5877dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.aaaa.address, sizeof(AvahiIPv6Address)) < 0) 588a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 589a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 590c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 591c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 592c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 5934aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 594c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("generic"); */ 595a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5964aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering if (rdlength > 0) { 5974aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 5984f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.generic.data = avahi_memdup(avahi_dns_packet_get_rptr(p), rdlength); 599a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 6007dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 601a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 602a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering } 603c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 604c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 605c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 606c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 6074f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering/* avahi_log_debug("%i == %u ?", (uint8_t*) avahi_dns_packet_get_rptr(p) - (uint8_t*) start, rdlength); */ 608a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 609a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering /* Check if we read enough data */ 6104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((const uint8_t*) avahi_dns_packet_get_rptr(p) - (const uint8_t*) start != rdlength) 611a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 612a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 613a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return r; 614a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 615a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poetteringfail: 616a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (r) 6177dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_record_unref(r); 618a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 619a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 620f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 621f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6224f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiKey* avahi_dns_packet_consume_key(AvahiDnsPacket *p, int *ret_unicast_response) { 6234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char name[256]; 6244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t type, class; 625f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 627f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6287dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 6297dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 6307dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0) 631f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 632f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6331ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (ret_unicast_response) 6341ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering *ret_unicast_response = !!(class & AVAHI_DNS_UNICAST_RESPONSE); 635f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6361ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering class &= ~AVAHI_DNS_UNICAST_RESPONSE; 6371ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 6387dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return avahi_key_new(name, class, type); 639f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 640f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_key(AvahiDnsPacket *p, AvahiKey *k, int unicast_response) { 6424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *t; 6434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t size; 644f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6454f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 6464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(k); 647f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 648d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering size = p->size; 649d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 6507dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(t = avahi_dns_packet_append_name(p, k->name)) || 6517dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, k->type) || 65214f8d9beb7ef14b0aab5512345e09109bdd8cb0cLennart Poettering !avahi_dns_packet_append_uint16(p, k->clazz | (unicast_response ? AVAHI_DNS_UNICAST_RESPONSE : 0))) { 653d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 654f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 655d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering } 656f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 657f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return t; 658f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 659f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6604f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_record(AvahiDnsPacket *p, AvahiRecord *r, int cache_flush, unsigned max_ttl) { 6614f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *t, *l, *start; 6624f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t size; 663f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 6654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(r); 66654247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 667d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering size = p->size; 668d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 6697dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(t = avahi_dns_packet_append_name(p, r->key->name)) || 6707dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->key->type) || 67114f8d9beb7ef14b0aab5512345e09109bdd8cb0cLennart Poettering !avahi_dns_packet_append_uint16(p, cache_flush ? (r->key->clazz | AVAHI_DNS_CACHE_FLUSH) : (r->key->clazz &~ AVAHI_DNS_CACHE_FLUSH)) || 672602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering !avahi_dns_packet_append_uint32(p, (max_ttl && r->ttl > max_ttl) ? max_ttl : r->ttl) || 6737dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !(l = avahi_dns_packet_append_uint16(p, 0))) 674d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering goto fail; 67554247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 6767dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering start = avahi_dns_packet_extend(p, 0); 677a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 678c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering switch (r->key->type) { 679c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 6807dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 6817dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_CNAME : 682c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 6837dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(avahi_dns_packet_append_name(p, r->data.ptr.name))) 684a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 685c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 686a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 687a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 6887dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 689a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 6907dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_uint16(p, r->data.srv.priority) || 6917dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.weight) || 6927dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.port) || 6937dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_name(p, r->data.srv.name)) 694d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering goto fail; 695c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 696c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 697c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 6987dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 6997dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_string(p, r->data.hinfo.cpu) || 7007dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_string(p, r->data.hinfo.os)) 701a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 702a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 703a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 704a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7057dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: { 706a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7074f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *data; 7084f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t n; 709c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 71066142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = avahi_string_list_serialize(r->data.txt.string_list, NULL, 0); 711c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 71266142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering/* avahi_log_debug("appending string: %u %p", n, r->data.txt.string_list); */ 713a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 71466142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (!(data = avahi_dns_packet_extend(p, n))) 715d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering goto fail; 716c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 71766142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_string_list_serialize(r->data.txt.string_list, data, n); 718c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 719c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 720c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 721a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7227dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 723a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7247dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.a.address, sizeof(r->data.a.address))) 725a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 726a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 727a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 728a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7297dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 730a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7317dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.aaaa.address, sizeof(r->data.aaaa.address))) 732a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 733a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 734a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 735a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 736c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 737a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 738a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (r->data.generic.size && 7397dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_append_bytes(p, r->data.generic.data, r->data.generic.size)) 740d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering goto fail; 741a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 742a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 743c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 744c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 745a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 746a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 747a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7487dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering size = avahi_dns_packet_extend(p, 0) - start; 7494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(size <= 0xFFFF); 750a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 751c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("appended %u", size); */ 752a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering * (uint16_t*) l = htons((uint16_t) size); 754a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 75554247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return t; 756d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 757d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 758d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poetteringfail: 759d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 760d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering return NULL; 761d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering} 762d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 7634f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_empty(AvahiDnsPacket *p) { 7644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 765d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 7667dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return p->size <= AVAHI_DNS_PACKET_HEADER_SIZE; 767f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 7680a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 7694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringsize_t avahi_dns_packet_space(AvahiDnsPacket *p) { 7704f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 7710a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 7724f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p->size <= p->max_size); 7730a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 7740a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering return p->max_size - p->size; 7750a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering} 776