PERFORCE change 125234 for review
Fredrik Lindberg
fli at FreeBSD.org
Thu Aug 16 12:51:12 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125234
Change 125234 by fli at fli_nexus on 2007/08/16 19:50:49
- Add mdns_freerrset(), free resources allocated to a rrset.
- Add mdns_db_name_{add,del}() and mdns_db_res_{add,del}()
which allows manipulation of the record database.
- Make it possible to specify the default location of the
daemon pipe at compile time.
- General cleanup.
Affected files ...
.. //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.c#2 edit
.. //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.h#2 edit
.. //depot/projects/soc2007/fli-mdns_sd/libmdns/mdns.h#2 edit
Differences ...
==== //depot/projects/soc2007/fli-mdns_sd/libmdns/libmdns.c#2 (text+ko) ====
@@ -35,6 +35,7 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
@@ -44,20 +45,22 @@
#include "libmdns.h"
#include "mdnsd_ipc.h"
-#include "../mdnsd/debug.h"
-
-#define MDNSD_PIPE "/var/run/mdnsd.pipe"
-
static int sock_open(struct mdns *);
static void sock_close(struct mdns *);
static inline int sock_verify(struct mdns *);
static int sock_reconnect(struct mdns *);
+static int doquery(struct mdns *, int, int, int, int, int, int, wchar_t *);
static struct mdns_msg * sock_read(struct mdns *, int, struct timeval *);
static struct mdns_msg * msg_wait(struct mdns *, int, struct timeval *);
static void msg_free(struct mdns_msg *);
struct mdns_wait * in_wqueue(struct mdns *, int);
+static inline int ipc_sethdr(struct mdns *, struct mipc_head *, int);
+static ssize_t utf8_decode(char *, size_t, wchar_t *, size_t);
+static int docmd(struct mdns *, int, int, ...);
+static int errormsg(struct mdns_msg *);
-static inline int ipc_sethdr(struct mdns *, struct mipc_head *, int);
+extern struct ctmap class_map[];
+extern int class_map_size;
/*
* Open a handle to the daemon
@@ -66,6 +69,7 @@
mdns_open(void)
{
struct mdns *m;
+ int error;
m = malloc(sizeof(struct mdns));
if (m == NULL)
@@ -74,7 +78,11 @@
TAILQ_INIT(&m->m_recv);
TAILQ_INIT(&m->m_wait);
- sock_open(m);
+ error = sock_open(m);
+ if (error < 0) {
+ free(m);
+ return (NULL);
+ }
MDNS_SETCOOKIE(m);
return (m);
}
@@ -86,84 +94,29 @@
mdns_close(struct mdns *m)
{
struct mdns_msg *mm, *mm2;
+ struct mdns_wait *mw, *mw2;
if (m == NULL)
return;
MDNS_ASSERT(m);
+ if (sock_verify(m))
+ close(m->m_sock);
+
TAILQ_FOREACH_SAFE(mm, &m->m_recv, mm_next, mm2) {
TAILQ_REMOVE(&m->m_recv, mm, mm_next);
msg_free(mm);
}
+ TAILQ_FOREACH_SAFE(mw, &m->m_wait, mw_next, mw2) {
+ TAILQ_REMOVE(&m->m_wait, mw, mw_next);
+ free(mw);
+ }
MDNS_UNSETCOOKIE(m);
free(m);
}
-/*
- * Submit a query to the daemon
- */
-static int
-doquery(struct mdns *m, int cmd, int fam, int ifidx, int tmo, int class,
- int type, wchar_t *rec)
-{
- size_t rlen;
- int n, mid, retval = 0;
- struct mdns_msg *mm;
- struct mdns_wait *mw;
- struct mipc_head mih;
- struct mipc_query miq;
- struct iovec iov[3];
-
- rlen = wcslen(rec);
- if (rlen >= MDNS_NAME_LEN)
- return (-1);
-
- mid = ipc_sethdr(m, &mih, MIM_QUERY);
- miq.miq_cmd = cmd;
- miq.miq_len = rlen;
- miq.miq_timeout = tmo;
- miq.miq_fam = fam;
- miq.miq_ifidx = ifidx;
- miq.miq_class = class;
- miq.miq_type = type;
- iov[0].iov_base = &mih;
- iov[0].iov_len = sizeof(struct mipc_head);
- iov[1].iov_base = &miq;
- iov[1].iov_len = sizeof(struct mipc_query);
- iov[2].iov_base = rec;
- iov[2].iov_len = rlen * sizeof(wchar_t);
- mih.mih_msglen += sizeof(struct mipc_query) + (rlen * sizeof(wchar_t));
-
- do {
- n = writev(m->m_sock, iov, 3);
- } while (n < 0 && errno == EINTR);
-
- if (n < 0)
- return (-1);
-
- retval = mid;
- mm = sock_read(m, mid, NULL);
- if (mm->mm_msgtype == MIM_ERROR)
- retval = -1;
- msg_free(mm);
-
- if (retval >= 0 && (cmd == MIQ_CMD_CREG || cmd == MIQ_CMD_ONESHOT)) {
- mw = malloc(sizeof(struct mdns_wait));
- mw->mw_seqid = mid;
- mw->mw_msgtype = MIM_QUERY;
- mw->mw_rrset.mr_class = class;
- mw->mw_rrset.mr_type = type;
- mw->mw_rrset.mr_ifidx = ifidx;
- mw->mw_rrset.mr_family = fam;
- wcscpy(mw->mw_rrset.mr_name, rec);
- TAILQ_INSERT_TAIL(&m->m_wait, mw, mw_next);
- }
-
- return (retval);
-}
-
/*
* Dispatch a query to the daemon
*/
@@ -231,6 +184,8 @@
char *p;
size_t len;
+ MDNS_ASSERT(m);
+
again:
do {
mm = msg_wait(m, mid, tv);
@@ -286,6 +241,585 @@
return (rmid);
}
+void
+mdns_freerrset(struct mdns_rrset *mr)
+{
+
+ free(mr->mr_res);
+}
+
+/*
+ * Array to class (integer) translation
+ */
+int
+mdns_atoc(const char *class)
+{
+ int i;
+
+ for (i = 0; i < class_map_size; i++) {
+ if (strcasecmp(class_map[i].ctm_str, class) == 0)
+ return (class_map[i].ctm_int);
+ }
+ return (-1);
+}
+
+/*
+ * Class to array translation
+ */
+const char *
+mdns_ctoa(int class)
+{
+ int i;
+
+ for (i = 0; i < class_map_size; i++) {
+ if (class == class_map[i].ctm_int)
+ return (class_map[i].ctm_str);
+ }
+ return (NULL);
+}
+
+
+/*
+ * Array to type (integer) translation
+ */
+int
+mdns_atot(int class, const char *type)
+{
+ int i;
+ struct ctmap *type_map = NULL;
+
+ for (i = 0; i < class_map_size; i++) {
+ if (class == class_map[i].ctm_int) {
+ type_map = class_map[i].ctm_child;
+ break;
+ }
+ }
+
+ if (type_map == NULL)
+ return (-1);
+
+ for (i = 0; type_map[i].ctm_int != -1; i++) {
+ if (strcasecmp(type_map[i].ctm_str, type) == 0)
+ return (type_map[i].ctm_int);
+ }
+ return (-1);
+}
+
+/*
+ * Type to array translation
+ */
+const char *
+mdns_ttoa(int class, int type)
+{
+ int i;
+ struct ctmap *type_map = NULL;
+
+ for (i = 0; i < class_map_size; i++) {
+ if (class == class_map[i].ctm_int) {
+ type_map = class_map[i].ctm_child;
+ break;
+ }
+ }
+
+ if (type_map == NULL)
+ return (NULL);
+
+ for (i = 0; type_map[i].ctm_int != -1; i++) {
+ if (type_map[i].ctm_int == type)
+ return (type_map[i].ctm_str);
+ }
+ return (NULL);
+}
+
+/*
+ * Auto-convert the given resource set into a more readable format. The
+ * returned pointer must be passed to mdns_free_resource()
+ */
+void *
+mdns_get_resource(struct mdns_rrset *mr)
+{
+ int error;
+
+ if (mr->mr_class != mdns_c_in)
+ return (mr->mr_res);
+ else if (mr->mr_reslen == 0 || mr->mr_res == NULL)
+ return (NULL);
+
+ switch (mr->mr_type) {
+ case mdns_in_a:
+ if (mr->mr_reslen != sizeof(struct in_addr))
+ return (NULL);
+ return (mr->mr_res);
+ case mdns_in_aaaa:
+ if (mr->mr_reslen != sizeof(struct in6_addr))
+ return (NULL);
+ return (mr->mr_res);
+ case mdns_in_ptr:
+ case mdns_in_cname: {
+ wchar_t *nam;
+
+ nam = malloc((mr->mr_reslen + 1) * sizeof(wchar_t));
+ if (nam == NULL)
+ return (NULL);
+ error = utf8_decode(mr->mr_res, mr->mr_reslen, nam,
+ mr->mr_reslen + 1);
+ if (error <= 0) {
+ free(nam);
+ return (NULL);
+ }
+ return (nam);
+ break;
+ }
+ case mdns_in_txt: {
+ char *p, *q, **txt;
+ size_t len;
+ uint8_t slen;
+ int num;
+
+ num = 2;
+ txt = malloc(sizeof(char *) * num);
+ if (txt == NULL)
+ return (NULL);
+
+ len = mr->mr_reslen;
+ p = mr->mr_res;
+ while (len != 0 && p < (mr->mr_res + mr->mr_reslen)) {
+ memcpy(&slen, p++, sizeof(uint8_t));
+ if (slen > --len) {
+ free(txt);
+ return (NULL);
+ }
+
+ q = malloc(slen + 1);
+ memcpy(q, p, slen);
+ q[slen] = '\0';
+ txt[num - 2] = q;
+ txt[num - 1] = NULL;
+ txt = realloc(txt, sizeof(char *) * ++num);
+ p += slen;
+ len -= slen;
+ }
+ return (txt);
+ break;
+ }
+ case mdns_in_srv: {
+ struct mdns_res_in_srv *srv;
+ char *p;
+ uint16_t tmp;
+ size_t len;
+
+ if (mr->mr_reslen < 6)
+ return (NULL);
+
+ srv = malloc(sizeof(struct mdns_res_in_srv));
+ if (srv == NULL)
+ return (NULL);
+ p = mr->mr_res;
+ len = mr->mr_reslen;
+ memcpy(&tmp, p, sizeof(uint16_t));
+ p += sizeof(uint16_t);
+ srv->srv_pri = htons(tmp);
+
+ memcpy(&tmp, p, sizeof(uint16_t));
+ p += sizeof(uint16_t);
+ srv->srv_wei = htons(tmp);
+
+ memcpy(&tmp, p, sizeof(uint16_t));
+ p += sizeof(uint16_t);
+ srv->srv_prt = htons(tmp);
+
+ len -= sizeof(uint16_t) * 3;
+ srv->srv_nam = malloc((len + 1) * sizeof(wchar_t));
+ error = utf8_decode(p, len, srv->srv_nam, len + 1);
+ if (error <= 0) {
+ free(srv->srv_nam);
+ free(srv);
+ return (NULL);
+ }
+ return (srv);
+ }
+ default:
+ return (mr->mr_res);
+ }
+ return (NULL);
+}
+
+/*
+ * Free readable resource format created by mdns_get_resource()
+ */
+void
+mdns_free_resource(struct mdns_rrset *mr, void *res)
+{
+
+ if (mr->mr_class != mdns_c_in)
+ return;
+ else if (res == NULL)
+ return;
+
+ switch (mr->mr_type) {
+ case mdns_in_ptr:
+ case mdns_in_cname:
+ free(res);
+ break;
+ case mdns_in_txt: {
+ char **p;
+ int i;
+
+ for (p = res, i = 0; p[i] != NULL; i++)
+ free(p[i]);
+ free(res);
+ break;
+ }
+ case mdns_in_srv: {
+ struct mdns_res_in_srv *srv;
+
+ srv = res;
+ free(srv->srv_nam);
+ free(srv);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+int
+mdns_db_name_add(struct mdns *m, const char *ident, unsigned int ifidx,
+ int flags, const wchar_t *nam)
+{
+ int mid, error;
+ size_t ilen, nlen;
+ struct mdns_msg *mm;
+ struct mipc_dbident mii;
+ struct mipc_dbi_name miin;
+
+ MDNS_ASSERT(m);
+
+ ilen = strlen(ident);
+ if (ilen == 0)
+ return (-1);
+ nlen = wcslen(nam);
+ if (nlen == 0)
+ return (-1);
+
+ mii.mii_ifidx = ifidx;
+ mii.mii_len = ilen;
+ if (flags & MDNS_NAM_SHARED)
+ mii.mii_shared = 1;
+ mii.mii_zero = 0;
+ mid = docmd(m, MIM_IDENT_ADD, 2, &mii,
+ sizeof(struct mipc_dbident), ident, ilen);
+ if (mid < 0)
+ return (-1);
+ mm = msg_wait(m, mid, NULL);
+ if (mm == NULL)
+ return (-1);
+
+ if (mm->mm_msgtype == MIM_ERROR) {
+ if (errormsg(mm) != MIE_EXISTS) {
+ msg_free(mm);
+ return (-1);
+ }
+ }
+ msg_free(mm);
+
+ miin.miin_ifidx = ifidx;
+ miin.miin_ilen = ilen;
+ miin.miin_len = nlen;
+ miin.miin_elen = 0;
+ miin.miin_active = 0;
+ miin.miin_zero = 0;
+ mid = docmd(m, MIM_IDENT_NAME_ADD, 3, &miin,
+ sizeof(struct mipc_dbi_name), ident, ilen, nam,
+ nlen * sizeof(wchar_t));
+ if (mid < 0)
+ return (-1);
+
+ mm = msg_wait(m, mid, NULL);
+ if (mm == NULL)
+ return (-1);
+
+ error = errormsg(mm);
+ msg_free(mm);
+ if (error >= 0)
+ return (-1);
+ return (0);
+}
+
+int
+mdns_db_name_del(struct mdns *m, const char *ident, unsigned int ifidx,
+ const wchar_t *nam)
+{
+ size_t ilen, nlen;
+ int mid, error;
+ struct mdns_msg *mm;
+ struct mipc_dbi_name miin;
+
+ MDNS_ASSERT(m);
+
+ ilen = strlen(ident);
+ if (ilen == 0)
+ return (-1);
+ nlen = wcslen(nam);
+ if (nlen == 0)
+ return (-1);
+
+ miin.miin_ifidx = ifidx;
+ miin.miin_ilen = ilen;
+ miin.miin_len = nlen;
+ miin.miin_elen = 0;
+ miin.miin_active = 0;
+ miin.miin_zero = 0;
+ mid = docmd(m, MIM_IDENT_NAME_DEL, 3, &miin,
+ sizeof(struct mipc_dbi_name), ident, ilen, nam,
+ nlen * sizeof(wchar_t));
+
+ mm = msg_wait(m, mid, NULL);
+ if (mm == NULL)
+ return (-1);
+
+ error = errormsg(mm);
+ msg_free(mm);
+ if (error >= 0)
+ return (-1);
+
+ /* FIXME Auto remove ident if this was the last name */
+
+ return (0);
+}
+
+int
+mdns_db_res_add(struct mdns *m, const char *ident, unsigned int ifidx,
+ uint16_t class, uint16_t type, uint32_t ttl, int rhint, const void *res)
+{
+ size_t ilen, rlen;
+ int mid, error, ptr;
+ struct mdns_msg *mm;
+ struct mipc_dbident mii;
+ struct mipc_dbi_res_set mirs;
+
+ ilen = strlen(ident);
+ if (ilen == 0)
+ return (-1);
+
+ if (rhint == MDNS_RES_DEFAULT) {
+ mirs.mirs_rlen = wcslen((const wchar_t *)res);
+ rlen = mirs.mirs_rlen * sizeof(wchar_t);
+ ptr = 0;
+ }
+ else if (rhint == MDNS_RES_POINTER) {
+ rlen = strlen((const char *)res);
+ mirs.mirs_rlen = rlen;
+ ptr = 1;
+ }
+ else
+ return (-1);
+
+ mii.mii_ifidx = ifidx;
+ mii.mii_len = ilen;
+ mid = docmd(m, MIM_IDENT_ADD, 2, &mii,
+ sizeof(struct mipc_dbident), ident, ilen);
+ if (mid < 0)
+ return (-1);
+ mm = msg_wait(m, mid, NULL);
+ if (mm == NULL)
+ return (-1);
+
+ if (mm->mm_msgtype == MIM_ERROR) {
+ if (errormsg(mm) != MIE_EXISTS) {
+ msg_free(mm);
+ return (-1);
+ }
+ }
+ msg_free(mm);
+
+ mirs.mirs_ifidx = ifidx;
+ mirs.mirs_class = class;
+ mirs.mirs_type = type;
+ mirs.mirs_ttl = ttl;
+ mirs.mirs_ilen = ilen;
+ mirs.mirs_pointer = ptr;
+ mirs.mirs_zero = 0;
+
+ mid = docmd(m, MIM_IDENT_RES_ADD, 3,
+ &mirs, sizeof(struct mipc_dbi_res_set),
+ ident, ilen, res, rlen);
+ if (mid < 0)
+ return (-1);
+
+ mm = msg_wait(m, mid, NULL);
+ if (mm == NULL)
+ return (-1);
+
+ error = errormsg(mm);
+ msg_free(mm);
+ if (error >= 0)
+ return (-1);
+ return (0);
+}
+
+int
+mdns_db_res_del(struct mdns *m, const char *ident, unsigned int ifidx,
+ uint16_t class, uint16_t type, int rhint, const void *res)
+{
+ size_t ilen, rlen;
+ int mid, error, ptr;
+ struct mdns_msg *mm;
+ struct mipc_dbi_res_set mirs;
+
+ ilen = strlen(ident);
+ if (ilen == 0)
+ return (-1);
+
+ if (rhint == MDNS_RES_DEFAULT) {
+ mirs.mirs_rlen = wcslen((const wchar_t *)res);
+ rlen = mirs.mirs_rlen * sizeof(wchar_t);
+ ptr = 0;
+ }
+ else if (rhint == MDNS_RES_POINTER) {
+ rlen = strlen((const char *)res);
+ mirs.mirs_rlen = rlen;
+ ptr = 1;
+ }
+ else
+ return (-1);
+
+ mirs.mirs_ifidx = ifidx;
+ mirs.mirs_class = class;
+ mirs.mirs_type = type;
+ mirs.mirs_ttl = 0;
+ mirs.mirs_ilen = ilen;
+ mirs.mirs_pointer = ptr;
+ mirs.mirs_zero = 0;
+
+ mid = docmd(m, MIM_IDENT_RES_DEL, 3,
+ &mirs, sizeof(struct mipc_dbi_res_set),
+ ident, ilen, res, rlen);
+
+ mm = msg_wait(m, mid, NULL);
+ if (mm == NULL)
+ return (-1);
+
+ error = errormsg(mm);
+ msg_free(mm);
+ if (error >= 0)
+ return (-1);
+ return (0);
+}
+
+static int
+errormsg(struct mdns_msg *mm)
+{
+ struct mipc_error *mie;
+
+ if (mm->mm_msgtype != MIM_ERROR)
+ return (-1);
+
+ mie = (struct mipc_error *)mm->mm_buf;
+ return (mie->mie_code);
+}
+
+static int
+docmd(struct mdns *m, int cmd, int count, ...)
+{
+ va_list ap;
+ int mid, i, n;
+ void *payload;
+ size_t plen, msglen;
+ struct mipc_head mih;
+
+ msglen = sizeof(struct mipc_head);
+
+ va_start(ap, count);
+ for (i = 0; i < count; i++) {
+ payload = va_arg(ap, void *);
+ plen = va_arg(ap, size_t);
+ msglen += plen;
+ }
+ va_end(ap);
+
+ mid = ipc_sethdr(m, &mih, cmd);
+ mih.mih_msglen = msglen;
+ do {
+ n = write(m->m_sock, &mih, sizeof(struct mipc_head));
+ } while (n < 0 && errno == EINTR);
+ if (n <= 0)
+ return (-1);
+
+ va_start(ap, count);
+ for (i = 0; i < count; i++) {
+ payload = va_arg(ap, void *);
+ plen = va_arg(ap, size_t);
+ n = write(m->m_sock, payload, plen);
+ }
+ va_end(ap);
+ return (mid);
+}
+
+/*
+ * Submit a query to the daemon
+ */
+static int
+doquery(struct mdns *m, int cmd, int fam, int ifidx, int tmo, int class,
+ int type, wchar_t *rec)
+{
+ size_t rlen;
+ int n, mid, retval = 0;
+ struct mdns_msg *mm;
+ struct mdns_wait *mw;
+ struct mipc_head mih;
+ struct mipc_query miq;
+ struct iovec iov[3];
+
+ rlen = wcslen(rec);
+ if (rlen >= MDNS_NAME_LEN)
+ return (-1);
+
+ mid = ipc_sethdr(m, &mih, MIM_QUERY);
+ miq.miq_cmd = cmd;
+ miq.miq_len = rlen;
+ miq.miq_timeout = tmo;
+ miq.miq_fam = fam;
+ miq.miq_ifidx = ifidx;
+ miq.miq_class = class;
+ miq.miq_type = type;
+
+ iov[0].iov_base = &mih;
+ iov[0].iov_len = sizeof(struct mipc_head);
+ iov[1].iov_base = &miq;
+ iov[1].iov_len = sizeof(struct mipc_query);
+ iov[2].iov_base = rec;
+ iov[2].iov_len = rlen * sizeof(wchar_t);
+ mih.mih_msglen += sizeof(struct mipc_query) + (rlen * sizeof(wchar_t));
+
+ do {
+ n = writev(m->m_sock, iov, 3);
+ } while (n < 0 && errno == EINTR);
+
+ if (n < 0)
+ return (-1);
+
+ retval = mid;
+ mm = sock_read(m, mid, NULL);
+ if (mm->mm_msgtype == MIM_ERROR)
+ retval = -1;
+ msg_free(mm);
+
+ if (retval >= 0 && (cmd == MIQ_CMD_CREG || cmd == MIQ_CMD_ONESHOT)) {
+ mw = malloc(sizeof(struct mdns_wait));
+ mw->mw_seqid = mid;
+ mw->mw_msgtype = MIM_QUERY;
+ mw->mw_rrset.mr_class = class;
+ mw->mw_rrset.mr_type = type;
+ mw->mw_rrset.mr_ifidx = ifidx;
+ mw->mw_rrset.mr_family = fam;
+ wcscpy(mw->mw_rrset.mr_name, rec);
+ TAILQ_INSERT_TAIL(&m->m_wait, mw, mw_next);
+ }
+
+ return (retval);
+}
+
static void
msg_free(struct mdns_msg *mm)
{
@@ -503,92 +1037,8 @@
return (mih->mih_id);
}
-extern struct ctmap class_map[];
-extern int class_map_size;
-
-/*
- * Array to class (integer) translation
- */
-int
-mdns_atoc(const char *class)
-{
- int i;
-
- for (i = 0; i < class_map_size; i++) {
- if (strcasecmp(class_map[i].ctm_str, class) == 0)
- return (class_map[i].ctm_int);
- }
- return (-1);
-}
-
-/*
- * Class to array translation
- */
-const char *
-mdns_ctoa(int class)
-{
- int i;
-
- for (i = 0; i < class_map_size; i++) {
- if (class == class_map[i].ctm_int)
- return (class_map[i].ctm_str);
- }
- return (NULL);
-}
-/*
- * Array to type (integer) translation
- */
-int
-mdns_atot(int class, const char *type)
-{
- int i;
- struct ctmap *type_map = NULL;
-
- for (i = 0; i < class_map_size; i++) {
- if (class == class_map[i].ctm_int) {
- type_map = class_map[i].ctm_child;
- break;
- }
- }
-
- if (type_map == NULL)
- return (-1);
-
- for (i = 0; type_map[i].ctm_int != -1; i++) {
- if (strcasecmp(type_map[i].ctm_str, type) == 0)
- return (type_map[i].ctm_int);
- }
- return (-1);
-}
-
-/*
- * Type to array translation
- */
-const char *
-mdns_ttoa(int class, int type)
-{
- int i;
- struct ctmap *type_map = NULL;
-
- for (i = 0; i < class_map_size; i++) {
- if (class == class_map[i].ctm_int) {
- type_map = class_map[i].ctm_child;
- break;
- }
- }
-
- if (type_map == NULL)
- return (NULL);
-
- for (i = 0; type_map[i].ctm_int != -1; i++) {
- if (type_map[i].ctm_int == type)
- return (type_map[i].ctm_str);
- }
- return (NULL);
-}
-
static ssize_t
utf8_decode(char *src, size_t slen, wchar_t *dst, size_t dlen)
{
@@ -633,147 +1083,3 @@
return (len);
}
-void *
-mdns_get_resource(struct mdns_rrset *mr)
-{
- int error;
-
- if (mr->mr_class != mdns_c_in)
- return (mr->mr_res);
- else if (mr->mr_reslen == 0 || mr->mr_res == NULL)
- return (NULL);
-
- switch (mr->mr_type) {
- case mdns_in_a:
- if (mr->mr_reslen != sizeof(struct in_addr))
- return (NULL);
- return (mr->mr_res);
- case mdns_in_aaaa:
- if (mr->mr_reslen != sizeof(struct in6_addr))
- return (NULL);
- return (mr->mr_res);
- case mdns_in_ptr:
- case mdns_in_cname: {
- wchar_t *nam;
-
- nam = malloc((mr->mr_reslen + 1) * sizeof(wchar_t));
- if (nam == NULL)
- return (NULL);
- error = utf8_decode(mr->mr_res, mr->mr_reslen, nam,
- mr->mr_reslen + 1);
- if (error <= 0) {
- free(nam);
- return (NULL);
- }
- return (nam);
- break;
- }
- case mdns_in_txt: {
- char *p, *q, **txt;
- size_t len;
- uint8_t slen;
- int num;
-
- num = 2;
- txt = malloc(sizeof(char *) * num);
- if (txt == NULL)
- return (NULL);
-
- len = mr->mr_reslen;
- p = mr->mr_res;
- while (len != 0 && p < (mr->mr_res + mr->mr_reslen)) {
- memcpy(&slen, p++, sizeof(uint8_t));
- if (slen > --len) {
- free(txt);
- return (NULL);
- }
-
- q = malloc(slen + 1);
- memcpy(q, p, slen);
- q[slen] = '\0';
- txt[num - 2] = q;
- txt[num - 1] = NULL;
- txt = realloc(txt, sizeof(char *) * ++num);
- p += slen;
- len -= slen;
- }
- return (txt);
- break;
- }
- case mdns_in_srv: {
- struct mdns_res_in_srv *srv;
- char *p;
- uint16_t tmp;
- size_t len;
-
- if (mr->mr_reslen < 6)
- return (NULL);
-
- srv = malloc(sizeof(struct mdns_res_in_srv));
- if (srv == NULL)
- return (NULL);
- p = mr->mr_res;
- len = mr->mr_reslen;
- memcpy(&tmp, p, sizeof(uint16_t));
- p += sizeof(uint16_t);
- srv->srv_pri = htons(tmp);
-
- memcpy(&tmp, p, sizeof(uint16_t));
- p += sizeof(uint16_t);
- srv->srv_wei = htons(tmp);
-
- memcpy(&tmp, p, sizeof(uint16_t));
- p += sizeof(uint16_t);
- srv->srv_prt = htons(tmp);
-
- len -= sizeof(uint16_t) * 3;
- srv->srv_nam = malloc((len + 1) * sizeof(wchar_t));
- error = utf8_decode(p, len, srv->srv_nam, len + 1);
- if (error <= 0) {
- free(srv->srv_nam);
- free(srv);
- return (NULL);
- }
- return (srv);
- }
- default:
- return (mr->mr_res);
- }
- return (NULL);
-}
-
-void
-mdns_free_resource(struct mdns_rrset *mr, void *res)
-{
-
- if (mr->mr_class != mdns_c_in)
- return;
- else if (res == NULL)
- return;
-
- switch (mr->mr_type) {
- case mdns_in_ptr:
- case mdns_in_cname:
- free(res);
- break;
- case mdns_in_txt: {
- char **p;
- int i;
-
- for (p = res, i = 0; p[i] != NULL; i++)
- free(p[i]);
- free(res);
- break;
- }
- case mdns_in_srv: {
- struct mdns_res_in_srv *srv;
-
- srv = res;
- free(srv->srv_nam);
- free(srv);
- break;
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list