2 * Copyright (C) 2003 Jeremie Miller <jer@jabber.org>
3 * Copyright (C) 2013 Ole Reinhardt <ole.reinhardt@embedded-it.de>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the copyright holders nor the names of
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * For additional information see http://www.ethernut.de/
36 /* This code is based on
37 * Based on BSD licensed mdnsd implementation by Jer <jer@jabber.org>
38 * http://dotlocal.org/mdnsd/
40 * Unfortunately this site is now longer alive. You can still find it at:
41 * http://web.archive.org/web/20080705131510/http://dotlocal.org/mdnsd/
43 * mdnsd - embeddable Multicast DNS Daemon
44 * =======================================
46 * "mdnsd" is a very lightweight, simple, portable, and easy to integrate
47 * open source implementation of Multicast DNS (part of Zeroconf, also called
48 * Rendezvous by Apple) for developers. It supports both acting as a Query and
49 * a Responder, allowing any software to participate fully on the .localnetwork
50 * just by including a few files and calling a few functions. All of the
51 * complexity of handling the Multicast DNS retransmit timing, duplicate
52 * suppression, probing, conflict detection, and other facets of the DNS
53 * protocol is hidden behind a very simple and very easy to use interface,
54 * described in the header file. The single small c source file has almost no
55 * dependencies, and is portable to almost any embedded platform.
56 * Multiple example applications and usages are included in the download,
57 * including a simple persistent query browser and a tool to advertise .local
60 * The code is licensed under both the GPL and BSD licenses, for use in any
61 * free software or commercial application. If there is a licensing need not
62 * covered by either of those, alternative licensing is available upon request.
68 * \file pro/dns_sd_txt.c
69 * \brief Helper functions to hadle the DNS-SD (Multicast DNS) TXT record format
79 #include "dns_sd_txt.h"
84 * \addtogroup xgMulticastDns
90 * \brief Calculate the length of one key=value pair
93 * \param val hashed value string
95 static int DnsSd2TxtLen(const char *key, char *val)
97 int ret = strlen(key);
110 * \brief Count the length of hashedd key=value pairs
112 * Callback routine called by SHashForEach() in DnsSd2Txt()
114 * \param hash The hash table
115 * \param key key name
116 * \param val hashed value string
117 * \param arg pointer to the count variable
119 static void DnsSd2TxtCount_CB(SHASH UNUSED(hash), const char *key, void *val, void *arg)
121 int *count = (int*)arg;
122 *count += DnsSd2TxtLen(key, (char*)val) + 1;
127 * \brief Append hashed key=value pairs to the text buffer
129 * Callback routine called by SHashForEach() in DnsSd2Txt()
131 * \param hash The hash table
132 * \param key key name
133 * \param val hashed value string
134 * \param arg pointer to the text buffer, where we want to append the value of the hashed entry to
136 static void DnsSd2TxtWrite_CB(SHASH UNUSED(hash), const char *key, void *val, void *arg)
138 unsigned char **txtp = (unsigned char **)arg;
139 char *cval = (char*)val;
141 /* Copy the length... */
142 **txtp = DnsSd2TxtLen(key, (char*)val);
145 memcpy(*txtp, key, strlen(key));
146 *txtp += strlen(key);
152 /* ...and then the strings. */
156 memcpy(*txtp, cval, strlen(cval));
157 *txtp += strlen(cval);
162 * \brief Returns a raw block of data that can be send with a SD TXT record and also
165 * \param hash The hash table from which the SD TXT record data shall be generated from
166 * \param len Call by reference: Returns the length of the raw data record
168 * \return The newly allocated and filled hash table
170 unsigned char *DnsSd2Txt(SHASH hash, int *len)
172 unsigned char *buf, *raw;
175 SHashForEach(hash, DnsSd2TxtCount_CB, (void*)len);
178 buf = (unsigned char *)malloc(1);
182 buf = (unsigned char *)malloc(*len);
185 SHashForEach(hash, DnsSd2TxtWrite_CB, &buf);
191 * \brief Returns a hashtable of strings of the raw SD TXT record rdata
193 * \param txt The SD TXT record data
194 * \param len Length of the data
196 * \return The newly allocated and filled hash table
198 SHASH DnsTxt2Sd(unsigned char *txt, int len)
203 if ((txt == 0) || (len == 0) || (*txt == 0)) {
207 hash = SHashInit(23);
209 /* Loop through the data, break out each block and store it into the hash table */
210 for(; (*txt <= len) && (len > 0); len -= *txt, txt += *txt + 1) {
214 memcpy(key, txt+1, *txt);
217 val = strchr(key, '=');
223 SHashStore(hash, key, strlen(key), val, val ? strlen(val) : 0);