dns.c revision bbf6b92f662ed909d5b4fca4a43b19e815812b3e
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 31b91e3b47eaed054189c45c070002f291d7d11166Lennart Poettering#include <sys/types.h> 32eee711106f721fc73a1ef50348984b7a1d9cb595Sebastien Estienne#include <netinet/in.h> 33eee711106f721fc73a1ef50348984b7a1d9cb595Sebastien Estienne 34f6712902a92eb82b6c8d7e7fd0980a20a716fa0dLennart Poettering#include <avahi-common/defs.h> 355ebf655c85076f200955458673a8bbf0dd927407Lennart Poettering#include <avahi-common/domain.h> 364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include <avahi-common/malloc.h> 374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include "dns.h" 394f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include "log.h" 404ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 414f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new(unsigned mtu) { 427dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t max_size; 44c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 45602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (mtu <= 0) 463073103812f0ea376582eb0ff1479945a847b361Lennart Poettering max_size = AVAHI_DNS_PACKET_SIZE_MAX; 47b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering else if (mtu >= AVAHI_DNS_PACKET_EXTRA_SIZE) 48b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering max_size = mtu - AVAHI_DNS_PACKET_EXTRA_SIZE; 49602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering else 50602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering max_size = 0; 51602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 52602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (max_size < AVAHI_DNS_PACKET_HEADER_SIZE) 537dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering max_size = AVAHI_DNS_PACKET_HEADER_SIZE; 54c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 554f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_malloc(sizeof(AvahiDnsPacket) + max_size))) 564f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return p; 574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 587dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering p->size = p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 59c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->max_size = max_size; 604ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering p->name_table = NULL; 61943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p->data = NULL; 62c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 637dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memset(AVAHI_DNS_PACKET_DATA(p), 0, p->size); 64c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 65c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 66c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 674f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_query(unsigned mtu) { 687dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 69c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 704f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 714f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 724f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 737dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); 74c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 75c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 76c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 774f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_response(unsigned mtu, int aa) { 787dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 79c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 804f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 814f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 824f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 838d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(1, 0, aa, 0, 0, 0, 0, 0, 0, 0)); 844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return p; 854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 864ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 874f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_reply(AvahiDnsPacket* p, unsigned mtu, int copy_queries, int aa) { 88602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiDnsPacket *r; 894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 90602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 914f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(r = avahi_dns_packet_new_response(mtu, aa))) 924f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 93602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 94602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (copy_queries) { 954f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned saved_rindex; 964f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint32_t n; 97602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 98602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering saved_rindex = p->rindex; 99602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 100602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 101602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT); n > 0; n--) { 102602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiKey *k; 1034f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int unicast_response; 104602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 105602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if ((k = avahi_dns_packet_consume_key(p, &unicast_response))) { 106602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_append_key(r, k, unicast_response); 107602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_key_unref(k); 108602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 109602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 110602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 111602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = saved_rindex; 112602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 113602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_QDCOUNT, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT)); 114602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 115602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 116602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_ID, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ID)); 117602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 118602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_FLAGS, 119602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering (avahi_dns_packet_get_field(r, AVAHI_DNS_FIELD_FLAGS) & ~AVAHI_DNS_FLAG_OPCODE) | 1208d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_OPCODE)); 121602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 122602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering return r; 123602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering} 124602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 125602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 1267dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poetteringvoid avahi_dns_packet_free(AvahiDnsPacket *p) { 1274f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1284ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1294ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (p->name_table) 1304f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_free(p->name_table); 1314ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1324f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_free(p); 1334ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1344ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_set_field(AvahiDnsPacket *p, unsigned idx, uint16_t v) { 1364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 1384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1394f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering ((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx] = htons(v); 1404ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1414ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint16_t avahi_dns_packet_get_field(AvahiDnsPacket *p, unsigned idx) { 1434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1444f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 1454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return ntohs(((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx]); 1474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1484ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_inc_field(AvahiDnsPacket *p, unsigned idx) { 1504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 152af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 15366142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_dns_packet_set_field(p, idx, avahi_dns_packet_get_field(p, idx) + 1); 154af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering} 155af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 1564f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_name(AvahiDnsPacket *p, const char *name) { 1574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d, *saved_ptr = NULL; 1584f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t saved_size; 1594ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1604f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1614f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(name); 1624ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 163c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering saved_size = p->size; 1647dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering saved_ptr = avahi_dns_packet_extend(p, 0); 1654c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering 1664e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering while (*name) { 1674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* prev; 1684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const char *pname; 1694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char label[64], *u; 1704f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 1714ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering /* Check whether we can compress this name. */ 1724ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1734f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->name_table && (prev = avahi_hashmap_lookup(p->name_table, name))) { 1744f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned idx; 1754ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1764f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(prev >= AVAHI_DNS_PACKET_DATA(p)); 1774f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering idx = (unsigned) (prev - AVAHI_DNS_PACKET_DATA(p)); 1784ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1794f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < p->size); 1804ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 18166142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx < 0x4000) { 182973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t *t; 183973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering if (!(t = (uint8_t*) avahi_dns_packet_extend(p, sizeof(uint16_t)))) 1844ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering return NULL; 1854ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 186973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering t[0] = (uint8_t) ((0xC000 | idx) >> 8); 187973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering t[1] = (uint8_t) idx; 1884c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 1894ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 1904ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 1914e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 1924e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering pname = name; 1934ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 194a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering if (!(avahi_unescape_label(&name, label, sizeof(label)))) 195c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 1964ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1977dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_append_string(p, label))) 1984e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering goto fail; 1994c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering 2004ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (!p->name_table) 201a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering /* This works only for normalized domain names */ 2024f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->name_table = avahi_hashmap_new(avahi_string_hash, avahi_string_equal, avahi_free, NULL); 2034ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 2044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(u = avahi_strdup(pname))) 2054f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_log_error("avahi_strdup() failed."); 2064f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering else 2074f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_insert(p->name_table, u, d); 2084ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 2094ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2107dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, 1))) 211c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 212c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2134e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering *d = 0; 2144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2154c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 216c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 217c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poetteringfail: 218c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->size = saved_size; 219c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 2204ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2214ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2224f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_uint16(AvahiDnsPacket *p, uint16_t v) { 2234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint16_t)))) 227c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 2284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 229973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[0] = (uint8_t) (v >> 8); 230973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[1] = (uint8_t) v; 2314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 2324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2334ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_uint32(AvahiDnsPacket *p, uint32_t v) { 2354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 237c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint32_t)))) 239c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 240c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 241973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[0] = (uint8_t) (v >> 24); 242973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[1] = (uint8_t) (v >> 16); 243973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[2] = (uint8_t) (v >> 8); 244973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[3] = (uint8_t) v; 24554247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 24654247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 24754247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 24854247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_bytes(AvahiDnsPacket *p, const void *b, size_t l) { 2504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 25154247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2524f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(b); 2544f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l); 2554aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 2567dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, l))) 257c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 25854247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 259c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering memcpy(d, b, l); 26054247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 26154247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 26254247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2634f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_string(AvahiDnsPacket *p, const char *s) { 2644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 2654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 266a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 269a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 270a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if ((k = strlen(s)) >= 255) 271a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering k = 255; 272a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2737dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, k+1))) 274a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 275a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2764f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *d = (uint8_t) k; 277a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering memcpy(d+1, s, k); 278a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 279a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return d; 280a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 281a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2824f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_extend(AvahiDnsPacket *p, size_t l) { 2834f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2854f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2864ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 287c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering if (p->size+l > p->max_size) 288c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 289c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2907dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering d = AVAHI_DNS_PACKET_DATA(p) + p->size; 2914ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->size += l; 2924ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2934ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 2944ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2954ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2961ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid(AvahiDnsPacket *p) { 2974f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t flags; 2984f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2994ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3001ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (p->size < AVAHI_DNS_PACKET_HEADER_SIZE) 3014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3024ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3037dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 3041ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3051ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_OPCODE) 3061ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 3071ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3081ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return 0; 3091ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering} 3101ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3111ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid_multicast(AvahiDnsPacket *p) { 3121ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering uint16_t flags; 3131ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering assert(p); 3144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3151ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (avahi_dns_packet_check_valid(p) < 0) 3161ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 3171ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3181ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 3191ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3201ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_RCODE) 3214ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3224ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3234ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 3244ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_query(AvahiDnsPacket *p) { 3274f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 3284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3297dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return !(avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_QR); 3304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3324f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic int consume_labels(AvahiDnsPacket *p, unsigned idx, char *ret_name, size_t l) { 3334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int ret = 0; 3344ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int compressed = 0; 3354ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int first_label = 1; 3365ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd unsigned label_ptr; 33783b432c2369d7ef4142811bea0109b6588b6f313Trent Lloyd int i; 3384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p && ret_name && l); 3394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 340451be30b300b390b46738af3fd24fc942ba3158fTrent Lloyd for (i = 0; i < AVAHI_DNS_LABELS_MAX; i++) { 3414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t n; 3424ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 34366142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+1 > p->size) 3444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 34666142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = AVAHI_DNS_PACKET_DATA(p)[idx]; 3474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3484ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!n) { 34966142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3504ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3514ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 3524ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3534ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (l < 1) 3544ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3554ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *ret_name = 0; 3564ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3574ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return ret; 3584ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3594ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if (n <= 63) { 3604ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Uncompressed label */ 36166142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3624ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3634ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 3644ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 36566142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx + n > p->size) 3664ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3674ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((size_t) n + 1 > l) 3694ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3704ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3714ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!first_label) { 3724ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *(ret_name++) = '.'; 3734ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering l--; 3744ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 3754ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering first_label = 0; 3764ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 377d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering if (!(avahi_escape_label((char*) AVAHI_DNS_PACKET_DATA(p) + idx, n, &ret_name, &l))) 3784e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering return -1; 3794e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 38066142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx += n; 3814ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3824ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += n; 3844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if ((n & 0xC0) == 0xC0) { 3854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Compressed label */ 3864ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 38766142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+2 > p->size) 3884ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3894ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3905ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd label_ptr = ((unsigned) (AVAHI_DNS_PACKET_DATA(p)[idx] & ~0xC0)) << 8 | AVAHI_DNS_PACKET_DATA(p)[idx+1]; 3915ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd 3925ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd if ((label_ptr < AVAHI_DNS_PACKET_HEADER_SIZE) || (label_ptr >= idx)) 3935ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd return -1; 3945ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd 3955ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd idx = label_ptr; 3964ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3974ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3984ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += 2; 3994ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4004ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering compressed = 1; 4014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 4024ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4034ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 4046e9695a1e6a5f6a70195b6de37448aaf9cde8e30Trent Lloyd 4056e9695a1e6a5f6a70195b6de37448aaf9cde8e30Trent Lloyd return -1; 4064ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4074ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4084f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_name(AvahiDnsPacket *p, char *ret_name, size_t l) { 4094f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int r; 4104ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4114ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if ((r = consume_labels(p, p->rindex, ret_name, l)) < 0) 4124ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4134ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += r; 4154ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4164ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4174ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4184f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint16(AvahiDnsPacket *p, uint16_t *ret_v) { 419973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t *d; 420973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering 4214f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4224f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4234ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint16_t) > p->size) 4254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4264ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 427973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d = (uint8_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex); 428973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering *ret_v = (d[0] << 8) | d[1]; 4294f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint16_t); 4304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4334ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint32(AvahiDnsPacket *p, uint32_t *ret_v) { 435973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t* d; 436973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering 4374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4404f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint32_t) > p->size) 4414ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4424ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 443973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d = (uint8_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex); 444973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering *ret_v = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]; 4454f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint32_t); 4464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4484ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4494ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_bytes(AvahiDnsPacket *p, void * ret_data, size_t l) { 4514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4524f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_data); 4534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 4544ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4554ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + l > p->size) 4564ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4574ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4587dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_data, AVAHI_DNS_PACKET_DATA(p) + p->rindex, l); 4594ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += l; 4604ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4614ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4624ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4634ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_string(AvahiDnsPacket *p, char *ret_string, size_t l) { 4654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 466a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_string); 4694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 470a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 471a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex >= p->size) 472a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 473a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4747dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering k = AVAHI_DNS_PACKET_DATA(p)[p->rindex]; 475a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 476a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex+1+k > p->size) 477a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 478a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 479a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (l > k+1) 480a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering l = k+1; 481a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4827dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_string, AVAHI_DNS_PACKET_DATA(p)+p->rindex+1, l-1); 483a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering ret_string[l-1] = 0; 484a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 485a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering p->rindex += 1+k; 486a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 487a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return 0; 488a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 489a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringconst void* avahi_dns_packet_get_rptr(AvahiDnsPacket *p) { 4914f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 492f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 493a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex > p->size) 494f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 495f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4967dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return AVAHI_DNS_PACKET_DATA(p) + p->rindex; 497f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 498f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 4994f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_skip(AvahiDnsPacket *p, size_t length) { 5004f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 5014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 5024ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + length > p->size) 5034ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 5044ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 5054ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += length; 5064ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 5074ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 508f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 509943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringstatic int parse_rdata(AvahiDnsPacket *p, AvahiRecord *r, uint16_t rdlength) { 510943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering char buf[AVAHI_DOMAIN_NAME_MAX]; 5114f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const void* start; 512943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5134f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 514943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(r); 515f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 5167dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering start = avahi_dns_packet_get_rptr(p); 517943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 518943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering switch (r->key->type) { 5197dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 5207dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_CNAME: 521d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_NS: 522a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5237dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 524943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 525a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.ptr.name = avahi_strdup(buf); 527a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 528a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 529c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5307dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 531a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5327dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_uint16(p, &r->data.srv.priority) < 0 || 5337dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.weight) < 0 || 5347dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.port) < 0 || 5357dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 536943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 537a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.srv.name = avahi_strdup(buf); 539a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 540a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5417dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 542a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5437dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 544943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 545943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.cpu = avahi_strdup(buf); 547943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5487dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 549943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 550943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 5514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.os = avahi_strdup(buf); 552c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 553c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5547dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: 555a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 556a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (rdlength > 0) { 55720011324500a728851e4888c890a756ecf71394bLennart Poettering if (avahi_string_list_parse(avahi_dns_packet_get_rptr(p), rdlength, &r->data.txt.string_list) < 0) 55820011324500a728851e4888c890a756ecf71394bLennart Poettering return -1; 559a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5607dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 561943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 562fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering } else 563fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering r->data.txt.string_list = NULL; 564c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 565a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 566a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5677dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 568a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 569c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("A"); */ 570c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5717dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.a.address, sizeof(AvahiIPv4Address)) < 0) 572943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 573a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 574a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 575a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5767dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 577a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 578c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("aaaa"); */ 579a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5807dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.aaaa.address, sizeof(AvahiIPv6Address)) < 0) 581943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 582a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 583c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 584c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 585c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 5864aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 587c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("generic"); */ 588a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5894aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering if (rdlength > 0) { 5904aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 5914f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.generic.data = avahi_memdup(avahi_dns_packet_get_rptr(p), rdlength); 592a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5937dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 594943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 595a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering } 596c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 597c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 598c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 599c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 600a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering /* Check if we read enough data */ 6014f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((const uint8_t*) avahi_dns_packet_get_rptr(p) - (const uint8_t*) start != rdlength) 602943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 603943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 604943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return 0; 605943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 606943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 607943a6b93697fc0a7bcd0cc574744d7de609c189cLennart PoetteringAvahiRecord* avahi_dns_packet_consume_record(AvahiDnsPacket *p, int *ret_cache_flush) { 608943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering char name[AVAHI_DOMAIN_NAME_MAX]; 609943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint16_t type, class; 610943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint32_t ttl; 611943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint16_t rdlength; 612943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiRecord *r = NULL; 613943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 614943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(p); 615943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 616943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 617943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 618943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0 || 619943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint32(p, &ttl) < 0 || 620943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &rdlength) < 0 || 621943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p->rindex + rdlength > p->size) 622a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 623a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 624943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (ret_cache_flush) 625943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering *ret_cache_flush = !!(class & AVAHI_DNS_CACHE_FLUSH); 626943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering class &= ~AVAHI_DNS_CACHE_FLUSH; 627943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 628943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (!(r = avahi_record_new_full(name, class, type, ttl))) 629943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 630943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 631943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (parse_rdata(p, r, rdlength) < 0) 632943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 6337e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6347e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!avahi_record_is_valid(r)) 6357e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering goto fail; 636943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 637a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return r; 638a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 639a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poetteringfail: 640a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (r) 6417dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_record_unref(r); 642a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 643a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 644f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 645f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6464f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiKey* avahi_dns_packet_consume_key(AvahiDnsPacket *p, int *ret_unicast_response) { 6474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char name[256]; 6484f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t type, class; 6497e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering AvahiKey *k; 650f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 652f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6537dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 6547dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 6557dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0) 656f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 657f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6581ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (ret_unicast_response) 6591ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering *ret_unicast_response = !!(class & AVAHI_DNS_UNICAST_RESPONSE); 660f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6611ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering class &= ~AVAHI_DNS_UNICAST_RESPONSE; 6621ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 6637e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!(k = avahi_key_new(name, class, type))) 6647e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return NULL; 6657e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6667e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!avahi_key_is_valid(k)) { 6677e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering avahi_key_unref(k); 6687e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return NULL; 6697e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering } 6707e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6717e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return k; 672f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 673f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6744f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_key(AvahiDnsPacket *p, AvahiKey *k, int unicast_response) { 6754f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *t; 6764f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t size; 677f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 6794f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(k); 680f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 681d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering size = p->size; 682d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 6837dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(t = avahi_dns_packet_append_name(p, k->name)) || 6847dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, k->type) || 68514f8d9beb7ef14b0aab5512345e09109bdd8cb0cLennart Poettering !avahi_dns_packet_append_uint16(p, k->clazz | (unicast_response ? AVAHI_DNS_UNICAST_RESPONSE : 0))) { 686d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 687f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 688d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering } 689f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 690f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return t; 691f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 692f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 693943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringstatic int append_rdata(AvahiDnsPacket *p, AvahiRecord *r) { 6944f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 6954f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(r); 696943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 697c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering switch (r->key->type) { 698c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 6997dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 700d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_CNAME: 701d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_NS: 702d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering 7037dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(avahi_dns_packet_append_name(p, r->data.ptr.name))) 704943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 705c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 706a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 707a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7087dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 709a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7107dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_uint16(p, r->data.srv.priority) || 7117dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.weight) || 7127dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.port) || 7137dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_name(p, r->data.srv.name)) 714943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 715c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 716c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 717c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 7187dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 7197dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_string(p, r->data.hinfo.cpu) || 7207dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_string(p, r->data.hinfo.os)) 721943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 722a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 723a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 724a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7257dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: { 726a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7274f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *data; 7284f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t n; 729c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 73066142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = avahi_string_list_serialize(r->data.txt.string_list, NULL, 0); 731c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 73266142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (!(data = avahi_dns_packet_extend(p, n))) 733943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 734c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 73566142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_string_list_serialize(r->data.txt.string_list, data, n); 736c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 737c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 738c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 739a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7407dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 741a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7427dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.a.address, sizeof(r->data.a.address))) 743943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 744a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 745a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 746a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7477dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 748a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7497dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.aaaa.address, sizeof(r->data.aaaa.address))) 750943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 751a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 752a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 753a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 754c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 755a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 756943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (r->data.generic.size) 757943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (avahi_dns_packet_append_bytes(p, r->data.generic.data, r->data.generic.size)) 758943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 759a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 760a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 761c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 762c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 763943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return 0; 764943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 765943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 766a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 767943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringuint8_t* avahi_dns_packet_append_record(AvahiDnsPacket *p, AvahiRecord *r, int cache_flush, unsigned max_ttl) { 768943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint8_t *t, *l, *start; 769943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering size_t size; 770943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 771943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(p); 772943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(r); 773943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 774943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering size = p->size; 775943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 776943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (!(t = avahi_dns_packet_append_name(p, r->key->name)) || 777943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint16(p, r->key->type) || 778943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint16(p, cache_flush ? (r->key->clazz | AVAHI_DNS_CACHE_FLUSH) : (r->key->clazz &~ AVAHI_DNS_CACHE_FLUSH)) || 779943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint32(p, (max_ttl && r->ttl > max_ttl) ? max_ttl : r->ttl) || 780943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !(l = avahi_dns_packet_append_uint16(p, 0))) 781943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 782943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 783943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering start = avahi_dns_packet_extend(p, 0); 784a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 785943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (append_rdata(p, r) < 0) 786943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 787a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7887dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering size = avahi_dns_packet_extend(p, 0) - start; 789bbf6b92f662ed909d5b4fca4a43b19e815812b3eLennart Poettering assert(size <= AVAHI_DNS_RDATA_MAX); 790a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 791c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("appended %u", size); */ 792a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 793973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering l[0] = (uint8_t) ((uint16_t) size >> 8); 794973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering l[1] = (uint8_t) ((uint16_t) size); 795a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 79654247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return t; 797d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 798d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 799d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poetteringfail: 800d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 801d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering return NULL; 802d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering} 803d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 8044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_empty(AvahiDnsPacket *p) { 8054f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 806d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 8077dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return p->size <= AVAHI_DNS_PACKET_HEADER_SIZE; 808f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 8090a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringsize_t avahi_dns_packet_space(AvahiDnsPacket *p) { 8114f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 8120a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8134f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p->size <= p->max_size); 8140a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8150a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering return p->max_size - p->size; 8160a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering} 817943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 818943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringint avahi_rdata_parse(AvahiRecord *record, const void* rdata, size_t size) { 819943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering int ret; 820943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiDnsPacket p; 821943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 822943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(record); 823943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(rdata); 824943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 825943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.data = (void*) rdata; 826943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.max_size = p.size = size; 827943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.rindex = 0; 828943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.name_table = NULL; 829943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 830943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering ret = parse_rdata(&p, record, size); 831943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 832943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(!p.name_table); 833943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 834943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return ret; 835943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 836943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 837943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringsize_t avahi_rdata_serialize(AvahiRecord *record, void *rdata, size_t max_size) { 838943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering int ret; 839943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiDnsPacket p; 840943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 841943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(record); 842943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(rdata); 843943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(max_size > 0); 844943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 845943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.data = (void*) rdata; 846943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.max_size = max_size; 847943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.size = p.rindex = 0; 848943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.name_table = NULL; 849943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 850943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering ret = append_rdata(&p, record); 851943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 852943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (p.name_table) 853943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_hashmap_free(p.name_table); 854943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 855943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (ret < 0) 856943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return (size_t) -1; 857943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 858943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return p.size; 859943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 860