PERFORCE change 125012 for review
Fredrik Lindberg
fli at FreeBSD.org
Fri Aug 10 05:33:34 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125012
Change 125012 by fli at fli_nexus on 2007/08/10 12:33:25
- Add a name validation function that verifies name length,
label length, removes duplicated label separators and make
sure names are properly dot-terminated.
- Add a (correct) TXT resource encoding function.
- Some minor whitespace fixes.
Affected files ...
.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/mdns.h#7 edit
.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/stack_util.c#5 edit
Differences ...
==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/mdns.h#7 (text+ko) ====
@@ -99,7 +99,7 @@
char *bufptr; /* Direct buffer data pointer */
char **offsets; /* Section offset pointers */
int last_offset;
- TAILQ_HEAD(, mdns_pkg_res) res_head;
+ TAILQ_HEAD(, mdns_pkg_res) res_head;
} p_data[4];
#define p_buf(x) p_data[x].bufptr
#define p_bufseg(x) p_data[x].buf
@@ -292,5 +292,6 @@
int mdns_type_atoi(const char *);
void * mdns_res_encode(uint16_t, uint16_t, void *, int, size_t, size_t *);
char * mdns_name_encode(wchar_t *, size_t, int);
+int mdns_name_validate(char *, size_t *, size_t);
#endif /* _MDNS_H_ */
==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/stack_util.c#5 (text+ko) ====
@@ -37,6 +37,7 @@
#include <strings.h>
#include "mdns.h"
+#include "stack_mdns.h"
#include "utf8.h"
struct char2type {
@@ -270,7 +271,7 @@
}
/*
- * Resource data encoder to CNAME,TXT
+ * Resource data encoder to CNAME
*/
static void *
enc_in_string(void *data, int flags, size_t dlen, size_t *rlen)
@@ -297,6 +298,41 @@
}
/*
+ * Resource data encoder to TXT
+ */
+static void *
+enc_in_text(void *data, int flags, size_t dlen, size_t *rlen)
+{
+ char *r, *p, *q;
+ size_t len;
+
+ r = NULL;
+ if (flags & (MDNS_ENC_CHAR | MDNS_ENC_WCHAR)) {
+ p = data;
+ if (flags & MDNS_ENC_WCHAR) {
+ p = q = malloc(255);
+ len = wcstombs(q, data, 255);
+ }
+
+ len = dlen & 0xff;
+ r = malloc(len + 1);
+ *r = len;
+ memcpy(r+1, p, len);
+ if (flags & MDNS_ENC_CHAR)
+ free(q);
+ *rlen = len + 1;
+ }
+ else if (flags & MDNS_ENC_BINARY) {
+ len = dlen & 0xff;
+ r = malloc(len + 1);
+ *r = len;
+ memcpy(r+1, data, len);
+ *rlen = len + 1;
+ }
+ return (r);
+}
+
+/*
* Table of recognized IN types for which a resource encoding
* function exists.
*/
@@ -307,7 +343,7 @@
#endif
{ .em_type = mdns_in_ptr, .em_encoder = enc_in_ptr },
{ .em_type = mdns_in_cname, .em_encoder = enc_in_string },
- { .em_type = mdns_in_txt, .em_encoder = enc_in_string }
+ { .em_type = mdns_in_txt, .em_encoder = enc_in_text }
};
static int res_enc_table_size = sizeof(res_enc_table) / sizeof(struct encmap);
@@ -333,6 +369,7 @@
{
char *p, *res = NULL;
size_t rlen;
+ int error;
char addr[MDNS_RECORD_LEN];
/*
@@ -364,12 +401,70 @@
#endif
}
- if (flags & MDNS_ENC_ADDR)
+ if (flags & MDNS_ENC_ADDR) {
res = enc_in_ptr(data, flags | MDNS_ENC_WCHAR, dlen, &rlen);
+ }
else {
res = malloc(MDNS_RECORD_LEN);
- utf8_encode(data, res, MDNS_RECORD_LEN);
+ rlen = utf8_encode(data, res, MDNS_RECORD_LEN);
+ if ((ssize_t)rlen <= 0) {
+ free(res);
+ res = NULL;
+ }
+ }
+
+ if (res != NULL) {
+ error = mdns_name_validate(res, &rlen, MDNS_RECORD_LEN);
+ if (error < 0) {
+ free(res);
+ res = NULL;
+ }
}
return (res);
}
+
+/*
+ * Validate a name and fix errors where possible.
+ */
+int
+mdns_name_validate(char *name, size_t *namlen, size_t buflen)
+{
+ char *p;
+ size_t len, llen;
+
+ /*
+ * Length check, the maximum length on-wire is 255, which
+ * in pratice results in maximum 254 real chars (incl. final dot).
+ */
+ if (name[*namlen] != '.' && *namlen >= (MDNS_RECORD_LEN - 1))
+ return (-1);
+ else if (*namlen >= MDNS_RECORD_LEN)
+ return (-1);
+
+ len = *namlen;
+ llen = 0;
+ for (p = name; *p != '\0'; p++) {
+ if (*p == '.') {
+ /* Remove duplicate zero length labels */
+ if (llen == 0)
+ memmove(p - 1, p, --len);
+ llen = 0;
+ }
+ /* Validate label length */
+ else if (++llen > MDNS_PKG_LABEL_LEN)
+ return (-1);
+ }
+
+ /* Make sure name is dot-terminated */
+ if (*(p - 1) != '.') {
+ if (len >= buflen)
+ return (-1);
+ *p = '.';
+ *++p = '\0';
+ len++;
+ }
+
+ *namlen = len;
+ return (0);
+}
More information about the p4-projects
mailing list