]> git.karo-electronics.de Git - mdnsd.git/blob - dns_sd_txt.c
Add futher files to .gitignore
[mdnsd.git] / dns_sd_txt.c
1 /*
2  * Copyright (C) 2003 Jeremie Miller <jer@jabber.org>
3  * Copyright (C) 2013 Ole Reinhardt <ole.reinhardt@embedded-it.de>
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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.
19  *
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
31  * SUCH DAMAGE.
32  *
33  * For additional information see http://www.ethernut.de/
34  */
35
36 /* This code is based on
37  * Based on BSD licensed mdnsd implementation by Jer <jer@jabber.org>
38  * http://dotlocal.org/mdnsd/
39  *
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/
42  *
43  * mdnsd - embeddable Multicast DNS Daemon
44  * =======================================
45  *
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
58  * web sites.
59  *
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.
63  *
64  */
65
66
67 /*!
68  * \file pro/dns_sd_txt.c
69  * \brief Helper functions to hadle the DNS-SD (Multicast DNS) TXT record format
70  *
71  * \verbatim
72  *
73  * $Id$
74  *
75  * \endverbatim
76  */
77 #include <stdlib.h>
78 #include <string.h>
79 #include "dns_sd_txt.h"
80 #include "mdnsd.h"
81 #include "shash.h"
82
83 /*!
84  * \addtogroup xgMulticastDns
85  */
86 /*@{*/
87
88
89 /*!
90  * \brief Calculate the length of one key=value pair
91  *
92  * \param key   key name
93  * \param val   hashed value string
94  */
95 static int DnsSd2TxtLen(const char *key, char *val)
96 {
97     int ret = strlen(key);
98
99     if(*val == 0) {
100         return ret;
101     }
102
103     ret += strlen(val);
104     ret++;
105     return ret;
106 }
107
108
109 /*!
110  * \brief Count the length of hashedd key=value pairs
111  *
112  * Callback routine called by SHashForEach() in DnsSd2Txt()
113  *
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
118  */
119 static void DnsSd2TxtCount_CB(SHASH UNUSED(hash), const char *key, void *val, void *arg)
120 {
121     int *count = (int*)arg;
122     *count += DnsSd2TxtLen(key, (char*)val) + 1;
123 }
124
125
126 /*!
127  * \brief Append hashed key=value pairs to the text buffer
128  *
129  * Callback routine called by SHashForEach() in DnsSd2Txt()
130  *
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
135  */
136 static void DnsSd2TxtWrite_CB(SHASH UNUSED(hash), const char *key, void *val, void *arg)
137 {
138     unsigned char **txtp = (unsigned char **)arg;
139     char *cval = (char*)val;
140
141     /* Copy the length... */
142     **txtp = DnsSd2TxtLen(key, (char*)val);
143     (*txtp)++;
144
145     memcpy(*txtp, key, strlen(key));
146     *txtp += strlen(key);
147
148     if(*cval == 0) {
149         return;
150     }
151
152     /* ...and then the strings. */
153     **txtp = '=';
154     (*txtp)++;
155
156     memcpy(*txtp, cval, strlen(cval));
157     *txtp += strlen(cval);
158 }
159
160
161 /*!
162  * \brief Returns a raw block of data that can be send with a SD TXT record and also
163           sets length.
164  *
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
167  *
168  * \return      The newly allocated and filled hash table
169  */
170 unsigned char *DnsSd2Txt(SHASH hash, int *len)
171 {
172     unsigned char *buf, *raw;
173     *len = 0;
174
175     SHashForEach(hash, DnsSd2TxtCount_CB, (void*)len);
176     if(*len == 0) {
177         *len = 1;
178         buf = (unsigned char *)malloc(1);
179         *buf = 0;
180         return buf;
181     }
182     buf = (unsigned char *)malloc(*len);
183     raw = buf;
184
185     SHashForEach(hash, DnsSd2TxtWrite_CB, &buf);
186     return raw;
187 }
188
189
190 /*!
191  * \brief Returns a hashtable of strings of the raw SD TXT record rdata
192  *
193  * \param txt   The SD TXT record data
194  * \param len   Length of the data
195  *
196  * \return      The newly allocated and filled hash table
197  */
198 SHASH DnsTxt2Sd(unsigned char *txt, int len)
199 {
200     char key[256], *val;
201     SHASH hash = NULL;
202
203     if ((txt == 0) || (len == 0) || (*txt == 0)) {
204         return 0;
205     }
206
207     hash = SHashInit(23);
208
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) {
211         if(*txt == 0) {
212             break;
213         }
214         memcpy(key, txt+1, *txt);
215         key[*txt] = 0;
216
217         val = strchr(key, '=');
218         if (val != NULL) {
219             *val = 0;
220             val++;
221         }
222
223         SHashStore(hash, key, strlen(key), val, val ? strlen(val) : 0);
224     }
225     return hash;
226 }
227
228 /*@}*/