1ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering/*** 2ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering This file is part of avahi. 3a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering avahi is free software; you can redistribute it and/or modify it 5ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering under the terms of the GNU Lesser General Public License as 6ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering published by the Free Software Foundation; either version 2.1 of the 7ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering License, or (at your option) any later version. 8a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 9ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering avahi is distributed in the hope that it will be useful, but WITHOUT 10ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 12ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering Public License for more details. 13a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 14ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering You should have received a copy of the GNU Lesser General Public 15ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering License along with avahi; if not, write to the Free Software 16ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 17ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering USA. 18ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering***/ 19ab84bbc4bef07413f95c3237e29f2287319e0f4cLennart Poettering 20eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering#ifdef HAVE_CONFIG_H 21eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering#include <config.h> 22eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering#endif 23eca309458f9521a2e3276dc11a1792d5f2e227e4Lennart Poettering 244ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <stdlib.h> 254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <string.h> 264ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include <stdio.h> 274f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include <assert.h> 284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 29b91e3b47eaed054189c45c070002f291d7d11166Lennart Poettering#include <sys/types.h> 30eee711106f721fc73a1ef50348984b7a1d9cb595Sebastien Estienne#include <netinet/in.h> 31eee711106f721fc73a1ef50348984b7a1d9cb595Sebastien Estienne 32f6712902a92eb82b6c8d7e7fd0980a20a716fa0dLennart Poettering#include <avahi-common/defs.h> 335ebf655c85076f200955458673a8bbf0dd927407Lennart Poettering#include <avahi-common/domain.h> 348e46e738cae449bf44232c66e973c8e9e15fbcb5Robert Ginda#include "avahi-common/avahi-malloc.h" 354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 364ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering#include "dns.h" 374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering#include "log.h" 384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 394f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new(unsigned mtu) { 407dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t max_size; 42c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 43602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (mtu <= 0) 443073103812f0ea376582eb0ff1479945a847b361Lennart Poettering max_size = AVAHI_DNS_PACKET_SIZE_MAX; 45b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering else if (mtu >= AVAHI_DNS_PACKET_EXTRA_SIZE) 46b6820898d317c29a31f97018ede6da5195d16bfbLennart Poettering max_size = mtu - AVAHI_DNS_PACKET_EXTRA_SIZE; 47602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering else 48602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering max_size = 0; 49602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 50602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (max_size < AVAHI_DNS_PACKET_HEADER_SIZE) 517dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering max_size = AVAHI_DNS_PACKET_HEADER_SIZE; 52a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_malloc(sizeof(AvahiDnsPacket) + max_size))) 544f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return p; 55a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 567dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering p->size = p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 57c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->max_size = max_size; 584ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering p->name_table = NULL; 59943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p->data = NULL; 60c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 617dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memset(AVAHI_DNS_PACKET_DATA(p), 0, p->size); 62c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 63c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 64c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 654f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_query(unsigned mtu) { 667dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 67c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 70a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 717dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); 72c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return p; 73c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering} 74c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 754f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_response(unsigned mtu, int aa) { 767dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering AvahiDnsPacket *p; 77c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new(mtu))) 794f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 80a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 818d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(1, 0, aa, 0, 0, 0, 0, 0, 0, 0)); 824ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return p; 834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 854f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiDnsPacket* avahi_dns_packet_new_reply(AvahiDnsPacket* p, unsigned mtu, int copy_queries, int aa) { 86602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiDnsPacket *r; 874f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 88602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(r = avahi_dns_packet_new_response(mtu, aa))) 904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 91602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 92602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if (copy_queries) { 934f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned saved_rindex; 944f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint32_t n; 95602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 96602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering saved_rindex = p->rindex; 97602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE; 98a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 99602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT); n > 0; n--) { 100602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering AvahiKey *k; 1014f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int unicast_response; 102602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 103602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering if ((k = avahi_dns_packet_consume_key(p, &unicast_response))) { 104602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_append_key(r, k, unicast_response); 105602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_key_unref(k); 106602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 107602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 108602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 109602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering p->rindex = saved_rindex; 110602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 111602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_QDCOUNT, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT)); 112602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering } 113602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 114602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_ID, avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ID)); 115602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 116602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_FLAGS, 117602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering (avahi_dns_packet_get_field(r, AVAHI_DNS_FIELD_FLAGS) & ~AVAHI_DNS_FLAG_OPCODE) | 1188d8c0255f0f0242a067b577747740bab1b1021eaLennart Poettering (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_OPCODE)); 119602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 120602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering return r; 121a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering} 122602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 123602a2b6481587b7da2594db39151ec9380f276dfLennart Poettering 1247dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poetteringvoid avahi_dns_packet_free(AvahiDnsPacket *p) { 1254f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1264ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1274ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (p->name_table) 1284f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_free(p->name_table); 129a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1304f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_free(p); 1314ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1324ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_set_field(AvahiDnsPacket *p, unsigned idx, uint16_t v) { 1344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 136a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering ((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx] = htons(v); 1384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1404f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint16_t avahi_dns_packet_get_field(AvahiDnsPacket *p, unsigned idx) { 1414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 1434ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1444f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return ntohs(((uint16_t*) AVAHI_DNS_PACKET_DATA(p))[idx]); 1454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 1464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 1474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringvoid avahi_dns_packet_inc_field(AvahiDnsPacket *p, unsigned idx) { 1484f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < AVAHI_DNS_PACKET_HEADER_SIZE); 150af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 15166142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_dns_packet_set_field(p, idx, avahi_dns_packet_get_field(p, idx) + 1); 152a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering} 153af1ce5fe2245fba0045d2c0d70b58b700938bd2fLennart Poettering 154043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd 15572c5d38b3a671e987d59ced6396c74185e3ce660Lennart Poetteringstatic void name_table_cleanup(void *key, void *value, void *user_data) { 15672c5d38b3a671e987d59ced6396c74185e3ce660Lennart Poettering AvahiDnsPacket *p = user_data; 157a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 15872c5d38b3a671e987d59ced6396c74185e3ce660Lennart Poettering if ((uint8_t*) value >= AVAHI_DNS_PACKET_DATA(p) + p->size) 15972c5d38b3a671e987d59ced6396c74185e3ce660Lennart Poettering avahi_hashmap_remove(p->name_table, key); 160043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd} 161043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd 16272c5d38b3a671e987d59ced6396c74185e3ce660Lennart Poetteringvoid avahi_dns_packet_cleanup_name_table(AvahiDnsPacket *p) { 16372c5d38b3a671e987d59ced6396c74185e3ce660Lennart Poettering if (p->name_table) 16472c5d38b3a671e987d59ced6396c74185e3ce660Lennart Poettering avahi_hashmap_foreach(p->name_table, name_table_cleanup, p); 165043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd} 166043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd 1674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_name(AvahiDnsPacket *p, const char *name) { 1684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d, *saved_ptr = NULL; 1694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t saved_size; 170a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1714f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1724f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(name); 1734ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 174c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering saved_size = p->size; 1757dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering saved_ptr = avahi_dns_packet_extend(p, 0); 176a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1774e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering while (*name) { 1784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* prev; 1794f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const char *pname; 1804f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char label[64], *u; 181a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1824ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering /* Check whether we can compress this name. */ 1834ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1844f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->name_table && (prev = avahi_hashmap_lookup(p->name_table, name))) { 1854f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned idx; 186a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1874f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(prev >= AVAHI_DNS_PACKET_DATA(p)); 1884f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering idx = (unsigned) (prev - AVAHI_DNS_PACKET_DATA(p)); 1894ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 1904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(idx < p->size); 1914ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 19266142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx < 0x4000) { 193973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t *t; 194973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering if (!(t = (uint8_t*) avahi_dns_packet_extend(p, sizeof(uint16_t)))) 1954ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering return NULL; 1964ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 197973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering t[0] = (uint8_t) ((0xC000 | idx) >> 8); 198973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering t[1] = (uint8_t) idx; 1994c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 2004ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 2014ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering } 2024e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 2034e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering pname = name; 204a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 205a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering if (!(avahi_unescape_label(&name, label, sizeof(label)))) 206c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 2074ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2087dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_append_string(p, label))) 2094e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering goto fail; 2104c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering 2114ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering if (!p->name_table) 212a3596a5e3ec4937a220e6e60218639e2aba82701Lennart Poettering /* This works only for normalized domain names */ 2134f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->name_table = avahi_hashmap_new(avahi_string_hash, avahi_string_equal, avahi_free, NULL); 2144ccd2cdd5ae567dc2cb6c05ca5e5a9537a9dc1c4Lennart Poettering 2154f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(u = avahi_strdup(pname))) 2164f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_log_error("avahi_strdup() failed."); 2174f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering else 2184f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_hashmap_insert(p->name_table, u, d); 2194ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 2204ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2217dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, 1))) 222c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering goto fail; 223a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 2244e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering *d = 0; 2254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2264c8155fa9c85c7ece92182d0ab53f99a982a4abfLennart Poettering return saved_ptr; 227c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 228c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poetteringfail: 229c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering p->size = saved_size; 230043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd avahi_dns_packet_cleanup_name_table(p); 231043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd 232c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 2334ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2344ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_uint16(AvahiDnsPacket *p, uint16_t v) { 2364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 238a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 2394f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint16_t)))) 240c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 241a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 242973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[0] = (uint8_t) (v >> 8); 243973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[1] = (uint8_t) v; 2444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 2454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 2464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 2474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_uint32(AvahiDnsPacket *p, uint32_t v) { 2484f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 2494f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 250c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering 2514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(d = avahi_dns_packet_extend(p, sizeof(uint32_t)))) 252c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 253a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 254973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[0] = (uint8_t) (v >> 24); 255973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[1] = (uint8_t) (v >> 16); 256973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[2] = (uint8_t) (v >> 8); 257973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d[3] = (uint8_t) v; 25854247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 25954247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 26054247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 26154247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2624f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_append_bytes(AvahiDnsPacket *p, const void *b, size_t l) { 2634f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 26454247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(b); 2674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l); 2684aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 2697dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, l))) 270c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 27154247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 272c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering memcpy(d, b, l); 27354247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return d; 27454247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering} 27554247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering 2764f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_string(AvahiDnsPacket *p, const char *s) { 2774f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t* d; 2784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 279a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 2804f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2814f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 282a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 283a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if ((k = strlen(s)) >= 255) 284a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering k = 255; 285a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 2867dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(d = avahi_dns_packet_extend(p, k+1))) 287a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 288a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering *d = (uint8_t) k; 290a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering memcpy(d+1, s, k); 291a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 292a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return d; 293a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 294a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 2954f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t *avahi_dns_packet_extend(AvahiDnsPacket *p, size_t l) { 2964f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *d; 297a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 2984f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 2994ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 300c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering if (p->size+l > p->max_size) 301c18626ad35cdf94edbff196070ccbb6ae825abd0Lennart Poettering return NULL; 302a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3037dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering d = AVAHI_DNS_PACKET_DATA(p) + p->size; 3044ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->size += l; 305a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3064ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return d; 3074ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3084ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3091ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid(AvahiDnsPacket *p) { 3104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t flags; 3114f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 3124ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3131ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (p->size < AVAHI_DNS_PACKET_HEADER_SIZE) 3144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3154ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3167dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 317a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3181ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_OPCODE) 3191ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 3201ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3211ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return 0; 3221ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering} 3231ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering 3241ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poetteringint avahi_dns_packet_check_valid_multicast(AvahiDnsPacket *p) { 3251ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering uint16_t flags; 3261ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering assert(p); 3274ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3281ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (avahi_dns_packet_check_valid(p) < 0) 3291ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering return -1; 330a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3311ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering flags = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS); 332a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3331ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (flags & AVAHI_DNS_FLAG_RCODE) 3344ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3354ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3364ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 3374ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3394f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_query(AvahiDnsPacket *p) { 3404f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 341a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3427dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return !(avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_QR); 3434ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 3444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3454f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic int consume_labels(AvahiDnsPacket *p, unsigned idx, char *ret_name, size_t l) { 3464f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int ret = 0; 3474ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int compressed = 0; 3484ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering int first_label = 1; 3495ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd unsigned label_ptr; 35083b432c2369d7ef4142811bea0109b6588b6f313Trent Lloyd int i; 3514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p && ret_name && l); 352a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 353451be30b300b390b46738af3fd24fc942ba3158fTrent Lloyd for (i = 0; i < AVAHI_DNS_LABELS_MAX; i++) { 3544f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t n; 3554ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 35666142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+1 > p->size) 3574ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3584ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 35966142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = AVAHI_DNS_PACKET_DATA(p)[idx]; 3604ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3614ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!n) { 36266142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3634ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3644ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 3654ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3664ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (l < 1) 3674ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3684ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *ret_name = 0; 369a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3704ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return ret; 371a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3724ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if (n <= 63) { 3734ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Uncompressed label */ 37466142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx++; 3754ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3764ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret++; 377a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 37866142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx + n > p->size) 3794ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3804ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3814f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((size_t) n + 1 > l) 3824ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 3834ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 3844ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!first_label) { 3854ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering *(ret_name++) = '.'; 3864ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering l--; 3874ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 3884ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering first_label = 0; 3894ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 390d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering if (!(avahi_escape_label((char*) AVAHI_DNS_PACKET_DATA(p) + idx, n, &ret_name, &l))) 3914e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering return -1; 3924e2d82b18f7e099cbce933b383c45efa40306161Lennart Poettering 39366142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering idx += n; 394a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3954ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 3964ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += n; 3974ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else if ((n & 0xC0) == 0xC0) { 3984ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering /* Compressed label */ 3994ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 40066142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (idx+2 > p->size) 4014ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4024ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4035ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd label_ptr = ((unsigned) (AVAHI_DNS_PACKET_DATA(p)[idx] & ~0xC0)) << 8 | AVAHI_DNS_PACKET_DATA(p)[idx+1]; 4045ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd 4055ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd if ((label_ptr < AVAHI_DNS_PACKET_HEADER_SIZE) || (label_ptr >= idx)) 4065ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd return -1; 4075ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd 4085ed5452823a5da7d7a7b36d5a42d3edc09f2342fTrent Lloyd idx = label_ptr; 4094ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4104ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (!compressed) 4114ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering ret += 2; 412a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4134ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering compressed = 1; 4144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } else 4154ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4164ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering } 4176e9695a1e6a5f6a70195b6de37448aaf9cde8e30Trent Lloyd 4186e9695a1e6a5f6a70195b6de37448aaf9cde8e30Trent Lloyd return -1; 4194ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4204ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4214f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_name(AvahiDnsPacket *p, char *ret_name, size_t l) { 4224f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int r; 423a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4244ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if ((r = consume_labels(p, p->rindex, ret_name, l)) < 0) 4254ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4264ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4274ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += r; 4284ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4294ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4304ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4314f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint16(AvahiDnsPacket *p, uint16_t *ret_v) { 432973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t *d; 433973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering 4344f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4364ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint16_t) > p->size) 4384ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4394ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 440973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d = (uint8_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex); 441973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering *ret_v = (d[0] << 8) | d[1]; 4424f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint16_t); 4434ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4444ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4454ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4464ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4474f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_uint32(AvahiDnsPacket *p, uint32_t *ret_v) { 448973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering uint8_t* d; 449973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering 4504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_v); 4524ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (p->rindex + sizeof(uint32_t) > p->size) 4544ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4554ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 456973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering d = (uint8_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex); 457973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering *ret_v = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]; 4584f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering p->rindex += sizeof(uint32_t); 459a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4604ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4614ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4624ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4634f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_bytes(AvahiDnsPacket *p, void * ret_data, size_t l) { 4644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_data); 4664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 467a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4684ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + l > p->size) 4694ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 4704ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4717dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_data, AVAHI_DNS_PACKET_DATA(p) + p->rindex, l); 4724ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += l; 4734ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4744ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 4754ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 4764ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 4774f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_consume_string(AvahiDnsPacket *p, char *ret_string, size_t l) { 4784f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t k; 479a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4804f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 4814f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(ret_string); 4824f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(l > 0); 483a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 484a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex >= p->size) 485a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 486a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4877dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering k = AVAHI_DNS_PACKET_DATA(p)[p->rindex]; 488a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 489a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex+1+k > p->size) 490a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return -1; 491a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 492a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (l > k+1) 493a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering l = k+1; 494a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 4957dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering memcpy(ret_string, AVAHI_DNS_PACKET_DATA(p)+p->rindex+1, l-1); 496a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering ret_string[l-1] = 0; 497a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 498a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering p->rindex += 1+k; 499a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 500a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return 0; 501a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering} 502a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5034f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringconst void* avahi_dns_packet_get_rptr(AvahiDnsPacket *p) { 5044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 505a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 506a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (p->rindex > p->size) 507f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 508f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 5097dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return AVAHI_DNS_PACKET_DATA(p) + p->rindex; 510f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 511f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 5124f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_skip(AvahiDnsPacket *p, size_t length) { 5134f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 5144ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 5154ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering if (p->rindex + length > p->size) 5164ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return -1; 5174ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering 5184ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering p->rindex += length; 5194ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering return 0; 5204ba1a4b0b4488e5058af67b789187735b529075eLennart Poettering} 521f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 522943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringstatic int parse_rdata(AvahiDnsPacket *p, AvahiRecord *r, uint16_t rdlength) { 523943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering char buf[AVAHI_DOMAIN_NAME_MAX]; 5244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering const void* start; 525a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5264f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 527943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(r); 528f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 5297dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering start = avahi_dns_packet_get_rptr(p); 530a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 531943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering switch (r->key->type) { 5327dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 5337dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_CNAME: 534d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_NS: 535a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5367dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 537943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 538a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5394f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.ptr.name = avahi_strdup(buf); 540a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 541a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 542a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5437dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 544a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5457dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_uint16(p, &r->data.srv.priority) < 0 || 5467dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.weight) < 0 || 5477dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &r->data.srv.port) < 0 || 5487dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_name(p, buf, sizeof(buf)) < 0) 549943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 550a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5514f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.srv.name = avahi_strdup(buf); 552a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 553a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5547dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 555a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5567dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 557943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 558a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5594f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.cpu = avahi_strdup(buf); 560a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5617dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_string(p, buf, sizeof(buf)) < 0) 562943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 563a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.hinfo.os = avahi_strdup(buf); 565c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 566c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5677dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: 568a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 569a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (rdlength > 0) { 57020011324500a728851e4888c890a756ecf71394bLennart Poettering if (avahi_string_list_parse(avahi_dns_packet_get_rptr(p), rdlength, &r->data.txt.string_list) < 0) 57120011324500a728851e4888c890a756ecf71394bLennart Poettering return -1; 572a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5737dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 574943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 575fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering } else 576fc174c871b4f85e558766c1ca55661fa7b1b4c9aLennart Poettering r->data.txt.string_list = NULL; 577a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 578a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 579a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5807dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 581a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 582c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("A"); */ 583c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 5847dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.a.address, sizeof(AvahiIPv4Address)) < 0) 585943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 586a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 587a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 588a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 5897dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 590a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 591c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("aaaa"); */ 592a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 5937dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_bytes(p, &r->data.aaaa.address, sizeof(AvahiIPv6Address)) < 0) 594943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 595a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 596c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 597a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 598c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 5994aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 600c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("generic"); */ 601a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 6024aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering if (rdlength > 0) { 6034aa744ffac20c7b5e18cb3b23e5dbac8221c0043Lennart Poettering 6044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering r->data.generic.data = avahi_memdup(avahi_dns_packet_get_rptr(p), rdlength); 605a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering r->data.generic.size = rdlength; 606a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 6077dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_skip(p, rdlength) < 0) 608943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 609a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering } 610c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 611c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 612c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 613c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 614a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering /* Check if we read enough data */ 6154f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if ((const uint8_t*) avahi_dns_packet_get_rptr(p) - (const uint8_t*) start != rdlength) 616943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 617a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 618943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return 0; 619943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 620943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 621943a6b93697fc0a7bcd0cc574744d7de609c189cLennart PoetteringAvahiRecord* avahi_dns_packet_consume_record(AvahiDnsPacket *p, int *ret_cache_flush) { 622943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering char name[AVAHI_DOMAIN_NAME_MAX]; 623943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint16_t type, class; 624943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint32_t ttl; 625943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint16_t rdlength; 626943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiRecord *r = NULL; 627943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 628943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(p); 629943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 630943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 631943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 632943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0 || 633943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint32(p, &ttl) < 0 || 634943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_dns_packet_consume_uint16(p, &rdlength) < 0 || 635943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p->rindex + rdlength > p->size) 636a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering goto fail; 637a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 638943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (ret_cache_flush) 639943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering *ret_cache_flush = !!(class & AVAHI_DNS_CACHE_FLUSH); 640943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering class &= ~AVAHI_DNS_CACHE_FLUSH; 641a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 642943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (!(r = avahi_record_new_full(name, class, type, ttl))) 643943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 644a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 645943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (parse_rdata(p, r, rdlength) < 0) 646943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 6477e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6487e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!avahi_record_is_valid(r)) 6497e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering goto fail; 650a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 651a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return r; 652a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 653a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poetteringfail: 654a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering if (r) 6557dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_record_unref(r); 656a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 657a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering return NULL; 658f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 659f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6604f0a5e7572a4257894b4bfede42c26d65152609eLennart PoetteringAvahiKey* avahi_dns_packet_consume_key(AvahiDnsPacket *p, int *ret_unicast_response) { 6614f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering char name[256]; 6624f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint16_t type, class; 6637e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering AvahiKey *k; 664f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 666f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6677dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (avahi_dns_packet_consume_name(p, name, sizeof(name)) < 0 || 6687dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &type) < 0 || 6697dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering avahi_dns_packet_consume_uint16(p, &class) < 0) 670f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 671f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6721ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering if (ret_unicast_response) 6731ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering *ret_unicast_response = !!(class & AVAHI_DNS_UNICAST_RESPONSE); 674f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6751ffedb586bd2fb6daa3970304fac7c5b415cd38fLennart Poettering class &= ~AVAHI_DNS_UNICAST_RESPONSE; 676a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 6777e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!(k = avahi_key_new(name, class, type))) 6787e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return NULL; 6797e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6807e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering if (!avahi_key_is_valid(k)) { 6817e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering avahi_key_unref(k); 6827e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return NULL; 6837e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering } 6847e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering 6857e80cf6838c15be19cad03aeb80996d03a98921bLennart Poettering return k; 686f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 687f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 6884f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringuint8_t* avahi_dns_packet_append_key(AvahiDnsPacket *p, AvahiKey *k, int unicast_response) { 6894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *t; 6904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t size; 691a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 6924f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 6934f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(k); 694f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 695d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering size = p->size; 696a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 6977dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(t = avahi_dns_packet_append_name(p, k->name)) || 6987dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, k->type) || 69914f8d9beb7ef14b0aab5512345e09109bdd8cb0cLennart Poettering !avahi_dns_packet_append_uint16(p, k->clazz | (unicast_response ? AVAHI_DNS_UNICAST_RESPONSE : 0))) { 700d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 701043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd avahi_dns_packet_cleanup_name_table(p); 702043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd 703f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return NULL; 704d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering } 705f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 706f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering return t; 707f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 708f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering 709943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringstatic int append_rdata(AvahiDnsPacket *p, AvahiRecord *r) { 7104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 7114f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(r); 712a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 713c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering switch (r->key->type) { 714a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 7157dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_PTR: 716d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_CNAME: 717d1dd07145bb3db5c6fd77c55aea762eb79ab3b5cLennart Poettering case AVAHI_DNS_TYPE_NS: 718a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 7197dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!(avahi_dns_packet_append_name(p, r->data.ptr.name))) 720943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 721a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 722a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 723a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7247dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_SRV: 725a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7267dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_uint16(p, r->data.srv.priority) || 7277dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.weight) || 7287dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_uint16(p, r->data.srv.port) || 7297dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_name(p, r->data.srv.name)) 730943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 731c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 732c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 733c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 7347dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_HINFO: 7357dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_string(p, r->data.hinfo.cpu) || 7367dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering !avahi_dns_packet_append_string(p, r->data.hinfo.os)) 737943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 738a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 739a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 740a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7417dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_TXT: { 742a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering uint8_t *data; 7444f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t n; 745c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 74666142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering n = avahi_string_list_serialize(r->data.txt.string_list, NULL, 0); 747c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 74866142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering if (!(data = avahi_dns_packet_extend(p, n))) 749943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 750c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 75166142b071a2497d7e3cf58d7bf5159bb1c970d84Lennart Poettering avahi_string_list_serialize(r->data.txt.string_list, data, n); 752c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering break; 753c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 754c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 755a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7567dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_A: 757a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7587dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.a.address, sizeof(r->data.a.address))) 759943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 760a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 761a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 762a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 7637dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering case AVAHI_DNS_TYPE_AAAA: 764a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 7657dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering if (!avahi_dns_packet_append_bytes(p, &r->data.aaaa.address, sizeof(r->data.aaaa.address))) 766943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 767a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 768a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 769a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 770c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering default: 771a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 772943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (r->data.generic.size) 773b7e1f69e270e38642305d9064e9ca8051419b52cLennart Poettering if (!avahi_dns_packet_append_bytes(p, r->data.generic.data, r->data.generic.size)) 774943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return -1; 775a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 776a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering break; 777c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering } 778c8dd2dc8f91a322178c43281cbc5c8fc16da5219Lennart Poettering 779943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return 0; 780943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 781943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 782a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 783943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringuint8_t* avahi_dns_packet_append_record(AvahiDnsPacket *p, AvahiRecord *r, int cache_flush, unsigned max_ttl) { 784943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering uint8_t *t, *l, *start; 785943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering size_t size; 786943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 787943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(p); 788943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(r); 789943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 790943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering size = p->size; 791943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 792943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (!(t = avahi_dns_packet_append_name(p, r->key->name)) || 793943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint16(p, r->key->type) || 794943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint16(p, cache_flush ? (r->key->clazz | AVAHI_DNS_CACHE_FLUSH) : (r->key->clazz &~ AVAHI_DNS_CACHE_FLUSH)) || 795943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !avahi_dns_packet_append_uint32(p, (max_ttl && r->ttl > max_ttl) ? max_ttl : r->ttl) || 796943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering !(l = avahi_dns_packet_append_uint16(p, 0))) 797943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 798943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 799943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering start = avahi_dns_packet_extend(p, 0); 800a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 801943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (append_rdata(p, r) < 0) 802943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering goto fail; 803a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 8047dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering size = avahi_dns_packet_extend(p, 0) - start; 805bbf6b92f662ed909d5b4fca4a43b19e815812b3eLennart Poettering assert(size <= AVAHI_DNS_RDATA_MAX); 806a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 807c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("appended %u", size); */ 808a20c01bd12216d409e0dfc5d3bbacc940352bfceLennart Poettering 809973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering l[0] = (uint8_t) ((uint16_t) size >> 8); 810973b9c62f7cbc65f00e9730c6c362d30f9da5163Lennart Poettering l[1] = (uint8_t) ((uint16_t) size); 811a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 81254247ce93dc6f048c0ffea546f454653ce0e25a8Lennart Poettering return t; 813d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 814d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 815d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poetteringfail: 816d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering p->size = size; 817043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd avahi_dns_packet_cleanup_name_table(p); 818043eb084c1c76f5b62fc1745942bddfddf17fbf1Trent Lloyd 819d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering return NULL; 820d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering} 821d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 8224f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_dns_packet_is_empty(AvahiDnsPacket *p) { 8234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 824d553a1c2d1cd3fcdd65ade64940b5bd3efc70675Lennart Poettering 8257dce450bdc23ea306a61e00f914481e29ebcb176Lennart Poettering return p->size <= AVAHI_DNS_PACKET_HEADER_SIZE; 826f0f4bb0c37eeed71934e3191cffa5afb1cfdca0dLennart Poettering} 8270a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8284f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringsize_t avahi_dns_packet_space(AvahiDnsPacket *p) { 8294f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 8300a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering 8314f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p->size <= p->max_size); 832a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 8330a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering return p->max_size - p->size; 8340a985aa6c5453fe09bf0a3a79fe66d49c698b309Lennart Poettering} 835943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 836943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringint avahi_rdata_parse(AvahiRecord *record, const void* rdata, size_t size) { 837943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering int ret; 838943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiDnsPacket p; 839a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 840943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(record); 841943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(rdata); 842a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 843943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.data = (void*) rdata; 844943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.max_size = p.size = size; 845943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.rindex = 0; 846943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.name_table = NULL; 847943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 848943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering ret = parse_rdata(&p, record, size); 849943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 850943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(!p.name_table); 851a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 852943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return ret; 853943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 854943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 855943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poetteringsize_t avahi_rdata_serialize(AvahiRecord *record, void *rdata, size_t max_size) { 856943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering int ret; 857943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering AvahiDnsPacket p; 858a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 859943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(record); 860943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(rdata); 861943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering assert(max_size > 0); 862943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 863943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.data = (void*) rdata; 864943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.max_size = max_size; 865943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.size = p.rindex = 0; 866943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering p.name_table = NULL; 867943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 868943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering ret = append_rdata(&p, record); 869943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 870943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (p.name_table) 871943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering avahi_hashmap_free(p.name_table); 872943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering 873943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering if (ret < 0) 874943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return (size_t) -1; 875a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 876943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering return p.size; 877943a6b93697fc0a7bcd0cc574744d7de609c189cLennart Poettering} 878