dns.c revision 6e9695a1e6a5f6a70195b6de37448aaf9cde8e30
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 264ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <stdlib.h> 274ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <string.h> 284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <stdio.h> 294f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include <assert.h> 304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 31eee711106f721fc73a1ef50348984b7a1d9cb595Sebastien Estienne#include <netinet/in.h> 32eee711106f721fc73a1ef50348984b7a1d9cb595Sebastien Estienne 33f6712902a92eb82b6c8d7e7fd0980a20a716fa0dLennart Poettering#include <avahi-common/defs.h> 345ebf655c85076f200955458673a8bbf0dd927407Lennart Poettering#include <avahi-common/domain.h> 354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include <avahi-common/malloc.h> 364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 374ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include "dns.h" 384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include "log.h" 394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 404f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new(unsigned mtu) { 417dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t max_size; 43c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 44602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (mtu <= 0) 453073103812f0ea376582eb0ff1479945a847b361Lennart Poettering max_size = AVAHI_DNS_PACKET_SIZE_MAX; 46b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering else if (mtu >= AVAHI_DNS_PACKET_EXTRA_SIZE) 47b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering max_size = mtu - AVAHI_DNS_PACKET_EXTRA_SIZE; 48602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering else 49602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering max_size = 0; 50602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 51602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (max_size < AVAHI_DNS_PACKET_HEADER_SIZE) 527dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering max_size = AVAHI_DNS_PACKET_HEADER_SIZE; 53c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 544f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_malloc(sizeof(AvahiDnsPacket) + max_size))) 554f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return p; 564f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 577dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering p->size = p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 58c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->max_size = max_size; 594ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering p->name_table = NULL; 60943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p->data = NULL; 61c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 627dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memset(AVAHI_DNS_PACKET_DATA(p), 0, p->size); 63c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 64c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 65c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 664f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_query(unsigned mtu) { 677dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 68c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 704f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 714f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 727dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); 73c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 74c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 75c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 764f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_response(unsigned mtu, int aa) { 777dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 78c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 794f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 804f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 814f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 828d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(1, 0, aa, 0, 0, 0, 0, 0, 0, 0)); 834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return p; 844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 864f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_reply(AvahiDnsPacket* p, unsigned mtu, int copy_queries, int aa) { 87602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiDnsPacket *r; 884f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 89602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(r = avahi_dns_packet_new_response(mtu, aa))) 914f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 92602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 93602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (copy_queries) { 944f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned saved_rindex; 954f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint32_t n; 96602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 97602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering saved_rindex = p->rindex; 98602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 99602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 100602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT); n > 0; n--) { 101602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiKey *k; 1024f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int unicast_response; 103602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 104602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if ((k = avahi_dns_packet_consume_key(p, &unicast_response))) { 105602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_append_key(r, k, unicast_response); 106602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_key_unref(k); 107602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 108602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 109602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 110602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = saved_rindex; 111602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 112602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_QDCOUNT, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT)); 113602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 114602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 115602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_ID, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ID)); 116602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 117602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_FLAGS, 118602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering (avahi_dns_packet_get_field(r, AVAHI_DNS_FIELD_FLAGS) & ~AVAHI_DNS_FLAG_OPCODE) | 1198d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_OPCODE)); 120602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 121602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering return r; 122602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering} 123602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 124602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 1257dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poetteringvoid avahi_dns_packet_free(AvahiDnsPacket *p) { 1264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1274ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1284ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (p->name_table) 1294f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_free(p->name_table); 1304ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1314f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_free(p); 1324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1334ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_set_field(AvahiDnsPacket *p, unsigned idx, uint16_t v) { 1354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 1374ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering ((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx] = htons(v); 1394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1404ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint16_t avahi_dns_packet_get_field(AvahiDnsPacket *p, unsigned idx) { 1424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 1444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1454f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return ntohs(((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx]); 1464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1484f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_inc_field(AvahiDnsPacket *p, unsigned idx) { 1494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 151af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 15266142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_dns_packet_set_field(p, idx, avahi_dns_packet_get_field(p, idx) + 1); 153af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering} 154af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 1554f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_name(AvahiDnsPacket *p, const char *name) { 1564f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d, *saved_ptr = NULL; 1574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t saved_size; 1584ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1594f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1604f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(name); 1614ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 162c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering saved_size = p->size; 1637dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering saved_ptr = avahi_dns_packet_extend(p, 0); 1644c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering 1654e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering while (*name) { 1664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* prev; 1674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const char *pname; 1684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char label[64], *u; 1694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 1704ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering /* Check whether we can compress this name. */ 1714ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1724f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->name_table && (prev = avahi_hashmap_lookup(p->name_table, name))) { 1734f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned idx; 1744ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1754f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(prev >= AVAHI_DNS_PACKET_DATA(p)); 1764f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering idx = (unsigned) (prev - AVAHI_DNS_PACKET_DATA(p)); 1774ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < p->size); 1794ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 18066142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx < 0x4000) { 181973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t *t; 182973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering if (!(t = (uint8_t*) avahi_dns_packet_extend(p, sizeof(uint16_t)))) 1834ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering return NULL; 1844ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 185973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering t[0] = (uint8_t) ((0xC000 | idx) >> 8); 186973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering t[1] = (uint8_t) idx; 1874c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 1884ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 1894ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 1904e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 1914e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering pname = name; 1924ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 193a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering if (!(avahi_unescape_label(&name, label, sizeof(label)))) 194c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 1954ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1967dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_append_string(p, label))) 1974e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering goto fail; 1984c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering 1994ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (!p->name_table) 200a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering /* This works only for normalized domain names */ 2014f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->name_table = avahi_hashmap_new(avahi_string_hash, avahi_string_equal, avahi_free, NULL); 2024ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 2034f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(u = avahi_strdup(pname))) 2044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_log_error("avahi_strdup() failed."); 2054f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering else 2064f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_insert(p->name_table, u, d); 2074ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 2084ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2097dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, 1))) 210c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 211c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2124e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering *d = 0; 2134ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2144c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 215c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 216c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poetteringfail: 217c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->size = saved_size; 218c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 2194ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2204ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2214f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_uint16(AvahiDnsPacket *p, uint16_t v) { 2224f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2244ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2254f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint16_t)))) 226c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 2274ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 228973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[0] = (uint8_t) (v >> 8); 229973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[1] = (uint8_t) v; 2304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 2314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_uint32(AvahiDnsPacket *p, uint32_t v) { 2344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 236c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint32_t)))) 238c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 239c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 240973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[0] = (uint8_t) (v >> 24); 241973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[1] = (uint8_t) (v >> 16); 242973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[2] = (uint8_t) (v >> 8); 243973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[3] = (uint8_t) v; 24454247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 24554247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 24654247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 24754247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2484f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_bytes(AvahiDnsPacket *p, const void *b, size_t l) { 2494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 25054247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2524f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(b); 2534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l); 2544aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 2557dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, l))) 256c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 25754247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 258c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering memcpy(d, b, l); 25954247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 26054247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 26154247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2624f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_string(AvahiDnsPacket *p, const char *s) { 2634f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 2644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 265a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 268a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 269a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if ((k = strlen(s)) >= 255) 270a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering k = 255; 271a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2727dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, k+1))) 273a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 274a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2754f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *d = (uint8_t) k; 276a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering memcpy(d+1, s, k); 277a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 278a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return d; 279a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 280a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2814f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_extend(AvahiDnsPacket *p, size_t l) { 2824f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2844f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 286c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering if (p->size+l > p->max_size) 287c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 288c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2897dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering d = AVAHI_DNS_PACKET_DATA(p) + p->size; 2904ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->size += l; 2914ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2924ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 2934ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2944ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2951ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid(AvahiDnsPacket *p) { 2964f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t flags; 2974f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2984ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2991ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (p->size < AVAHI_DNS_PACKET_HEADER_SIZE) 3004ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3027dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 3031ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3041ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_OPCODE) 3051ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 3061ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3071ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return 0; 3081ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering} 3091ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3101ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid_multicast(AvahiDnsPacket *p) { 3111ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering uint16_t flags; 3121ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering assert(p); 3134ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3141ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (avahi_dns_packet_check_valid(p) < 0) 3151ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 3161ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3171ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 3181ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3191ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_RCODE) 3204ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3214ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3224ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 3234ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3244ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3254f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_query(AvahiDnsPacket *p) { 3264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 3274ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3287dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return !(avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_QR); 3294ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3314f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic int consume_labels(AvahiDnsPacket *p, unsigned idx, char *ret_name, size_t l) { 3324f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int ret = 0; 3334ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int compressed = 0; 3344ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int first_label = 1; 3355ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd unsigned label_ptr; 33683b432c2369d7ef4142811bea0109b6588b6f313Trent Lloyd int i; 3374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p && ret_name && l); 3384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 339451be30b300b390b46738af3fd24fc942ba3158fTrent Lloyd for (i = 0; i < AVAHI_DNS_LABELS_MAX; i++) { 3404f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t n; 3414ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 34266142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+1 > p->size) 3434ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 34566142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = AVAHI_DNS_PACKET_DATA(p)[idx]; 3464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!n) { 34866142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3494ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3504ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 3514ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3524ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (l < 1) 3534ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3544ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *ret_name = 0; 3554ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3564ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return ret; 3574ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3584ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if (n <= 63) { 3594ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Uncompressed label */ 36066142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3614ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3624ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 3634ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 36466142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx + n > p->size) 3654ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3664ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((size_t) n + 1 > l) 3684ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3694ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3704ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!first_label) { 3714ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *(ret_name++) = '.'; 3724ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering l--; 3734ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 3744ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering first_label = 0; 3754ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 376d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering if (!(avahi_escape_label((char*) AVAHI_DNS_PACKET_DATA(p) + idx, n, &ret_name, &l))) 3774e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering return -1; 3784e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 37966142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx += n; 3804ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3814ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3824ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += n; 3834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if ((n & 0xC0) == 0xC0) { 3844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Compressed label */ 3854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 38666142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+2 > p->size) 3874ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3884ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3895ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd label_ptr = ((unsigned) (AVAHI_DNS_PACKET_DATA(p)[idx] & ~0xC0)) << 8 | AVAHI_DNS_PACKET_DATA(p)[idx+1]; 3905ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd 3915ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd if ((label_ptr < AVAHI_DNS_PACKET_HEADER_SIZE) || (label_ptr >= idx)) 3925ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd return -1; 3935ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd 3945ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd idx = label_ptr; 3954ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3964ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3974ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += 2; 3984ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3994ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering compressed = 1; 4004ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 4014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4024ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 4036e9695a1e6a5f6a70195b6de37448aaf9cde8e30Trent Lloyd 4046e9695a1e6a5f6a70195b6de37448aaf9cde8e30Trent Lloyd return -1; 4054ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4064ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4074f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_name(AvahiDnsPacket *p, char *ret_name, size_t l) { 4084f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int r; 4094ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4104ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if ((r = consume_labels(p, p->rindex, ret_name, l)) < 0) 4114ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4124ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4134ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += r; 4144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4154ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4164ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4174f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint16(AvahiDnsPacket *p, uint16_t *ret_v) { 418973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t *d; 419973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering 4204f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4214f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4224ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint16_t) > p->size) 4244ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 426973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d = (uint8_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex); 427973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering *ret_v = (d[0] << 8) | d[1]; 4284f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint16_t); 4294ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint32(AvahiDnsPacket *p, uint32_t *ret_v) { 434973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t* d; 435973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering 4364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4394f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint32_t) > p->size) 4404ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4414ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 442973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d = (uint8_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex); 443973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering *ret_v = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]; 4444f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint32_t); 4454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4484ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_bytes(AvahiDnsPacket *p, void * ret_data, size_t l) { 4504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_data); 4524f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 4534ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4544ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + l > p->size) 4554ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4564ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4577dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_data, AVAHI_DNS_PACKET_DATA(p) + p->rindex, l); 4584ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += l; 4594ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4604ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4614ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4624ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4634f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_string(AvahiDnsPacket *p, char *ret_string, size_t l) { 4644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 465a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_string); 4684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 469a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 470a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex >= p->size) 471a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 472a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4737dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering k = AVAHI_DNS_PACKET_DATA(p)[p->rindex]; 474a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 475a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex+1+k > p->size) 476a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 477a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 478a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (l > k+1) 479a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering l = k+1; 480a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4817dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_string, AVAHI_DNS_PACKET_DATA(p)+p->rindex+1, l-1); 482a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering ret_string[l-1] = 0; 483a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 484a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering p->rindex += 1+k; 485a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 486a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return 0; 487a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 488a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringconst void* avahi_dns_packet_get_rptr(AvahiDnsPacket *p) { 4904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 491f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 492a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex > p->size) 493f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 494f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4957dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return AVAHI_DNS_PACKET_DATA(p) + p->rindex; 496f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 497f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4984f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_skip(AvahiDnsPacket *p, size_t length) { 4994f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 5004ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 5014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + length > p->size) 5024ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 5034ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 5044ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += length; 5054ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 5064ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 507f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 508943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringstatic int parse_rdata(AvahiDnsPacket *p, AvahiRecord *r, uint16_t rdlength) { 509943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering char buf[AVAHI_DOMAIN_NAME_MAX]; 5104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const void* start; 511943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5124f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 513943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(r); 514f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 5157dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering start = avahi_dns_packet_get_rptr(p); 516943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 517943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering switch (r->key->type) { 5187dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 5197dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_CNAME: 520d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_NS: 521a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5227dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 523943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 524a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5254f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.ptr.name = avahi_strdup(buf); 526a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 527a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 528c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5297dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 530a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5317dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_uint16(p, &r->data.srv.priority) < 0 || 5327dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.weight) < 0 || 5337dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.port) < 0 || 5347dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 535943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 536a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.srv.name = avahi_strdup(buf); 538a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 539a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5407dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 541a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5427dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 543943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 544943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5454f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.cpu = avahi_strdup(buf); 546943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5477dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 548943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 549943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.os = avahi_strdup(buf); 551c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 552c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5537dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: 554a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 555a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (rdlength > 0) { 55620011324500a728851e4888c890a756ecf71394bLennart Poettering if (avahi_string_list_parse(avahi_dns_packet_get_rptr(p), rdlength, &r->data.txt.string_list) < 0) 55720011324500a728851e4888c890a756ecf71394bLennart Poettering return -1; 558a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5597dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 560943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 561fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering } else 562fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering r->data.txt.string_list = NULL; 563c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 564a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 565a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5667dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 567a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 568c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("A"); */ 569c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5707dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.a.address, sizeof(AvahiIPv4Address)) < 0) 571943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 572a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 573a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 574a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5757dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 576a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 577c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("aaaa"); */ 578a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5797dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.aaaa.address, sizeof(AvahiIPv6Address)) < 0) 580943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 581a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 582c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 583c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 584c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 5854aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 586c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("generic"); */ 587a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5884aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering if (rdlength > 0) { 5894aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 5904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.generic.data = avahi_memdup(avahi_dns_packet_get_rptr(p), rdlength); 591a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5927dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 593943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 594a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering } 595c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 596c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 597c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 598c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 599a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering /* Check if we read enough data */ 6004f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((const uint8_t*) avahi_dns_packet_get_rptr(p) - (const uint8_t*) start != rdlength) 601943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 602943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 603943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return 0; 604943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 605943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 606943a6b93697fc0a7bcd0cc574744d7de609c189cLennart PoetteringAvahiRecord* avahi_dns_packet_consume_record(AvahiDnsPacket *p, int *ret_cache_flush) { 607943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering char name[AVAHI_DOMAIN_NAME_MAX]; 608943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint16_t type, class; 609943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint32_t ttl; 610943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint16_t rdlength; 611943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiRecord *r = NULL; 612943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 613943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(p); 614943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 615943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 616943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 617943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0 || 618943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint32(p, &ttl) < 0 || 619943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &rdlength) < 0 || 620943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p->rindex + rdlength > p->size) 621a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 622a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 623943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (ret_cache_flush) 624943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering *ret_cache_flush = !!(class & AVAHI_DNS_CACHE_FLUSH); 625943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering class &= ~AVAHI_DNS_CACHE_FLUSH; 626943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 627943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (!(r = avahi_record_new_full(name, class, type, ttl))) 628943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 629943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 630943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (parse_rdata(p, r, rdlength) < 0) 631943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 6327e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6337e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!avahi_record_is_valid(r)) 6347e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering goto fail; 635943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 636a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return r; 637a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 638a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poetteringfail: 639a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (r) 6407dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_record_unref(r); 641a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 642a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 643f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 644f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6454f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiKey* avahi_dns_packet_consume_key(AvahiDnsPacket *p, int *ret_unicast_response) { 6464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char name[256]; 6474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t type, class; 6487e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering AvahiKey *k; 649f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 651f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6527dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 6537dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 6547dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0) 655f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 656f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6571ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (ret_unicast_response) 6581ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering *ret_unicast_response = !!(class & AVAHI_DNS_UNICAST_RESPONSE); 659f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6601ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering class &= ~AVAHI_DNS_UNICAST_RESPONSE; 6611ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 6627e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!(k = avahi_key_new(name, class, type))) 6637e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return NULL; 6647e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6657e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!avahi_key_is_valid(k)) { 6667e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering avahi_key_unref(k); 6677e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return NULL; 6687e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering } 6697e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6707e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return k; 671f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 672f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6734f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_key(AvahiDnsPacket *p, AvahiKey *k, int unicast_response) { 6744f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *t; 6754f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t size; 676f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6774f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 6784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(k); 679f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 680d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering size = p->size; 681d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 6827dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(t = avahi_dns_packet_append_name(p, k->name)) || 6837dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, k->type) || 68414f8d9beb7ef14b0aab5512345e09109bdd8cb0cLennart Poettering !avahi_dns_packet_append_uint16(p, k->clazz | (unicast_response ? AVAHI_DNS_UNICAST_RESPONSE : 0))) { 685d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 686f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 687d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering } 688f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 689f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return t; 690f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 691f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 692943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringstatic int append_rdata(AvahiDnsPacket *p, AvahiRecord *r) { 6934f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 6944f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(r); 695943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 696c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering switch (r->key->type) { 697c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 6987dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 699d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_CNAME: 700d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_NS: 701d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering 7027dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(avahi_dns_packet_append_name(p, r->data.ptr.name))) 703943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 704c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 705a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 706a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7077dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 708a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7097dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_uint16(p, r->data.srv.priority) || 7107dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.weight) || 7117dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.port) || 7127dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_name(p, r->data.srv.name)) 713943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 714c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 715c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 716c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 7177dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 7187dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_string(p, r->data.hinfo.cpu) || 7197dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_string(p, r->data.hinfo.os)) 720943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 721a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 722a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 723a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7247dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: { 725a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *data; 7274f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t n; 728c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 72966142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = avahi_string_list_serialize(r->data.txt.string_list, NULL, 0); 730c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 73166142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (!(data = avahi_dns_packet_extend(p, n))) 732943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 733c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 73466142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_string_list_serialize(r->data.txt.string_list, data, n); 735c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 736c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 737c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 738a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7397dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 740a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7417dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.a.address, sizeof(r->data.a.address))) 742943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 743a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 744a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 745a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7467dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 747a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7487dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.aaaa.address, sizeof(r->data.aaaa.address))) 749943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 750a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 751a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 752a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 753c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 754a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 755943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (r->data.generic.size) 756943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (avahi_dns_packet_append_bytes(p, r->data.generic.data, r->data.generic.size)) 757943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 758a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 759a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 760c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 761c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 762943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return 0; 763943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 764943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 765a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 766943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringuint8_t* avahi_dns_packet_append_record(AvahiDnsPacket *p, AvahiRecord *r, int cache_flush, unsigned max_ttl) { 767943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint8_t *t, *l, *start; 768943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering size_t size; 769943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 770943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(p); 771943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(r); 772943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 773943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering size = p->size; 774943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 775943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (!(t = avahi_dns_packet_append_name(p, r->key->name)) || 776943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint16(p, r->key->type) || 777943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint16(p, cache_flush ? (r->key->clazz | AVAHI_DNS_CACHE_FLUSH) : (r->key->clazz &~ AVAHI_DNS_CACHE_FLUSH)) || 778943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint32(p, (max_ttl && r->ttl > max_ttl) ? max_ttl : r->ttl) || 779943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !(l = avahi_dns_packet_append_uint16(p, 0))) 780943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 781943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 782943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering start = avahi_dns_packet_extend(p, 0); 783a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 784943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (append_rdata(p, r) < 0) 785943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 786a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7877dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering size = avahi_dns_packet_extend(p, 0) - start; 7884f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(size <= 0xFFFF); 789a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 790c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("appended %u", size); */ 791a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 792973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering l[0] = (uint8_t) ((uint16_t) size >> 8); 793973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering l[1] = (uint8_t) ((uint16_t) size); 794a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 79554247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return t; 796d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 797d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 798d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poetteringfail: 799d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 800d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering return NULL; 801d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering} 802d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 8034f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_empty(AvahiDnsPacket *p) { 8044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 805d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 8067dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return p->size <= AVAHI_DNS_PACKET_HEADER_SIZE; 807f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 8080a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8094f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringsize_t avahi_dns_packet_space(AvahiDnsPacket *p) { 8104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 8110a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8124f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p->size <= p->max_size); 8130a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8140a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering return p->max_size - p->size; 8150a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering} 816943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 817943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringint avahi_rdata_parse(AvahiRecord *record, const void* rdata, size_t size) { 818943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering int ret; 819943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiDnsPacket p; 820943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 821943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(record); 822943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(rdata); 823943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 824943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.data = (void*) rdata; 825943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.max_size = p.size = size; 826943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.rindex = 0; 827943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.name_table = NULL; 828943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 829943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering ret = parse_rdata(&p, record, size); 830943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 831943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(!p.name_table); 832943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 833943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return ret; 834943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 835943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 836943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringsize_t avahi_rdata_serialize(AvahiRecord *record, void *rdata, size_t max_size) { 837943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering int ret; 838943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiDnsPacket p; 839943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 840943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(record); 841943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(rdata); 842943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(max_size > 0); 843943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 844943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.data = (void*) rdata; 845943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.max_size = max_size; 846943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.size = p.rindex = 0; 847943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.name_table = NULL; 848943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 849943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering ret = append_rdata(&p, record); 850943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 851943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (p.name_table) 852943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_hashmap_free(p.name_table); 853943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 854943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (ret < 0) 855943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return (size_t) -1; 856943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 857943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return p.size; 858943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 859