From a9e01b3bd67c8a536de789416700f1bf7286dd60521ba40562254512090879cd Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Mon, 18 Dec 2006 23:17:15 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/openslp?expand=0&rev=1 --- .gitattributes | 23 + .gitignore | 1 + README.SuSE | 55 + extensions.diff | 4044 ++++++++++++++++++++++++++++++++++++++ hppa.diff | 11 + openslp-1.2.0.tar.bz2 | 3 + openslp-devel.desktop | 4 + openslp.audit.diff | 540 +++++ openslp.changes | 258 +++ openslp.checkovr.diff | 57 + openslp.desktop | 4 + openslp.diff | 136 ++ openslp.doubleequal.diff | 59 + openslp.emptyanswer.diff | 20 + openslp.logrotate | 14 + openslp.poll.diff | 853 ++++++++ openslp.spec | 385 ++++ openslp.tcpclearovr.diff | 27 + openslp.truncate.diff | 188 ++ openslp.v1sladdr.diff | 34 + ready | 0 slpd.init | 72 + slptool-timeout.diff | 11 + v1dadiscovery.diff | 67 + 24 files changed, 6866 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.SuSE create mode 100644 extensions.diff create mode 100644 hppa.diff create mode 100644 openslp-1.2.0.tar.bz2 create mode 100644 openslp-devel.desktop create mode 100644 openslp.audit.diff create mode 100644 openslp.changes create mode 100644 openslp.checkovr.diff create mode 100644 openslp.desktop create mode 100644 openslp.diff create mode 100644 openslp.doubleequal.diff create mode 100644 openslp.emptyanswer.diff create mode 100644 openslp.logrotate create mode 100644 openslp.poll.diff create mode 100644 openslp.spec create mode 100644 openslp.tcpclearovr.diff create mode 100644 openslp.truncate.diff create mode 100644 openslp.v1sladdr.diff create mode 100644 ready create mode 100644 slpd.init create mode 100644 slptool-timeout.diff create mode 100644 v1dadiscovery.diff diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/README.SuSE b/README.SuSE new file mode 100644 index 0000000..eec4511 --- /dev/null +++ b/README.SuSE @@ -0,0 +1,55 @@ +# +# Service Location Protocol on SuSE +# + +The Service Location Protcol (SLP) is part of the zerconf concept to provide +service informations inside a local network. + +# +# The client side +# + +Your client can search for avaible services using the slp library or via +using the slptool binary (for scripting). + +WARNING: Have in mind that you can usually NOT trust the results. + It is up to the service client to validate the server. + Do NOT authentificate to an untrusted server or it might be + possible it gets your password. + +# +# The server side +# + +Every system which provides a service which should get announced with SLP +in the network needs also to run the slpd. There are several possible ways +to announce the service: + + 1) The authors of any service daemon should directly use libslp to + register the service on the server. Documentation for this can be + found in /usr/share/doc/packages/openslp/html/ProgrammersGuide/ + + 2) Packages without direct SLP support should provide a registration + file in the /etc/slp.reg.d/ directory. See below for a template. + You can use the pseudo attributes watch-port-tcp and watch-port-udp + to make slpd check if the service is listening on the specified port. + This way a not-running service won't get announced by slpd. + + 3) Administrators can add service lines in the /etc/slp.reg file. + + 4) The slptool can be used to register a service in any script. + + +Example of a registration file. +This could be used to announce the sane daemon running on port 6566 +------------------------------------------------------------------------ +## Register a saned service on this system +## en means english language +## 65535 disables the timeout, so the service registration does +## not need refreshs +service:scanner.sane://$HOSTNAME:6566,en,65535 +# only announce the service if a daemon is listening on tcp port 6566 +watch-port-tcp=6566 +description=SANE scanner daemon +------------------------------------------------------------------------ + diff --git a/extensions.diff b/extensions.diff new file mode 100644 index 0000000..e3db9c6 --- /dev/null +++ b/extensions.diff @@ -0,0 +1,4044 @@ +--- ./common/Makefile.am.orig 2003-02-13 05:19:57.000000000 +0000 ++++ ./common/Makefile.am 2006-11-16 16:19:30.000000000 +0000 +@@ -24,6 +24,7 @@ libcommonlibslp_la_SOURCES = \ + slp_parse.c \ + slp_pid.c \ + slp_dhcp.c \ ++ slp_mdns.c \ + $(slp_v1message_SRCS) \ + $(slp_security_SRCS) + +@@ -46,6 +47,7 @@ libcommonslpd_la_SOURCES = \ + slp_filter_l.l \ + slp_predicate.c \ + slp_dhcp.c \ ++ slp_mdns.c \ + $(slp_v1message_SRCS) \ + $(slp_security_SRCS) + +@@ -75,6 +77,7 @@ noinst_HEADERS = \ + slp_filter.h \ + slp_filter_y.h \ + slp_predicate.h \ ++ slp_mdns.h \ + slp_dhcp.h + + AM_YFLAGS = -d +--- ./common/slp_compare.c.orig 2002-12-03 21:04:49.000000000 +0000 ++++ ./common/slp_compare.c 2006-11-16 16:19:30.000000000 +0000 +@@ -146,6 +146,17 @@ int SLPCompareNamingAuth(int srvtypelen, + if(namingauthlen == 0xffff) /* match all naming authorities */ + return 0; + ++ /* Skip "service:" */ ++ if(srvtypelen > 8 && strncasecmp(srvtype,"service:",8) == 0) ++ { ++ srvtypelen -= 8; ++ srvtype += 8; ++ } ++ dot = memchr(srvtype,':',srvtypelen); ++ if (dot) ++ { ++ srvtypelen = dot - srvtype; ++ } + dot = memchr(srvtype,'.',srvtypelen); + + if(!namingauthlen) /* IANA naming authority */ +--- ./common/slp_mdns.c.orig 2006-11-16 16:19:30.000000000 +0000 ++++ ./common/slp_mdns.c 2006-11-16 16:19:30.000000000 +0000 +@@ -0,0 +1,573 @@ ++#include "slp_mdns.h" ++#include "slp_message.h" ++ ++ ++#ifdef DEBUG ++ ++#include ++ ++unsigned char *SLPMDNSDumpN(unsigned char *bp, unsigned char *start) ++{ ++ unsigned char *obp = 0; ++ int x; ++ ++ for (;;) { ++ if ((*bp & 0xc0) == 0xc0) { ++ if (!obp) ++ obp = bp + 2; ++ x = (*bp & 0x3f) << 8 | bp[1]; ++ printf("%d:", x); ++ bp = start + x; ++ } ++ if (!*bp) { ++ printf("0"); ++ return obp ? obp : bp + 1; ++ } ++ printf("%d ", *bp); ++ fwrite(bp + 1, *bp, 1, stdout); ++ printf(" "); ++ bp += *bp + 1; ++ } ++} ++ ++unsigned char *SLPMDNSDumpRR(unsigned char *start, unsigned char *bp) ++{ ++ int t, l, l2; ++ printf(" "); ++ bp = SLPMDNSDumpN(bp, start); ++ t = AsUINT16(bp); ++ printf(" TYPE=%d CLASS=%d TTL=%d", t, AsUINT16(bp + 2), AsUINT32(bp + 4)); ++ l = AsUINT16(bp + 8); ++ bp += 10; ++ if (t == DNS_TYPE_A) ++ printf(" A=%d.%d.%d.%d", bp[0], bp[1], bp[2], bp[3]); ++ else if (t == DNS_TYPE_AAAA) ++ printf(" AAAA=%02x.%02x.%02x.%02x....", bp[0], bp[1], bp[2], bp[3]); ++ else if (t == DNS_TYPE_PTR) ++ { ++ putchar(' '); ++ SLPMDNSDumpN(bp, start); ++ } ++ else if (t == DNS_TYPE_SRV) ++ { ++ printf(" PRIO=%d WEIGHT=%d PORT=%d ", AsUINT16(bp), AsUINT16(bp + 2), AsUINT16(bp + 4)); ++ SLPMDNSDumpN(bp + 6, start); ++ } ++ else if (t == DNS_TYPE_TXT) ++ { ++ while (l > 0) ++ { ++ l2 = *bp++; ++ l--; ++ putchar(' '); ++ putchar('"'); ++ while (l2-- > 0 && l > 0) ++ { ++ putchar(*bp++); ++ l--; ++ } ++ putchar('"'); ++ } ++ } ++ else ++ { ++ while (l > 0) ++ { ++ printf(" %02x", *bp++); ++ l--; ++ } ++ } ++ printf("\n"); ++ return bp + l; ++} ++ ++void SLPMDNSDumpDNS(SLPBuffer buf, char *head) ++{ ++ int qcount, acount, ncount, xcount; ++ unsigned char *start = (unsigned char *)buf->start; ++ unsigned char *bp = start; ++ ++ printf("%s DNS buffer\n", head); ++ printf(" ID %04x", AsUINT16(bp)); ++ printf(" Flags %04x\n", AsUINT16(bp + 2)); ++ qcount = AsUINT16(bp + 4); ++ acount = AsUINT16(bp + 6); ++ ncount = AsUINT16(bp + 8); ++ xcount = AsUINT16(bp + 10); ++ printf(" QCount %d\n", qcount); ++ bp += 12; ++ while (qcount-- > 0) { ++ printf(" "); ++ bp = SLPMDNSDumpN(bp, start); ++ printf(" TYPE=%d CLASS=%d\n", AsUINT16(bp), AsUINT16(bp + 2)); ++ bp += 4; ++ } ++ printf(" ACount %d\n", acount); ++ while (acount-- > 0) { ++ bp = SLPMDNSDumpRR(start, bp); ++ } ++ printf(" NCount %d\n", ncount); ++ while (ncount-- > 0) { ++ bp = SLPMDNSDumpRR(start, bp); ++ } ++ printf(" XCount %d\n", xcount); ++ while (xcount-- > 0) { ++ bp = SLPMDNSDumpRR(start, bp); ++ } ++ printf("\n"); ++} ++ ++void SLPMDNSDumpBuf(unsigned char *buf, int len) ++{ ++ int i; ++ while (len > 0) ++ { ++ for (i = 0; i < 16; i++) ++ { ++ if (i < len) ++ printf(" %02x", buf[i]); ++ else ++ printf(" "); ++ } ++ printf(" "); ++ for (i = 0; i < 16; i++) ++ { ++ if (i < len) ++ putchar(buf[i] >= 32 && buf[i] < 127 ? buf[i] : '.'); ++ else ++ break; ++ } ++ putchar('\n'); ++ len -= 16; ++ buf += 16; ++ } ++} ++ ++#endif ++ ++unsigned char *SLPMDNSParseRR(unsigned char *bp, unsigned char *end, ++ int count, ++ unsigned char **dn, ++ unsigned char **dd, int *dc) ++{ ++ int c = 0; ++ for (; count > 0; count--) ++ { ++ if (dn && c < SLP_MDNS_MAX_RR) ++ dn[c] = bp; ++ while (bp < end && *bp && (*bp & 0xc0) != 0xc0) ++ bp += *bp + 1; ++ if (bp < end && *bp) ++ bp++; ++ if (bp + 11 > end) ++ return end + 1; ++ if (dd && c < SLP_MDNS_MAX_RR) ++ dd[c++] = bp + 1; ++ bp += 11 + AsUINT16((char *)bp + 9); ++ } ++ if (dc) ++ *dc = c; ++ return bp; ++} ++ ++int SLPMDNSCheckN(unsigned char *r, ++ unsigned char *e, ++ unsigned char *a, ++ int ini) ++{ ++ int l = 0; ++ ++ for (;;) ++ { ++ if (a < r || a >= e) ++ return 1; ++ if ((*a & 0xc0) == 0xc0) ++ { ++ ini = 0; ++ a = r + ((*a & 0x3f) << 8 | a[1]); ++ if (a < r || a >= e) ++ return 1; ++ } ++ if (!*a) ++ return 0; ++ if ((*a & 0xc0) != 0) ++ return 1; ++ l += *a + 1; ++ if (ini && ini < l + 1) ++ return 1; ++ a += *a + 1; ++ if (l > 254) ++ return 1; ++ } ++} ++ ++int SLPMDNSCheckRR(unsigned char *r, ++ unsigned char *e, ++ unsigned char **dn, ++ unsigned char **dd, int *dc) ++{ ++ int i, j, c, t, l; ++ ++ c = *dc; ++ for (i = j = 0; i < c; i++) ++ { ++ if (SLPMDNSCheckN(r, e, dn[i], 0)) ++ continue; ++ t = AsUINT16(dd[i]); ++ l = AsUINT16(dd[i] + 8); ++ if (t == DNS_TYPE_PTR) ++ { ++ if (l < 1) ++ continue; ++ if (SLPMDNSCheckN(r, e, dd[i] + 10, l)) ++ continue; ++ } ++ else if (t == DNS_TYPE_A) ++ { ++ if (l < 4) ++ continue; ++ } ++ else if (t == DNS_TYPE_AAAA) ++ { ++ if (l < 16) ++ continue; ++ } ++ else if (t == DNS_TYPE_SRV) ++ { ++ if (l < 7) ++ continue; ++ if (SLPMDNSCheckN(r, e, dd[i] + 16, l - 6)) ++ continue; ++ } ++ if (j < i) ++ { ++ dn[j] = dn[i]; ++ dd[j] = dd[i]; ++ } ++ j++; ++ } ++ *dc = j; ++ return i == j ? 0 : 1; ++} ++ ++int SLPMDNSCmpN(unsigned char *a, unsigned char *ar, ++ unsigned char *b, unsigned char *br) ++{ ++ for (;;) ++ { ++ if ((*a & 0xc0) == 0xc0) ++ a = ar + ((*a & 0x3f) << 8 | a[1]); ++ if ((*b & 0xc0) == 0xc0) ++ b = br + ((*b & 0x3f) << 8 | b[1]); ++ if (*a != *b) ++ return 1; ++ if (*a == 0) ++ return 0; ++ if (memcmp(a + 1, b + 1, *a)) ++ return 1; ++ a += *a + 1; ++ b += *b + 1; ++ } ++} ++ ++unsigned char *SLPMDNSCompN(unsigned char *bp, unsigned char *end, ++ unsigned char *a, unsigned char *ar, ++ unsigned char **cvec, int *ncvecp, ++ unsigned char *r) ++{ ++ int i; ++ unsigned char *first = 0; ++ int ncvec = ncvecp ? *ncvecp : 0; ++ ++ for (;;) ++ { ++ if ((*a & 0xc0) == 0xc0) ++ a = ar + ((*a & 0x3f) << 8 | a[1]); ++ if ((*a & 0xc0) == 0xc0) ++ return 0; ++ if (*a) ++ { ++ for (i = 0; i < ncvec; i++) ++ if (!SLPMDNSCmpN(a, ar, cvec[i], r)) ++ break; ++ if (i < ncvec) ++ { ++ if (bp + 1 >= end) ++ return 0; ++ *bp++ = (cvec[i] - r) >> 8 | 0xc0; ++ *bp++ = (cvec[i] - r) & 0xff; ++ break; ++ } ++ } ++ if (first == 0 && *a) ++ first = bp; ++ if (bp + *a + 1 >= end) ++ return 0; ++ memcpy(bp, a, *a + 1); ++ bp += *a + 1; ++ if (*a == 0) ++ break; ++ a += *a + 1; ++ } ++ if (first && ncvecp && ncvec < 256) ++ { ++ cvec[ncvec] = first; ++ *ncvecp = ncvec + 1; ++ } ++ return bp; ++} ++ ++unsigned char *SLPMDNSNToStr(unsigned char *bp, unsigned char *end, ++ unsigned char *a, unsigned char *ar, int nolastdot) ++{ ++ if (!*a && bp < end) ++ *bp++ = '.'; ++ for (;;) ++ { ++ if ((*a & 0xc0) == 0xc0) ++ a = ar + ((*a & 0x3f) << 8 | a[1]); ++ if (*a >= 64 || bp + *a >= end) ++ return 0; ++ if (!*a) ++ break; ++ memcpy(bp, a + 1, *a); ++ bp += *a; ++ a += *a + 1; ++ if (!nolastdot || *a) ++ *bp++ = '.'; ++ } ++ return bp; ++} ++ ++unsigned char *MDNSStrToN(unsigned char *bp, unsigned char *end, ++ const char *str, int len) ++{ ++ unsigned char *op; ++ ++ for (op = ++bp; ; str++, len--) ++ { ++ if (bp >= end) ++ return 0; ++ if (len == 0 || *str == '.') ++ { ++ if (bp != op) ++ { ++ if (bp - op >= 64) ++ return 0; ++ op[-1] = bp - op; ++ op = ++bp; ++ } ++ if (len == 0) ++ break; ++ continue; ++ } ++ *bp++ = *str; ++ } ++ bp[-1] = 0; ++ return bp; ++} ++ ++unsigned char *SLPMDNSCopyN(unsigned char *bp, unsigned char *end, unsigned char *a, unsigned char *ar) ++{ ++ for (;;) ++ { ++ if ((*a & 0xc0) == 0xc0) ++ a = ar + ((*a & 0x3f) << 8 | a[1]); ++ if (bp + *a + 1 > end) ++ return 0; ++ memcpy(bp, a, *a + 1); ++ bp += *a + 1; ++ if (!*a) ++ return bp; ++ a += *a + 1; ++ } ++} ++ ++unsigned char *SLPMDNSAddRR(unsigned char *bp, unsigned char *start, ++ unsigned char *end, ++ unsigned char *q, unsigned char *qr, ++ int type, ++ int ttl, ++ unsigned char **cvec, ++ int *ncvec, ++ int data1, ++ unsigned char *data2, ++ unsigned char **dp) ++{ ++ unsigned char *oldbp; ++ ++ bp = SLPMDNSCompN(bp, end, q, qr, cvec, ncvec, start); ++ if (!bp || bp + 10 > end) ++ return 0; ++ ToUINT16(bp, type); ++ ToUINT16(bp + 2, DNS_CLASS_IN); ++ ToUINT32(bp + 4, ttl); ++ bp += 10; ++ oldbp = bp; ++ if (type == DNS_TYPE_PTR) ++ { ++ bp = SLPMDNSCompN(bp, end, data2, qr, cvec, ncvec, start); ++ if (!bp) ++ return 0; ++ } ++ else if (type == DNS_TYPE_A) ++ { ++ if (bp + 4 > end) ++ return 0; ++ memcpy(bp, data2, 4); ++ bp += 4; ++ } ++ else if (type == DNS_TYPE_TXT) ++ { ++ if (bp + data1 > end) ++ return 0; ++ memcpy(bp, data2, data1); ++ bp += data1; ++ } ++ else if (type == DNS_TYPE_SRV) ++ { ++ if (bp + 6 > end) ++ return 0; ++ ToUINT16(bp, 0); ++ ToUINT16(bp + 2, 0); ++ ToUINT16(bp + 4, data1); ++ /* rfc says target is not compressed */ ++ bp = SLPMDNSCopyN(bp + 6, end, data2, 0); ++ if (!bp) ++ return 0; ++ } ++ else ++ return 0; ++ ToUINT16(oldbp - 2, bp - oldbp); ++ if (dp) ++ *dp = oldbp - 10; ++ return bp; ++} ++ ++int SLPMDNSNToSrvtype(unsigned char *a, unsigned char *ar, char *buf, int len) ++{ ++ char *sp; ++ int l, l2; ++ ++ if (len < 9) ++ return 0; ++ memcpy(buf, "service", 8); ++ sp = buf + 7; ++ len -= 7; ++ l2 = 1; /* the \0 */ ++ for (;;) ++ { ++ if ((*a & 0xc0) == 0xc0) ++ a = ar + ((*a & 0x3f) << 8 | a[1]); ++ l = *a++; ++ if (l == 0) ++ break; ++ if (l == 4 && (!strncasecmp(a, "_tcp", 4) || !strncasecmp(a, "_udp", 4))) ++ break; ++ if (*a == '_' && l > 1) ++ { ++ a++; ++ l--; ++ } ++ if (l2 + l + 1 > len) ++ return 0; /* doesn't fit */ ++ memmove(sp + l + 1, sp, l2); ++ l2 += l + 1; ++ *sp++ = ':'; ++ for (; l-- > 0; a++) ++ *sp++ = *a != ':' ? *a : '.'; ++ sp = buf + 7; ++ } ++ sp += l2 - 1; ++ if (l2 == 1) ++ { ++ *sp++ = ':'; ++ *sp = 0; ++ } ++ return sp - buf; ++} ++ ++unsigned char *SLPMDNSSrvtypeToN(unsigned char *bp, unsigned char *end, const char *buf, int len) ++{ ++ int l, l2; ++ unsigned char *bb; ++ char *p; ++ ++ if (len > 8 && !strncasecmp(buf, "service:", 8)) ++ { ++ len -= 8; ++ buf += 8; ++ } ++ if (len <= 0) ++ return 0; ++ l2 = 0; ++ for (;;) ++ { ++ p = memchr(buf, ':', len); ++ l = p ? p - buf : len; ++ if (l >= 63 || bp + l2 + l + 2 > end) ++ return 0; ++ if (l2) ++ memmove(bp + l + 2, bp, l2); ++ l2 += l + 2; ++ bb = bp; ++ *bp++ = l + 1; ++ *bp++ = '_'; ++ for (; l > 0; l--) ++ { ++ *bp++ = *buf != '.' ? *buf : ':'; ++ buf++; ++ len--; ++ } ++ bp = bb; ++ if (!p) ++ break; ++ buf++; ++ len--; ++ } ++ bp += l2; ++ if (bp + 12 > end) ++ return 0; ++ memcpy(bp, "\004_tcp\005local\000", 12); ++ return bp + 12; ++} ++ ++char *SLPMDNSFindInTxt(unsigned char *txtbuf, int txtlen, char *name, int *valuelen) ++{ ++ int namelen; ++ int l; ++ ++ namelen = strlen(name); ++ while (txtlen >= namelen + 1) ++ { ++ l = *txtbuf++; ++ if (l >= namelen && !memcmp(txtbuf, name, namelen)) ++ { ++ *valuelen = l - namelen; ++ return txtbuf + namelen; ++ } ++ txtbuf += l; ++ txtlen -= l + 1; ++ } ++ return 0; ++} ++ ++int SLPMDNSAddTxt(unsigned char *txtbuf, int buflen, int *txtlenp, const char *name, const char *value, int valuelen) ++{ ++ int txtlen = *txtlenp; ++ int namelen; ++ char *tp; ++ ++ namelen = strlen(name); ++ if (namelen + valuelen > 255) ++ return 1; ++ if (txtlen + 1 + namelen + valuelen > buflen) ++ return 1; ++ tp = txtbuf + txtlen; ++ *tp++ = namelen + valuelen; ++ memcpy(tp, name, namelen); ++ memcpy(tp + namelen, value, valuelen); ++ *txtlenp = txtlen + 1 + namelen + valuelen; ++ return 0; ++} ++ +--- ./common/slp_mdns.h.orig 2006-11-16 16:19:30.000000000 +0000 ++++ ./common/slp_mdns.h 2006-11-16 16:19:30.000000000 +0000 +@@ -0,0 +1,102 @@ ++#ifndef SLP_MDNS_H_INCLUDED ++#define SLP_MDNS_H_INCLUDED ++ ++#include "slp_buffer.h" ++ ++#define MDNS_RESERVED_PORT 5353 ++#define MDNS_MCAST_ADDRESS 0xe00000fb ++ ++#define DNS_TYPE_A 1 ++#define DNS_TYPE_PTR 12 ++#define DNS_TYPE_HINFO 13 ++#define DNS_TYPE_TXT 16 ++#define DNS_TYPE_AAAA 28 ++#define DNS_TYPE_SRV 33 ++#define DNS_TYPE_ANY 255 ++ ++#define DNS_CLASS_IN 1 ++#define DNS_CLASS_ANY 255 ++ ++#define SLP_MDNS_MAX_RR 128 ++ ++#ifdef DEBUG ++ ++extern unsigned char *SLPMDNSDumpN(unsigned char *bp, ++ unsigned char *start); ++extern unsigned char *SLPMDNSDumpRR(unsigned char *start, ++ unsigned char *bp); ++extern void SLPMDNSDumpDNS(SLPBuffer buf, ++ char *head); ++extern void SLPMDNSDumpBuf(unsigned char *buf, ++ int len); ++#endif ++ ++extern unsigned char *SLPMDNSParseRR(unsigned char *bp, ++ unsigned char *end, ++ int count, ++ unsigned char **dn, ++ unsigned char **dd, ++ int *dc); ++extern int SLPMDNSCheckN(unsigned char *r, ++ unsigned char *e, ++ unsigned char *a, ++ int ini); ++extern int SLPMDNSCheckRR(unsigned char *r, ++ unsigned char *e, ++ unsigned char **dn, ++ unsigned char **dd, int *dc); ++extern int SLPMDNSCmpN(unsigned char *a, ++ unsigned char *ar, ++ unsigned char *b, ++ unsigned char *br); ++extern unsigned char *SLPMDNSCompN(unsigned char *bp, ++ unsigned char *end, ++ unsigned char *a, ++ unsigned char *ar, ++ unsigned char **cvec, ++ int *ncvecp, ++ unsigned char *r); ++extern unsigned char *SLPMDNSNToStr(unsigned char *bp, ++ unsigned char *end, ++ unsigned char *a, ++ unsigned char *ar, ++ int nolastdot); ++extern unsigned char *MDNSStrToN(unsigned char *bp, ++ unsigned char *end, ++ const char *str, ++ int len); ++extern unsigned char *SLPMDNSCopyN(unsigned char *bp, ++ unsigned char *end, ++ unsigned char *a, ++ unsigned char *ar); ++extern unsigned char *SLPMDNSAddRR(unsigned char *bp, ++ unsigned char *start, ++ unsigned char *end, ++ unsigned char *q, unsigned char *qr, ++ int type, ++ int ttl, ++ unsigned char **cvec, ++ int *ncvec, ++ int data1, ++ unsigned char *data2, ++ unsigned char **dp); ++extern int SLPMDNSNToSrvtype(unsigned char *a, ++ unsigned char *ar, ++ char *buf, ++ int len); ++extern unsigned char *SLPMDNSSrvtypeToN(unsigned char *bp, ++ unsigned char *end, ++ const char *buf, ++ int len); ++extern char *SLPMDNSFindInTxt(unsigned char *txtbuf, ++ int txtlen, ++ char *name, ++ int *valuelen); ++extern int SLPMDNSAddTxt(unsigned char *txtbuf, ++ int buflen, ++ int *txtlenp, ++ const char *name, ++ const char *value, ++ int valuelen); ++ ++#endif +--- ./common/slp_message.h.orig 2003-04-04 06:52:07.000000000 +0000 ++++ ./common/slp_message.h 2006-11-16 16:19:30.000000000 +0000 +@@ -170,6 +170,10 @@ typedef UINT32* PUINT32; + #define SLP_REG_SOURCE_LOCAL 2 /* from localhost or IPC */ + #define SLP_REG_SOURCE_STATIC 3 /* from the slp.reg file */ + ++#define SLP_REG_WATCH_TCP (1<<0) ++#define SLP_REG_WATCH_UDP (1<<1) ++#define SLP_REG_WATCH_CHECKING (1<<8) ++#define SLP_REG_WATCH_DEAD (1<<9) + + /*=========================================================================*/ + /* SLP Extension IDs */ +@@ -274,6 +278,8 @@ typedef struct _SLPSrvReg + SLPAuthBlock* autharray; + /* The following are used for OpenSLP specific extensions */ + uint32_t pid; ++ int watchport; ++ int watchflags; + /* The following are not part of the RFC protocol. They are used by */ + /* the OpenSLP implementation for convenience */ + int source; +--- ./common/slp_net.c.orig 2006-11-16 16:19:17.000000000 +0000 ++++ ./common/slp_net.c 2006-11-16 16:19:30.000000000 +0000 +@@ -80,7 +80,19 @@ int SLPNetGetThisHostname(char** hostfdn + + if(gethostname(host, MAX_HOST_NAME) == 0) + { +- he = gethostbyname(host); ++ if (*host >= '0' && *host <= '9' && inet_aton(host, &ifaddr)) ++ { ++ if (numeric_only) ++ { ++ *hostfdn = xstrdup(inet_ntoa(ifaddr)); ++ return 0; ++ } ++ he = gethostbyaddr((char *)&ifaddr, sizeof(ifaddr), AF_INET); ++ } ++ else ++ { ++ he = gethostbyname(host); ++ } + if(he) + { + /* if the hostname has a '.' then it is probably a qualified +--- ./common/slp_property.c.orig 2002-12-03 21:04:50.000000000 +0000 ++++ ./common/slp_property.c 2006-11-16 16:19:30.000000000 +0000 +@@ -219,7 +219,7 @@ int SetDefaultValues() + + + /*=========================================================================*/ +-int SLPPropertyReadFile(const char* conffile) ++int SLPPropertyReadFileFP(FILE *fp) + /* Reads and sets properties from the specified configuration file */ + /* */ + /* conffile (IN) the path of the config file to read. */ +@@ -230,7 +230,6 @@ int SLPPropertyReadFile(const char* conf + { + char* line; + char* alloced; +- FILE* fp; + char* namestart; + char* nameend; + char* valuestart; +@@ -240,6 +239,10 @@ int SLPPropertyReadFile(const char* conf + { + return -1; + } ++ if(!fp) ++ { ++ return 0; ++ } + + alloced = xmalloc(4096); + if(alloced == 0) +@@ -249,14 +252,7 @@ int SLPPropertyReadFile(const char* conf + return -1; + } + +- fp = fopen(conffile,"r"); +- if(!fp) +- { +- goto CLEANUP; +- } +- +- /* Set the property that keeps track of conffile */ +- SLPPropertySet("net.slp.OpenSLPConfigFile",conffile); ++ rewind(fp); + + while(fgets(alloced,4096,fp)) + { +@@ -324,13 +320,6 @@ int SLPPropertyReadFile(const char* conf + } + } + +- +- CLEANUP: +- if(fp) +- { +- fclose(fp); +- } +- + if(alloced) + { + xfree(alloced); +@@ -340,6 +329,33 @@ int SLPPropertyReadFile(const char* conf + } + + /*=========================================================================*/ ++int SLPPropertyReadFile(const char* conffile) ++/* Reads and sets properties from the specified configuration file */ ++/* */ ++/* conffile (IN) the path of the config file to read. */ ++/* */ ++/* Returns - zero on success. non-zero on error. Properties will be set*/ ++/* to default on error. */ ++/*=========================================================================*/ ++{ ++ FILE* fp; ++ int ret; ++ ++ fp = fopen(conffile,"r"); ++ if (fp) ++ { ++ /* Set the property that keeps track of conffile */ ++ SLPPropertySet("net.slp.OpenSLPConfigFile",conffile); ++ } ++ ret = SLPPropertyReadFileFP(fp); ++ if (fp) ++ { ++ fclose(fp); ++ } ++ return ret; ++} ++ ++/*=========================================================================*/ + int SLPPropertyAsBoolean(const char* property) + /*=========================================================================*/ + { +--- ./common/slp_spi.c.orig 2006-11-16 16:19:17.000000000 +0000 ++++ ./common/slp_spi.c 2006-11-16 16:19:30.000000000 +0000 +@@ -395,6 +395,8 @@ SLPCryptoDSAKey* SLPSpiGetDSAKey(SLPSpiH + } + + tmp->key = SLPSpiReadKeyFile(tmp->keyfilename,keytype); ++ if (!tmp->key) ++ return 0; + } + + *key = SLPCryptoDSAKeyDup(tmp->key); +@@ -456,4 +458,15 @@ int SLPSpiCanSign(SLPSpiHandle hspi, + spistr) != 0); + } + +- ++void SLPSpiFill(SLPSpiHandle hspi) ++{ ++ SLPSpiEntry* entry = (SLPSpiEntry*)hspi->cache.head; ++ while(entry) ++ { ++ if(entry->keytype != SLPSPI_KEY_TYPE_PRIVATE || hspi->cacheprivate) ++ { ++ entry->key = SLPSpiReadKeyFile(entry->keyfilename,entry->keytype); ++ } ++ entry = (SLPSpiEntry*)entry->listitem.next; ++ } ++} +--- ./common/slp_spi.h.orig 2002-03-19 23:52:15.000000000 +0000 ++++ ./common/slp_spi.h 2006-11-16 16:19:30.000000000 +0000 +@@ -172,7 +172,13 @@ int SLPSpiCanSign(SLPSpiHandle hspi, + /* Returns Non-zero if we sign using the specified SPI */ + /*=========================================================================*/ + +-#endif ++/*=========================================================================*/ ++void SLPSpiFill(SLPSpiHandle hspi); ++/* Fill up all entries with private/public keys. */ ++/* */ ++/* Parameters: hspi (IN) handle obtained from call to SLPSpiOpen() */ ++/*=========================================================================*/ + ++#endif + + +--- ./common/slp_xcast.c.orig 2003-04-04 06:52:07.000000000 +0000 ++++ ./common/slp_xcast.c 2006-11-16 16:19:30.000000000 +0000 +@@ -72,6 +72,7 @@ + + #include "slp_xcast.h" + #include "slp_message.h" ++#include "slp_property.h" + + /*========================================================================*/ + int SLPBroadcastSend(const SLPIfaceInfo* ifaceinfo, +@@ -172,12 +173,15 @@ int SLPMulticastSend(const SLPIfaceInfo* + int flags = 0; + int xferbytes; + struct in_addr saddr; ++ int optarg; + + + #if defined(MSG_NOSIGNAL) + flags = MSG_NOSIGNAL; + #endif + ++ optarg = atoi(SLPPropertyGet("net.slp.multicastTTL")); ++ + for (socks->sock_count = 0; + socks->sock_count < ifaceinfo->iface_count; + socks->sock_count++) +@@ -199,6 +203,14 @@ int SLPMulticastSend(const SLPIfaceInfo* + /* error setting socket option */ + return -1; + } ++ if(setsockopt(socks->sock[socks->sock_count], ++ IPPROTO_IP, ++ IP_MULTICAST_TTL, ++ &optarg, ++ sizeof(optarg))) ++ { ++ return -1; ++ } + + socks->peeraddr[socks->sock_count].sin_family = AF_INET; + socks->peeraddr[socks->sock_count].sin_port = htons(SLP_RESERVED_PORT); +--- ./libslp/Makefile.am.orig 2001-07-11 21:03:59.000000000 +0000 ++++ ./libslp/Makefile.am 2006-11-16 16:19:30.000000000 +0000 +@@ -23,6 +23,7 @@ libslp_la_SOURCES = libslp_dereg.c \ + libslp_delattrs.c \ + libslp_findsrvtypes.c \ + libslp_knownda.c \ ++ libslp_mdns.c \ + libslp.h + libslp_la_LIBADD = ../common/libcommonlibslp.la + libslp_la_LDFLAGS = -version-info 1:0:0 +--- ./libslp/libslp_findsrvs.c.orig 2003-04-04 06:52:08.000000000 +0000 ++++ ./libslp/libslp_findsrvs.c 2006-11-16 16:29:43.000000000 +0000 +@@ -54,7 +54,8 @@ SLPBoolean ColateSLPSrvURLCallback(SLPHa + const char* pcSrvURL, + unsigned short sLifetime, + SLPError errCode, +- void *pvCookie) ++ void *pvCookie, ++ struct sockaddr_in *peerinfo) + /*-------------------------------------------------------------------------*/ + { + SLPSrvUrlColatedItem* collateditem; +@@ -107,12 +108,13 @@ SLPBoolean ColateSLPSrvURLCallback(SLPHa + if(collateditem == NULL) + { + collateditem = (SLPSrvUrlColatedItem*) xmalloc(sizeof(SLPSrvUrlColatedItem) + \ +- strlen(pcSrvURL) + 1); ++ strlen(pcSrvURL) + 1 + sizeof(*peerinfo)); + if(collateditem) + { + memset(collateditem,0,sizeof(SLPSrvUrlColatedItem)); + collateditem->srvurl = (char*)(collateditem + 1); + strcpy(collateditem->srvurl,pcSrvURL); ++ memcpy(collateditem->srvurl + strlen(pcSrvURL) + 1, (char *)peerinfo, sizeof(*peerinfo)); + collateditem->lifetime = sLifetime; + + /* Add the new item to the collated list */ +@@ -146,6 +148,38 @@ CLEANUP: + return SLP_FALSE; + } + ++char * SLPAPI SLPGetPeer(SLPHandle hSLP, const char *pcURL) ++{ ++ PSLPHandleInfo handle; ++ SLPSrvUrlColatedItem* collateditem; ++ struct sockaddr_in peer; ++ ++ /*------------------------------*/ ++ /* check for invalid parameters */ ++ /*------------------------------*/ ++ if(hSLP == 0 || *(unsigned int*)hSLP != SLP_HANDLE_SIG || pcURL == 0 || pcURL[0] == 0) ++ { ++ return 0; ++ } ++ ++ /*-----------------------------------------*/ ++ /* cast the SLPHandle into a SLPHandleInfo */ ++ /*-----------------------------------------*/ ++ handle = (PSLPHandleInfo)hSLP; ++ ++ collateditem = (SLPSrvUrlColatedItem*) handle->collatedsrvurls.head; ++ while(collateditem) ++ { ++ if (strcmp(collateditem->srvurl, pcURL) == 0) ++ { ++ memcpy((char *)&peer, collateditem->srvurl + strlen(collateditem->srvurl) + 1, sizeof(peer)); ++ return xstrdup(inet_ntoa(peer.sin_addr)); ++ } ++ collateditem = (SLPSrvUrlColatedItem*)collateditem->listitem.next; ++ } ++ return 0; ++} ++ + /*-------------------------------------------------------------------------*/ + SLPBoolean ProcessSrvRplyCallback(SLPError errorcode, + struct sockaddr_in* peerinfo, +@@ -173,7 +207,8 @@ SLPBoolean ProcessSrvRplyCallback(SLPErr + 0, + 0, + errorcode, +- handle->params.findsrvs.cookie); ++ handle->params.findsrvs.cookie, ++ peerinfo); + } + + /*--------------------*/ +@@ -215,7 +250,8 @@ SLPBoolean ProcessSrvRplyCallback(SLPErr + urlentry[i].url, + (unsigned short)urlentry[i].lifetime, + SLP_OK, +- handle->params.findsrvs.cookie); ++ handle->params.findsrvs.cookie, ++ peerinfo); + if(result == SLP_FALSE) + { + break; +@@ -242,7 +278,8 @@ SLPBoolean ProcessSrvRplyCallback(SLPErr + replymsg->body.daadvert.url, + SLP_LIFETIME_MAXIMUM, + SLP_OK, +- handle->params.findsrvs.cookie); ++ handle->params.findsrvs.cookie, ++ peerinfo); + } + else if(replymsg->header.functionid == SLP_FUNCT_SAADVERT) + { +@@ -264,7 +301,8 @@ SLPBoolean ProcessSrvRplyCallback(SLPErr + replymsg->body.saadvert.url, + SLP_LIFETIME_MAXIMUM, + SLP_OK, +- handle->params.findsrvs.cookie); ++ handle->params.findsrvs.cookie, ++ peerinfo); + + } + } +--- ./libslp/libslp_mdns.c.orig 2006-11-16 16:19:30.000000000 +0000 ++++ ./libslp/libslp_mdns.c 2006-11-16 16:19:30.000000000 +0000 +@@ -0,0 +1,915 @@ ++#ifdef _WIN32 ++#define WIN32_LEAN_AND_MEAN ++#include ++#include ++#include ++#define ETIMEDOUT 110 ++#define ENOTCONN 107 ++#else ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#endif ++#include ++ ++#ifndef UNICAST_NOT_SUPPORTED ++#include "../libslp/slp.h" ++#endif ++ ++#include "slp_compare.h" ++#include "slp_xcast.h" ++#include "slp_message.h" ++#include "libslp_mdns.h" ++ ++ ++/*========================================================================*/ ++SLPBuffer SLPBufToMDNS(char* buf, int bufsize, int buftype) ++/* Description: ++ * Convert the data part of a SLP request to a MDNS request ++ *========================================================================*/ ++{ ++ char *srvtype; ++ int srvtypelen; ++ char *scopelist; ++ int scopelistlen; ++ unsigned char *bp, *end; ++ SLPBuffer mdnsbuf; ++ unsigned char txtbuf[512]; ++ int txtlen; ++ char *na; ++ int nalen; ++ char *pred; ++ int predlen; ++ char *slpurl; ++ int slpurllen; ++ char *taglist; ++ int taglistlen; ++ ++ bp = (unsigned char *)buf; ++ txtlen = 0; ++ ++ if (buftype == SLP_FUNCT_SRVTYPERQST) ++ { ++ nalen = AsUINT16(bp); ++ bp += 2; ++ na = bp; ++ if (nalen != 65535) ++ bp += nalen; ++ scopelistlen = AsUINT16(bp); ++ scopelist = bp + 2; ++ if (!SLPContainsStringList(scopelistlen, scopelist, 5, "_mdns")) ++ return 0; ++ bp += 2 + scopelistlen; ++ if (!(mdnsbuf = SLPBufferAlloc(8000))) ++ return 0; ++ bp = mdnsbuf->start; ++ bp[0] = bp[1] = 0; /* ID */ ++ bp[2] = 0x01; /* normal query */ ++ bp[3] = 0x00; ++ bp[4] = 0x00; /* qcount = 1 */ ++ bp[5] = 0x01; ++ bp[6] = bp[7] = 0; /* acount = 0 */ ++ bp[8] = bp[9] = 0; /* ncount = 0 */ ++ bp[10] = bp[11] = 0; /* xcount = 0 */ ++ memcpy(bp + 12, "\011_services\007_dns-sd\004_udp\005local\000", 30); ++ bp += 12 + 30; ++ bp[0] = 0; ++ bp[1] = DNS_TYPE_PTR; ++ bp[2] = 0; ++ bp[3] = DNS_CLASS_IN; ++ mdnsbuf->end = bp + 4; ++ if (nalen != 65535) ++ SLPMDNSAddTxt(txtbuf, sizeof(txtbuf), &txtlen, "namingauth=", na, nalen); ++ } ++ else if (buftype == SLP_FUNCT_SRVRQST) ++ { ++ srvtypelen = AsUINT16(bp); ++ srvtype = bp + 2; ++ bp += 2 + srvtypelen; ++ scopelistlen = AsUINT16(bp); ++ scopelist = bp + 2; ++ bp += 2 + scopelistlen; ++ if (!SLPContainsStringList(scopelistlen, scopelist, 5, "_mdns")) ++ return 0; ++ predlen = AsUINT16(bp); ++ pred = bp + 2; ++ bp += 2 + predlen; ++ if (bp[0] || bp[1]) /* slpspilen */ ++ return 0; ++ mdnsbuf = SLPBufferAlloc(8000); ++ if (!mdnsbuf) ++ return 0; ++ bp = mdnsbuf->start; ++ bp[0] = bp[1] = 0; /* ID */ ++ bp[2] = 0x01; ++ bp[3] = 0x00; ++ bp[4] = 0x00; ++ bp[5] = 0x01; ++ bp[6] = bp[7] = 0; ++ bp[8] = bp[9] = 0; ++ bp[10] = bp[11] = 0; ++ end = mdnsbuf->start + mdnsbuf->allocated; ++ if (!(bp = SLPMDNSSrvtypeToN(bp + 12, end, srvtype, srvtypelen)) || bp + 4 > end) ++ { ++ SLPBufferFree(mdnsbuf); ++ return 0; ++ } ++ bp[0] = 0; ++ bp[1] = DNS_TYPE_PTR; ++ bp[2] = 0; ++ bp[3] = DNS_CLASS_IN; ++ mdnsbuf->end = bp + 4; ++ SLPMDNSAddTxt(txtbuf, sizeof(txtbuf), &txtlen, "scope=", scopelist, scopelistlen); ++ if (predlen) ++ SLPMDNSAddTxt(txtbuf, sizeof(txtbuf), &txtlen, "predicate=", pred, predlen); ++ } ++ else if (buftype == SLP_FUNCT_ATTRRQST) ++ { ++ slpurllen = AsUINT16(bp); ++ slpurl = bp + 2; ++ bp += 2 + slpurllen; ++ srvtype = slpurl; ++ for (srvtypelen = 0; srvtypelen < slpurllen; srvtypelen++) ++ if (srvtypelen > 2 && slpurl[srvtypelen] == '/' && slpurl[srvtypelen - 1] == '/' && slpurl[srvtypelen - 2] == ':') ++ break; ++ if (srvtypelen != slpurllen) ++ srvtypelen -= 2; ++ else ++ slpurllen = 0; ++ if (srvtypelen <= 0) ++ return 0; ++ scopelistlen = AsUINT16(bp); ++ scopelist = bp + 2; ++ bp += 2 + scopelistlen; ++ if (!SLPContainsStringList(scopelistlen, scopelist, 5, "_mdns")) ++ return 0; ++ taglistlen = AsUINT16(bp); ++ taglist = bp + 2; ++ bp += 2 + taglistlen; ++ if (bp[0] || bp[1]) /* slpspilen */ ++ return 0; ++ mdnsbuf = SLPBufferAlloc(8000); ++ if (!mdnsbuf) ++ return 0; ++ bp = mdnsbuf->start; ++ bp[0] = bp[1] = 0; /* ID */ ++ bp[2] = 0x01; ++ bp[3] = 0x00; ++ bp[4] = 0x00; ++ bp[5] = 0x01; ++ bp[6] = bp[7] = 0; ++ bp[8] = bp[9] = 0; ++ bp[10] = bp[11] = 0; ++ end = mdnsbuf->start + mdnsbuf->allocated; ++ if (!(bp = SLPMDNSSrvtypeToN(bp + 12, end, srvtype, srvtypelen)) || bp + 4 > end) ++ { ++ SLPBufferFree(mdnsbuf); ++ return 0; ++ } ++ bp[0] = 0; ++ bp[1] = DNS_TYPE_PTR; ++ bp[2] = 0; ++ bp[3] = DNS_CLASS_IN; ++ mdnsbuf->end = bp + 4; ++ if (slpurllen) ++ SLPMDNSAddTxt(txtbuf, sizeof(txtbuf), &txtlen, "slpurl=", slpurl, slpurllen); ++ if (taglistlen) ++ SLPMDNSAddTxt(txtbuf, sizeof(txtbuf), &txtlen, "taglist=", taglist, taglistlen); ++ } ++ else ++ { ++ return 0; ++ } ++ if (txtlen) ++ { ++ /* small hack: we patch in the compression vector afterwards */ ++ bp = SLPMDNSAddRR(mdnsbuf->end, mdnsbuf->start, mdnsbuf->start + mdnsbuf->allocated, "\012_slpqueryX\000", 0, DNS_TYPE_TXT, 0, 0, 0, txtlen, txtbuf, 0); ++ if (bp) ++ { ++ /* set compression pointer to query */ ++ mdnsbuf->end[0] = 9; ++ mdnsbuf->end[10] = 0xc0; ++ mdnsbuf->end[11] = 12; ++ mdnsbuf->end = bp; ++ mdnsbuf->start[7]++; /* increment acount */ ++ } ++ } ++#ifdef DEBUG ++ SLPMDNSDumpDNS(mdnsbuf, "-> srvtype"); ++#endif ++ return mdnsbuf; ++} ++ ++static int SLPMDNSCmpRRData(unsigned char *a, unsigned char *ra, unsigned char *b, unsigned char *rb) ++{ ++ int type = AsUINT16(a); ++ if (memcmp(a, b, 4)) ++ return 1; ++ if (type == DNS_TYPE_PTR) ++ return SLPMDNSCmpN(a + 10, ra, b + 10, rb); ++ if (type == DNS_TYPE_SRV) ++ { ++ if (memcmp(a + 10, b + 10, 6)) ++ return 1; ++ return SLPMDNSCmpN(a + 16, ra, b + 16, rb); ++ } ++ return memcmp(a + 8, b + 8, 2 + AsUINT16(a + 8)); ++} ++ ++int SLPMDNSNToAttrs(unsigned char *txtbuf, int txtlen, char *buf, int len) ++{ ++ char *bp = buf; ++ int i, l; ++ int comma = 0; ++ ++ while (txtlen) ++ { ++ l = *txtbuf++; ++ txtlen--; ++ if (l > txtlen) ++ return 0; ++ for (i = 0; i < l; i++) ++ if (txtbuf[i] == '=') ++ break; ++ if (comma) ++ { ++ if (len == 0) ++ return 0; ++ *bp++ = ','; ++ len--; ++ } ++ comma = 1; ++ if (i == l) ++ { ++ /* keyword */ ++ if (l > len) ++ return 0; ++ memcpy(bp, txtbuf, l); ++ bp += l; ++ len -= l; ++ } ++ else ++ { ++ if (l + 2 > len) ++ return 0; ++ /* (keyword=values) */ ++ *bp++ = '('; ++ memcpy(bp, txtbuf, l); ++ bp += l; ++ *bp++ = ')'; ++ len -= l + 2; ++ } ++ txtbuf += l; ++ txtlen -= l; ++ } ++ return bp - buf; ++} ++ ++ ++/*========================================================================*/ ++int SLPMDNSToBuf(SLPBuffer buf, struct sockaddr *peer, int peerlen, SLPBuffer mdnssendbuf, int buftype, PSLPHandleInfo handle) ++/* Description: ++ * Convert the an MDNS answer to a SLP answer ++ *========================================================================*/ ++{ ++ int qcount, acount, ncount, xcount; ++ unsigned char *end = buf->end; ++ unsigned char *bp, *obp; ++ unsigned char slpbuf[8000], *slpbufend; ++ unsigned char *an[SLP_MDNS_MAX_RR]; ++ unsigned char *ad[SLP_MDNS_MAX_RR]; ++ unsigned char *xn[SLP_MDNS_MAX_RR]; ++ unsigned char *xd[SLP_MDNS_MAX_RR]; ++ int ac, xc, i, j, rac, l, type; ++ int jsrv, ja, jtxt; ++ unsigned char *cvec[256]; ++ unsigned char *ran[SLP_MDNS_MAX_RR]; ++ unsigned char *rad[SLP_MDNS_MAX_RR]; ++ int ncvec; ++ unsigned char *slpurl; ++ unsigned int ttl; ++ unsigned char *name; ++ int namelen; ++ int urllen; ++ ++ if (end - buf->start < 12) ++ return 1; /* too small */ ++#ifdef DEBUG ++ SLPMDNSDumpDNS(buf, "<-"); ++#endif ++ if (buf->start[0] != mdnssendbuf->start[0]) ++ return 1; /* XID mismatch */ ++ if (buf->start[1] != mdnssendbuf->start[1]) ++ return 1; /* XID mismatch */ ++ if ((buf->start[2] & 0xf0) != 0x80) ++ return 1; /* no standard response */ ++ if ((buf->start[3] & 0x0f) != 0x00) ++ return 1; /* DNS error */ ++ qcount = AsUINT16(buf->start + 4); ++ if (qcount > 1) ++ return 1; /* we didn't query this */ ++ ++ slpbuf[0] = 2; ++ if (buftype == SLP_FUNCT_SRVTYPERQST) ++ slpbuf[1] = SLP_FUNCT_SRVTYPERPLY; ++ else if (buftype == SLP_FUNCT_SRVRQST) ++ slpbuf[1] = SLP_FUNCT_SRVRPLY; ++ else if (buftype == SLP_FUNCT_ATTRRQST) ++ slpbuf[1] = SLP_FUNCT_ATTRRPLY; ++ else ++ return 1; /* internal error */ ++ slpbuf[2] = slpbuf[3] = slpbuf[4] = 0; /* length */ ++ slpbuf[5] = slpbuf[6] = 0; /* flags */ ++ slpbuf[7] = slpbuf[8] = slpbuf[9] = 0; /* ext off */ ++ slpbuf[10] = mdnssendbuf->start[0]; /* xid */ ++ slpbuf[11] = mdnssendbuf->start[1]; /* xid */ ++ slpbuf[12] = slpbuf[13] = 0; /* ltaglen */ ++ slpbuf[14] = slpbuf[15] = 0; /* error code */ ++ slpbuf[16] = slpbuf[17] = 0; /* url count */ ++ slpurl = slpbuf + 18; ++ ++ acount = AsUINT16(buf->start + 6); ++ ncount = AsUINT16(buf->start + 8); ++ xcount = AsUINT16(buf->start + 10); ++ ++ /* set up compression vector from old query */ ++ cvec[0] = bp = mdnssendbuf->start + 12; ++ ncvec = 1; ++ while (bp < end && *bp) ++ bp += *bp + 1; ++ bp += 1 + 4; ++ bp = SLPMDNSParseRR(bp, mdnssendbuf->end, AsUINT16(mdnssendbuf->start + 6), ran, rad, &rac); ++ for (i = 0; i < rac; i++) ++ { ++ if ((ran[i][0] & 0xc0) == 0xc0 && ncvec < 256) ++ cvec[ncvec++] = ran[i]; ++ if (AsUINT16(rad[i]) == DNS_TYPE_PTR) ++ { ++ if ((rad[i][10] & 0xc0) == 0xc0 && ncvec < 256) ++ cvec[ncvec++] = rad[i] + 10; ++ } ++ } ++ ++ bp = buf->start + 12; ++ /* skip query section */ ++ if (qcount) ++ { ++ while (bp < end && *bp && (*bp & 0xc0) != 0xc0) ++ bp += *bp + 1; ++ if (bp < end && *bp) ++ bp++; ++ bp += 5; ++ } ++ bp = SLPMDNSParseRR(bp, end, acount, an, ad, &ac); ++ if (bp > end) ++ return 1; ++ bp = SLPMDNSParseRR(bp, end, ncount, 0, 0, 0); ++ bp = SLPMDNSParseRR(bp, end, xcount, xn, xd, &xc); ++ ++ /* now that we know the end of the packet validate rrs */ ++ SLPMDNSCheckRR(buf->start, bp > end ? end : bp, an, ad, &ac); ++ SLPMDNSCheckRR(buf->start, bp > end ? end : bp, xn, xd, &xc); ++ /* printf("checked rrs: ac=%d, xc=%d\n", ac, xc); */ ++ ++ /* add answer rrs to our query if not already there */ ++ for (i = 0; i < ac; i++) ++ { ++ /* is this an answer we are looking for? */ ++ if (SLPMDNSCmpN(an[i], buf->start, ++ mdnssendbuf->start + 12, mdnssendbuf->start)) ++ continue; ++ type = AsUINT16(ad[i]); ++ /* skip everything but PTR RR, CLASS INs */ ++ if (type != DNS_TYPE_PTR) ++ continue; ++ if (AsUINT16(ad[i] + 2) != DNS_CLASS_IN) ++ continue; ++ ++ for (j = 0; j < rac; j++) ++ if (!SLPMDNSCmpRRData(ad[i], buf->start, rad[j], mdnssendbuf->start)) ++ break; ++ if (j < rac) ++ continue; ++ /* new rr, add it to query */ ++ if (rac < SLP_MDNS_MAX_RR) ++ { ++ bp = mdnssendbuf->end; ++ ran[rac] = bp; ++ bp = SLPMDNSAddRR(bp, mdnssendbuf->start, mdnssendbuf->start + mdnssendbuf->allocated, an[i], buf->start, type, AsUINT32(ad[i] + 4), cvec, &ncvec, 0, ad[i] + 10, rad + rac); ++ if (bp) ++ { ++ mdnssendbuf->end = bp; ++ j = AsUINT16(mdnssendbuf->start + 6); ++ ToUINT16(mdnssendbuf->start + 6, j + 1); ++ rac++; ++ } ++ } ++#ifdef DEBUG ++ SLPMDNSDumpDNS(mdnssendbuf, "updated sendbuf"); ++#endif ++ ++ slpbufend = slpbuf + sizeof(slpbuf); ++ if (buftype == SLP_FUNCT_SRVTYPERQST) ++ { ++ int comma = slpbuf[16] || slpbuf[17] ? 1 : 0; ++ l = SLPMDNSNToSrvtype(ad[i] + 10, buf->start, slpurl + comma, slpbufend - (slpurl + comma)); ++ if (!l) ++ continue; ++ if (comma) ++ *slpurl++ = ','; ++ slpurl += l; ++ ToUINT16(slpbuf + 16, slpurl - (slpbuf + 18)); ++ continue; ++ } ++ if (buftype == SLP_FUNCT_ATTRRQST) ++ { ++ unsigned char *txtbuf; ++ int txtlen; ++ ++ int comma = slpbuf[16] || slpbuf[17] ? 1 : 0; ++ /* find TXT record in additional section */ ++ for (jtxt = 0; jtxt < xcount; jtxt++) ++ if (AsUINT16(xd[jtxt]) == DNS_TYPE_TXT ++ && !SLPMDNSCmpN(ad[i] + 10, buf->start, xn[jtxt], buf->start)) ++ break; ++ if (jtxt == xcount) ++ continue; /* oops, no TXT */ ++ txtbuf = xd[jtxt] + 10; ++ txtlen = AsUINT16(xd[jtxt] + 8); ++ /* skip internal slpurl attribute */ ++ if (txtlen > 7 && *txtbuf > 7 && *txtbuf + 1 <= txtlen && !strncasecmp(txtbuf + 1, "slpurl=", 7)) { ++ txtlen -= *txtbuf + 1; ++ txtbuf += *txtbuf + 1; ++ } ++ /* extra +1 for # of AttrAuths added later */ ++ l = SLPMDNSNToAttrs(txtbuf, txtlen, slpurl + comma, slpbufend - (slpurl + comma + 1)); ++ if (!l) ++ continue; ++ if (comma) ++ *slpurl++ = ','; ++ slpurl += l; ++ ToUINT16(slpbuf + 16, slpurl - (slpbuf + 18)); ++ continue; ++ } ++ ++ /* now create a nice url */ ++ /* find SRV record in the additional section */ ++ for (jsrv = 0; jsrv < xcount; jsrv++) ++ if (AsUINT16(xd[jsrv]) == DNS_TYPE_SRV ++ && !SLPMDNSCmpN(ad[i] + 10, buf->start, xn[jsrv], buf->start)) ++ break; ++ if (jsrv == xcount) ++ continue; /* oops, server didn't send SRV RR */ ++ for (ja = 0; ja < xcount; ja++) ++ if (AsUINT16(xd[ja]) == DNS_TYPE_A ++ && !SLPMDNSCmpN(xd[jsrv] + 10 + 6, buf->start, xn[ja], buf->start)) ++ break; ++ if (ja == xcount) ++ ja = -1; ++ for (jtxt = 0; jtxt < xcount; jtxt++) ++ if (AsUINT16(xd[jtxt]) == DNS_TYPE_TXT ++ && !SLPMDNSCmpN(ad[i] + 10, buf->start, xn[jtxt], buf->start)) ++ break; ++ if (jtxt == xcount) ++ jtxt = -1; ++ ++ /* calculate slp TTL */ ++ ttl = AsUINT32(xd[jsrv] + 4); ++ if (ttl > 65535) ++ ttl = 65535; ++ ++ /* check if we hava an "slpurl" attribute in the TXT entry */ ++ if (jtxt >= 0) ++ { ++ char *txt; ++ l = 0; ++ txt = SLPMDNSFindInTxt(xd[jtxt] + 10, AsUINT16(xd[jtxt] + 8), "slpurl=", &l); ++ if (txt && l) ++ { ++ /* found it, great! add the slpurl */ ++ if (slpurl + 6 + l >= slpbufend) ++ continue; ++ *slpurl = 0; /* reserved */ ++ ToUINT16(slpurl + 1, ttl); ++ ToUINT16(slpurl + 3, l); ++ memcpy(slpurl + 5, txt, l); ++ slpurl[5 + l] = 0; /* url auths */ ++ slpurl += 6 + l; ++ if (++slpbuf[17] == 0) ++ slpbuf[16]++; ++ continue; ++ } ++ } ++ ++ bp = mdnssendbuf->start + 12; /* equal to an[i], not compr. */ ++ l = *bp++; ++ if (*bp == '_') ++ { ++ l--; ++ bp++; ++ } ++ if (l == 0 || l >= 64 || slpurl + 16 + l >= slpbufend) ++ continue; ++ memcpy(slpurl, "\0\0\0\0\0service:", 13); ++ ToUINT16(slpurl + 1, ttl); ++ memcpy(slpurl + 13, bp, l); ++ bp = slpurl + 13; ++ /* convert : to . */ ++ for (; *bp && l-- > 0; bp++) ++ if (*bp == ':') ++ *bp = '.'; ++ *bp++ = ':'; ++ *bp++ = '/'; ++ *bp++ = '/'; ++ obp = bp; ++ bp = SLPMDNSNToStr(bp, slpbufend - 1 - 8, xd[jsrv] + 10 + 6, buf->start, 1); ++ if (bp == 0) ++ continue; ++ if (ja >= 0 && (xd[ja][10] != 169 || xd[ja][11] != 254) && bp - obp > 6 && !strncmp(bp - 6, ".local", 6)) ++ { ++ /* got .local address but ip isn't local. Lookup. */ ++ struct sockaddr_in sai; ++ sai.sin_family = AF_INET; ++ memcpy(&sai.sin_addr.s_addr, xd[ja] + 10, 4); ++ if (getnameinfo((struct sockaddr *)&sai, sizeof(sai), ++ obp, slpbufend - 1 - 8 - obp, ++ (char *)0, 0, NI_NAMEREQD) == 0 ++ && obp + strlen(obp) < slpbufend - 1 - 9) ++ { ++ bp = obp + strlen(obp); ++ } ++ else ++ { ++ /* recreate old content */ ++ bp = SLPMDNSNToStr(obp, slpbufend - 1 - 8, xd[jsrv] + 10 + 6, buf->start, 1); ++ } ++ } ++ sprintf(bp, ":%u", AsUINT16(xd[jsrv] + 14)); ++ bp += strlen(bp); ++ urllen = bp - (slpurl + 5); ++ ToUINT16(slpurl + 3, urllen); ++ *bp++ = 0; /* 0 url blocks */ ++ ++ /* add extra name info */ ++ name = ad[i] + 10; ++ if ((*name & 0xc0) == 0xc0) ++ name = buf->start + ((*name & 0x3f) << 8 | name[1]); ++ namelen = *name++; ++ if (namelen && urllen && buftype == SLP_FUNCT_SRVRQST) ++ { ++ SLPSrvUrlColatedItem *collateditem; ++ collateditem = (SLPSrvUrlColatedItem*) xmalloc(sizeof(SLPSrvUrlColatedItem) + 3 + urllen + namelen); ++ if (collateditem) ++ { ++ memset(collateditem,0,sizeof(SLPSrvUrlColatedItem)); ++ collateditem->srvurl = (char*)(collateditem + 1); ++ collateditem->srvurl[0] = 0; ++ strcpy(collateditem->srvurl + 1, slpurl + 5); ++ memcpy(collateditem->srvurl + 1 + urllen + 1, name, namelen); ++ collateditem->srvurl[2 + urllen + namelen] = 0; ++ SLPListLinkTail(&(handle->collatedsrvurls), (SLPListItem*)collateditem); ++ } ++ } ++ ++ /* sucessfully added url */ ++ slpurl = bp; ++ if (++slpbuf[17] == 0) ++ slpbuf[16]++; ++ } ++ if ((!slpbuf[16] && !slpbuf[17]) || slpurl - slpbuf > buf->allocated) ++ return 1; ++ if (buftype == SLP_FUNCT_ATTRRQST) ++ { ++ /* we already know there is room for this byte */ ++ *slpurl++ = 0; ++ } ++ ToUINT24(slpbuf + 2, slpurl - slpbuf); ++ memcpy(buf->start, slpbuf, slpurl - slpbuf); ++#ifdef DEBUG ++ printf("SLP buffer\n"); ++ SLPMDNSDumpBuf(slpbuf, slpurl - slpbuf); ++#endif ++ buf->end = buf->start + (slpurl - slpbuf); ++ buf->curpos = buf->start; ++ return 0; ++} ++ ++const char *SLPAPI SLPGetMDNSName(SLPHandle hSLP, const char *pcURL) ++{ ++ ++ PSLPHandleInfo handle; ++ SLPSrvUrlColatedItem* collateditem; ++ ++ /*------------------------------*/ ++ /* check for invalid parameters */ ++ /*------------------------------*/ ++ if(hSLP == 0 || *(unsigned int*)hSLP != SLP_HANDLE_SIG || pcURL == 0) ++ { ++ return 0; ++ } ++ ++ /*-----------------------------------------*/ ++ /* cast the SLPHandle into a SLPHandleInfo */ ++ /*-----------------------------------------*/ ++ handle = (PSLPHandleInfo)hSLP; ++ ++ collateditem = (SLPSrvUrlColatedItem*) handle->collatedsrvurls.head; ++ while(collateditem) ++ { ++ if (collateditem->srvurl[0] == 0 ++ && strcmp(collateditem->srvurl + 1,pcURL) == 0) ++ return collateditem->srvurl + strlen(collateditem->srvurl + 1) + 2; ++ collateditem = (SLPSrvUrlColatedItem*)collateditem->listitem.next; ++ } ++ return 0; ++} ++ ++ ++/*========================================================================*/ ++int SLPMDNSMulticastSend(const SLPIfaceInfo* ifaceinfo, ++ SLPBuffer msg, ++ SLPXcastSockets* socks) ++/* Description: ++ * Multicast a message. ++ * ++ * Parameters: ++ * ifaceinfo (IN) Pointer to the SLPIfaceInfo structure that contains ++ * information about the interfaces to send on ++ * msg (IN) Buffer to send ++ * ++ * socks (OUT) Sockets used to multicast. May be used to recv() ++ * responses. MUST be close by caller using ++ * SLPXcastSocketsClose() ++ * ++ * Returns: ++ * Zero on sucess. Non-zero with errno set on error ++ *========================================================================*/ ++{ ++ int flags = 0; ++ int on = 1; ++ int xferbytes; ++ struct in_addr saddr; ++ ++#if defined(MSG_NOSIGNAL) ++ flags = MSG_NOSIGNAL; ++#endif ++ ++ for (socks->sock_count = 0; ++ socks->sock_count < ifaceinfo->iface_count; ++ socks->sock_count++) ++ { ++ socks->sock[socks->sock_count] = socket(AF_INET, SOCK_DGRAM, 0); ++ if (socks->sock[socks->sock_count] < 0) ++ { ++ /* error creating socket */ ++ return -1; ++ } ++ if (setsockopt(socks->sock[socks->sock_count], ++ SOL_IP, ++ IP_RECVTTL, ++ &on, ++ sizeof(on))) { ++ /* error setting socket option */ ++ return -1; ++ } ++ ++ saddr.s_addr = ifaceinfo->iface_addr[socks->sock_count].sin_addr.s_addr; ++ if( setsockopt(socks->sock[socks->sock_count], ++ IPPROTO_IP, ++ IP_MULTICAST_IF, ++ (char*)&saddr, ++ sizeof(struct in_addr))) ++ { ++ /* error setting socket option */ ++ return -1; ++ } ++ ++ socks->peeraddr[socks->sock_count].sin_family = AF_INET; ++ socks->peeraddr[socks->sock_count].sin_port = htons(MDNS_RESERVED_PORT); ++ socks->peeraddr[socks->sock_count].sin_addr.s_addr = htonl(MDNS_MCAST_ADDRESS); ++ ++ xferbytes = sendto(socks->sock[socks->sock_count], ++ msg->start, ++ msg->end - msg->start, ++ flags, ++ (struct sockaddr *) &(socks->peeraddr[socks->sock_count]), ++ sizeof(struct sockaddr_in)); ++ if (xferbytes <= 0) ++ { ++ /* error sending */ ++ return -1; ++ } ++ } ++ return 0; ++} ++ ++ ++/*=========================================================================*/ ++int SLPMDNSXcastRecvMessage(const SLPXcastSockets* sockets, ++ const SLPXcastSockets* mdnssockets, ++ SLPBuffer *buf, ++ struct sockaddr_in* peeraddr, ++ struct timeval* timeout, ++ SLPBuffer mdnssendbuf, int buftype, ++ PSLPHandleInfo handle) ++/* Description: ++ * Receives datagram messages from one of the sockets in the specified   ++ * SLPXcastsSockets structure ++ * ++ * Parameters: ++ * sockets (IN) Pointer to the SOPXcastSockets structure that describes ++ * which sockets to read slp messages from. ++ * sockets (IN) Pointer to the SOPXcastSockets structure that describes ++ * which sockets to read mdns messages from. ++ * buf (OUT) Pointer to SLPBuffer that will contain the message upon ++ * successful return. ++ * peeraddr (OUT) Pointer to struc sockaddr_in that will contain the ++ * address of the peer that sent the received message. ++ * timeout (IN/OUT) pointer to the struct timeval that indicates how much ++ * time to wait for a message to arrive ++ * mdnssendbuf (IN/OUT) Pointer to SLPBuffer that contains the MDNS message. ++ * We will add our received RRs here (known answer ++ * suppression) ++ * ++ * Returns: ++ * Zero on success, non-zero with errno set on failure. ++ *========================================================================*/ ++{ ++ fd_set readfds; ++ int highfd; ++ int i; ++ int readable; ++ size_t bytesread; ++ int recvloop; ++ int peeraddrlen = sizeof(struct sockaddr_in); ++ char peek[16]; ++ int result = 0; ++ struct msghdr mhdr; ++ struct iovec iov; ++ unsigned char cmsgbuf[CMSG_SPACE(sizeof(int))]; ++ struct cmsghdr *cmsg; ++ int ttl; ++ ++ /* recv loop */ ++ recvloop = 1; ++ while(recvloop) ++ { ++ /* Set the readfds */ ++ FD_ZERO(&readfds); ++ highfd = 0; ++ for (i=0; isock_count; i++) ++ { ++ FD_SET(sockets->sock[i],&readfds); ++ if(sockets->sock[i] > highfd) ++ highfd = sockets->sock[i]; ++ } ++ for (i=0; isock_count; i++) ++ { ++ FD_SET(mdnssockets->sock[i],&readfds); ++ if(mdnssockets->sock[i] > highfd) ++ highfd = mdnssockets->sock[i]; ++ } ++ ++ /* Select */ ++ readable = select(highfd + 1,&readfds,NULL,NULL,timeout); ++ if(readable > 0) ++ { ++ /* Read the datagram */ ++ for (i=0; isock_count; i++) ++ { ++ if(FD_ISSET(sockets->sock[i],&readfds)) ++ { ++ /* Peek at the first 16 bytes of the header */ ++ bytesread = recvfrom(sockets->sock[i], ++ peek, ++ 16, ++ MSG_PEEK, ++ (struct sockaddr *)peeraddr, ++ &peeraddrlen); ++ if(bytesread == 16 ++#ifdef _WIN32 ++ /* Win32 returns WSAEMSGSIZE if the message is larger than ++ * the requested size, even with MSG_PEEK. But if this is the ++ * error code we can be sure that the message is at least 16 ++ * bytes */ ++ || (bytesread == (size_t)-1 && WSAGetLastError() == WSAEMSGSIZE) ++#endif ++ ) ++ { ++ if(AsUINT24(peek + 2) <= SLP_MAX_DATAGRAM_SIZE) ++ { ++ *buf = SLPBufferRealloc(*buf, AsUINT24(peek + 2)); ++ bytesread = recv(sockets->sock[i], ++ (*buf)->curpos, ++ (*buf)->end - (*buf)->curpos, ++ 0); ++ if(bytesread != AsUINT24(peek + 2)) ++ { ++ /* This should never happen but we'll be paranoid*/ ++ (*buf)->end = (*buf)->curpos + bytesread; ++ } ++ ++ /* Message read. We're done! */ ++ result = 0; ++ recvloop = 0; ++ break; ++ } ++ else ++ { ++ /* we got a bad message, or one that is too big! */ ++#ifndef UNICAST_NOT_SUPPORTED ++ /* Reading SLP_MAX_DATAGRAM_SIZE bytes on the socket */ ++ *buf = SLPBufferRealloc(*buf, SLP_MAX_DATAGRAM_SIZE); ++ bytesread = recv(sockets->sock[i], ++ (*buf)->curpos, ++ (*buf)->end - (*buf)->curpos, ++ 0); ++ if(bytesread != SLP_MAX_DATAGRAM_SIZE) ++ { ++ /* This should never happen but we'll be paranoid*/ ++ (*buf)->end = (*buf)->curpos + bytesread; ++ } ++ result = SLP_RETRY_UNICAST; ++ recvloop = 0; ++ return result; ++#endif ++ } ++ } ++ else ++ { ++ /* Not even 16 bytes available */ ++ } ++ } ++ } ++ for (i=0; isock_count; i++) ++ { ++ if(!FD_ISSET(mdnssockets->sock[i],&readfds)) ++ continue; ++ *buf = SLPBufferRealloc(*buf, 8000); ++ (*buf)->curpos = (*buf)->start; ++#if 1 ++ iov.iov_base = (*buf)->curpos; ++ iov.iov_len = (*buf)->end - (*buf)->curpos; ++ mhdr.msg_name = (struct sockaddr *)peeraddr; ++ mhdr.msg_namelen = peeraddrlen; ++ mhdr.msg_iov = &iov; ++ mhdr.msg_iovlen = 1; ++ mhdr.msg_control = cmsgbuf; ++ mhdr.msg_controllen = sizeof(cmsgbuf); ++ mhdr.msg_flags = 0; ++ bytesread = recvmsg(mdnssockets->sock[i], &mhdr, 0); ++ if (bytesread < 12) ++ continue; ++ cmsg = CMSG_FIRSTHDR(&mhdr); ++ for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; CMSG_NXTHDR(&mhdr, cmsg)) ++ if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) ++ break; ++ if (!cmsg) ++ continue; ++ ttl = *(int *)CMSG_DATA(cmsg); ++ if (ttl != 255) ++ { ++ continue; ++ } ++#else ++ bytesread = recvfrom(mdnssockets->sock[i], ++ (*buf)->curpos, ++ (*buf)->end - (*buf)->curpos, ++ 0, ++ (struct sockaddr *)peeraddr, ++ &peeraddrlen); ++ if (bytesread < 12) ++ continue; ++#endif ++ (*buf)->end = (*buf)->start + bytesread; ++ if (SLPMDNSToBuf(*buf, (struct sockaddr *)peeraddr, peeraddrlen, mdnssendbuf, buftype, handle) == 0) ++ { ++ result = 0; ++ recvloop = 0; ++ break; ++ } ++ } ++ } ++ else if(readable == 0) ++ { ++ result = -1; ++ errno = ETIMEDOUT; ++ recvloop = 0; ++ } ++ else ++ { ++ result = -1; ++ recvloop = 0; ++ } ++ } ++ ++ return result; ++} ++ +--- ./libslp/libslp_mdns.h.orig 2006-11-16 16:19:30.000000000 +0000 ++++ ./libslp/libslp_mdns.h 2006-11-16 16:19:30.000000000 +0000 +@@ -0,0 +1,14 @@ ++#include "slp_mdns.h" ++#include "libslp.h" ++ ++extern SLPBuffer SLPBufToMDNS(char* buf, int bufsize, int buftype); ++extern int SLPMDNSToBuf(SLPBuffer buf, struct sockaddr *peer, ++ int peerlen, SLPBuffer mdnssendbuf, int buftype, PSLPHandleInfo handle); ++extern int SLPMDNSMulticastSend(const SLPIfaceInfo* ifaceinfo, ++ SLPBuffer msg, SLPXcastSockets* socks); ++extern int SLPMDNSXcastRecvMessage(const SLPXcastSockets* sockets, ++ const SLPXcastSockets* mdnssockets, ++ SLPBuffer *buf, ++ struct sockaddr_in* peeraddr, ++ struct timeval* timeout, ++ SLPBuffer mdnssendbuf, int buftype, PSLPHandleInfo handle); +--- ./libslp/libslp_network.c.orig 2003-08-20 05:25:58.000000000 +0000 ++++ ./libslp/libslp_network.c 2006-11-16 16:19:30.000000000 +0000 +@@ -49,6 +49,7 @@ + + #include "slp.h" + #include "libslp.h" ++#include "libslp_mdns.h" + + + /*=========================================================================*/ +@@ -660,6 +661,15 @@ SLPError NetworkMcastRqstRply(const char + SLPIfaceInfo ifaceinfo; + SLPXcastSockets xcastsocks; + ++ int usemdns = 1; ++ int useslp = 1; ++ SLPBuffer mdnssendbuf = 0; ++ SLPXcastSockets mdnsxcastsocks; ++ ++ /* initialize sock_count so that CLEANUP won't get hurt */ ++ xcastsocks.sock_count = 0; ++ mdnsxcastsocks.sock_count = 0; ++ + #ifdef DEBUG + /* This function only supports multicast or broadcast of the following + * messages +@@ -726,6 +736,7 @@ SLPError NetworkMcastRqstRply(const char + /* SLP_FUNCT_DASRVRQST is a fake function. We really want to */ + /* send a SRVRQST */ + buftype = SLP_FUNCT_SRVRQST; ++ usemdns = 0; + } + + /*---------------------------------------------------------------------*/ +@@ -744,6 +755,13 @@ SLPError NetworkMcastRqstRply(const char + *prlist = 0; + prlistlen = 0; + ++ if (usemdns) ++ { ++ mdnssendbuf = SLPBufToMDNS(buf, bufsize, buftype); ++ if (!mdnssendbuf) ++ usemdns = 0; ++ } ++ + /*--------------------------*/ + /* Main retransmission loop */ + /*--------------------------*/ +@@ -831,14 +849,23 @@ SLPError NetworkMcastRqstRply(const char + /*----------------------*/ + /* send the send buffer */ + /*----------------------*/ +- if(usebroadcast) +- { +- result = SLPBroadcastSend(&ifaceinfo,sendbuf,&xcastsocks); +- } +- else +- { +- result = SLPMulticastSend(&ifaceinfo,sendbuf,&xcastsocks); +- } ++ result = 0; ++ if (useslp) ++ { ++ if(usebroadcast) ++ { ++ result = SLPBroadcastSend(&ifaceinfo,sendbuf,&xcastsocks); ++ } ++ else ++ { ++ result = SLPMulticastSend(&ifaceinfo,sendbuf,&xcastsocks); ++ } ++ } ++ if (result == 0 && usemdns) ++ { ++ ToUINT16(mdnssendbuf->start,xid); ++ result = SLPMDNSMulticastSend(&ifaceinfo,mdnssendbuf,&mdnsxcastsocks); ++ } + if(result != 0) + { + /* we could not send the message for some reason */ +@@ -851,20 +878,19 @@ SLPError NetworkMcastRqstRply(const char + /*----------------*/ + while(1) + { +- #ifndef UNICAST_NOT_SUPPORTED +- int retval = 0; +- if((retval = SLPXcastRecvMessage(&xcastsocks, +- &recvbuf, +- &peeraddr, +- &timeout)) != 0) +- #else +- +- if(SLPXcastRecvMessage(&xcastsocks, +- &recvbuf, +- &peeraddr, +- &timeout) != 0) +- #endif +- ++ int retval; ++ if (usemdns) ++ retval = SLPMDNSXcastRecvMessage(&xcastsocks, ++ &mdnsxcastsocks, ++ &recvbuf, ++ &peeraddr, ++ &timeout, mdnssendbuf, buftype, handle); ++ else ++ retval = SLPXcastRecvMessage(&xcastsocks, ++ &recvbuf, ++ &peeraddr, ++ &timeout); ++ if (retval != 0) + { + /* An error occured while receiving the message */ + /* probably a just time out error. break for re-send. */ +@@ -972,13 +998,16 @@ SLPError NetworkMcastRqstRply(const char + goto CLEANUP; + } + +- /* add the peer to the previous responder list */ +- if(prlistlen != 0) +- { +- strcat(prlist,","); +- } +- strcat(prlist,inet_ntoa(peeraddr.sin_addr)); +- prlistlen = strlen(prlist); ++ if (prlistlen + 14 < mtu) ++ { ++ /* add the peer to the previous responder list */ ++ if(prlistlen != 0) ++ { ++ strcat(prlist,","); ++ } ++ strcat(prlist,inet_ntoa(peeraddr.sin_addr)); ++ prlistlen = strlen(prlist); ++ } + } + } + +@@ -1016,8 +1045,11 @@ SLPError NetworkMcastRqstRply(const char + /*----------------*/ + if(prlist) xfree(prlist); + SLPBufferFree(sendbuf); ++ SLPBufferFree(mdnssendbuf); + SLPBufferFree(recvbuf); + SLPXcastSocketsClose(&xcastsocks); ++ if (usemdns) ++ SLPXcastSocketsClose(&mdnsxcastsocks); + + return result; + } +@@ -1190,6 +1222,7 @@ SLPError NetworkUcastRqstRply(PSLPHandle + /* send the send buffer */ + /*----------------------*/ + ++ peeraddr = handle->unicastaddr; + handle->unicastsock = SLPNetworkConnectStream(&(handle->unicastaddr), &timeout); + if ( handle->unicastsock >= 0 ) { + retval1 = SLPNetworkSendMessage(handle->unicastsock, SOCK_STREAM, sendbuf, &(handle->unicastaddr), &timeout); +--- ./libslp/slp.h.orig 2003-04-21 11:26:54.000000000 +0000 ++++ ./libslp/slp.h 2006-11-16 16:42:16.000000000 +0000 +@@ -981,6 +981,41 @@ SLPEXP SLPError SLPAPI SLPParseAttrs(con + /* was not found otherwise SLP_OK */ + /*=========================================================================*/ + ++ ++/*=========================================================================*/ ++SLPEXP const char* SLPAPI SLPGetMDNSName(SLPHandle hSLP, ++ const char *pcURL); ++/* */ ++/* Used to get the MDNS name corresponding to a service URL. This function */ ++/* may only be called from a SLPSrvURLCallback. */ ++/* */ ++/* hSLP The language specific SLPHandle on which to search for */ ++/* the MDNS name. */ ++/* */ ++/* pcURL (IN) The service URL. */ ++/* */ ++/* Returns: Returns NULL if no name is available for the URL, otherwise */ ++/* the name. Note that the memory belongs to libslp and must not */ ++/* be freed! */ ++/*=========================================================================*/ ++ ++ ++/*=========================================================================*/ ++SLPEXP char * SLPAPI SLPGetPeer(SLPHandle hSLP, ++ const char *pcURL); ++/* */ ++/* Used to get the peer info corresponding to a service URL. This function */ ++/* may only be called from a SLPSrvURLCallback. */ ++/* The memory should be freed by calling SLPFree(). */ ++/* */ ++/* hSLP The language specific SLPHandle on which to search for */ ++/* the MDNS name. */ ++/* */ ++/* pcURL (IN) The service URL. */ ++/* */ ++/* Returns: the ip address if the peer, NULL if not available */ ++/*=========================================================================*/ ++ + #if(defined __cplusplus) + } + #endif +--- ./libslpattr/libslpattr.c.orig 2002-11-23 03:44:53.000000000 +0000 ++++ ./libslpattr/libslpattr.c 2006-11-16 16:19:30.000000000 +0000 +@@ -360,6 +360,11 @@ int find_value_list_end(char const *valu + (*cur)++; + } + ++ if (type_guess == TYPE_UNKNOWN) ++ { ++ return 0; /* empty */ ++ } ++ + *type = type_guess; + return 1; + } +--- ./slpd/Makefile.am.orig 2002-03-19 23:52:15.000000000 +0000 ++++ ./slpd/Makefile.am 2006-11-16 16:19:30.000000000 +0000 +@@ -38,6 +38,7 @@ slpd_regfile.c \ + slpd_knownda.c \ + slpd_incoming.c \ + slpd_outgoing.c \ ++slpd_mdns.c \ + slpd.h \ + slpd_knownda.h \ + slpd_process.h \ +@@ -49,6 +50,7 @@ slpd_database.h \ + slpd_outgoing.h \ + slpd_regfile.h \ + slpd_incoming.h \ ++slpd_mdns.h \ + slpd_socket.h + + slpd_LDADD = ../common/libcommonslpd.la \ +--- ./slpd/slpd_database.c.orig 2003-03-19 05:03:21.000000000 +0000 ++++ ./slpd/slpd_database.c 2006-11-16 16:19:30.000000000 +0000 +@@ -69,6 +69,13 @@ + #include "slp_xmalloc.h" + #include "slp_pid.h" + ++extern char *reg_file_dir; ++FILE *regfileFP; ++ ++/*=========================================================================*/ ++/* standard header files */ ++/*=========================================================================*/ ++#include + + /*=========================================================================*/ + SLPDDatabase G_SlpdDatabase; +@@ -414,6 +421,8 @@ int SLPDDatabaseSrvRqstStart(SLPMessage + + /* entry reg is the SrvReg message from the database */ + entryreg = &(entry->msg->body.srvreg); ++ if ((entryreg->watchflags & SLP_REG_WATCH_DEAD) != 0) ++ continue; + + /* check the service type */ + if ( SLPCompareSrvType(srvrqst->srvtypelen, +@@ -548,6 +557,8 @@ int SLPDDatabaseSrvTypeRqstStart(SLPMess + + /* entry reg is the SrvReg message from the database */ + entryreg = &(entry->msg->body.srvreg); ++ if ((entryreg->watchflags & SLP_REG_WATCH_DEAD) != 0) ++ continue; + + if ( SLPCompareNamingAuth(entryreg->srvtypelen, + entryreg->srvtype, +@@ -658,6 +669,8 @@ int SLPDDatabaseAttrRqstStart(SLPMessage + + /* entry reg is the SrvReg message from the database */ + entryreg = &(entry->msg->body.srvreg); ++ if ((entryreg->watchflags & SLP_REG_WATCH_DEAD) != 0) ++ continue; + + + if ( SLPCompareString(attrrqst->urllen, +@@ -775,18 +788,19 @@ SLPMessage SLPDDatabaseEnum(void* eh, SL + /*=========================================================================*/ + { + SLPDatabaseEntry* entry; +- entry = SLPDatabaseEnum((SLPDatabaseHandle) eh); +- if ( entry ) ++ SLPSrvReg* entryreg; ++ ++ while ((entry = SLPDatabaseEnum((SLPDatabaseHandle) eh)) != 0) + { ++ entryreg = &(entry->msg->body.srvreg); ++ if ((entryreg->watchflags & SLP_REG_WATCH_DEAD) != 0) ++ continue; + *msg = entry->msg; + *buf = entry->buf; ++ return *msg; + } +- else +- { +- *msg = 0; +- *buf = 0; +- } +- ++ *msg = 0; ++ *buf = 0; + return *msg; + } + +@@ -840,12 +854,141 @@ int SLPDDatabaseInit(const char* regfile + SLPDatabaseInit(&G_SlpdDatabase.database); + + /* Call the reinit function */ +- return SLPDDatabaseReInit(regfile); ++ if (regfileFP) ++ { ++ fclose(regfileFP); ++ } ++ regfileFP = fopen(regfile, "r"); ++ return SLPDDatabaseReInit(); + } + ++/*=========================================================================*/ ++static void SLPDDatabaseWatcher_fd(int fd, int flag, unsigned char *porthash) ++{ ++ SLPDatabaseHandle dh; ++ SLPDatabaseEntry* entry; ++ SLPSrvReg* srvreg; ++ char buf[4096], *p[6]; ++ int l, o, i, j, k, c, n, port; ++ ++ if (fd < 0) ++ return; ++ lseek(fd, (off_t)0, SEEK_SET); ++ o = 0; ++ while ((l = read(fd, buf + o, sizeof(buf) - o)) > 0) { ++ l += o; ++ n = 0; ++ for (;;) { ++ for (i = n; i < l; i++) ++ if (buf[i] == '\n') ++ break; ++ if (i == l) { ++ if (l > n) ++ memmove(buf, buf + n, l - n); ++ o = l > n ? l - n : 0; ++ break; ++ } ++ k = 0; ++ for (j = n; j < i; j++) { ++ c = buf[j]; ++ if (!(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'F') && !(c >= 'a' && c <= 'f')) ++ buf[j] = 0; ++ else if ((j == n || buf[j - 1] == 0) && k < 6) ++ p[k++] = buf + j; ++ } ++ n = i + 1; ++ if (k < 6 || strlen(p[1]) < 8) ++ continue; ++ if (strlen(p[1]) == 8 && strtol(p[1], (char **)0, 16) == htonl(0x7f000001)) ++ continue; ++ if ((flag & SLP_REG_WATCH_TCP) != 0 && strtol(p[5], (char **)0, 16) != 10) ++ continue; ++ port = strtol(p[2], (char **)0, 16); ++ if (!(porthash[(port / 8) & 255] & (1 << (port & 7)))) ++ continue; ++ dh = SLPDatabaseOpen(&G_SlpdDatabase.database); ++ while ((entry = SLPDatabaseEnum(dh)) != 0) { ++ srvreg = &(entry->msg->body.srvreg); ++ if (!(srvreg->watchflags & flag)) ++ continue; ++ if (port == srvreg->watchport) ++ srvreg->watchflags &= ~SLP_REG_WATCH_CHECKING; ++ } ++ SLPDatabaseClose(dh); ++ } ++ } ++} + + /*=========================================================================*/ +-int SLPDDatabaseReInit(const char* regfile) ++void SLPDDatabaseWatcher(void) ++{ ++ static int initialized = 0; ++ static int proctcp, procudp, proctcp6, procudp6; ++ unsigned char porthash[256]; ++ int flags, port; ++ SLPDatabaseHandle dh; ++ SLPDatabaseEntry* entry; ++ SLPSrvReg* srvreg; ++ ++ if (!initialized) { ++ proctcp = open("/proc/net/tcp_listen", O_RDONLY); ++ if (proctcp == -1) ++ proctcp = open("/proc/net/tcp", O_RDONLY); ++ procudp = open("/proc/net/udp", O_RDONLY); ++ proctcp6 = open("/proc/net/tcp6_listen", O_RDONLY); ++ if (proctcp6 == -1) ++ proctcp6 = open("/proc/net/tcp6", O_RDONLY); ++ procudp6 = open("/proc/net/udp6", O_RDONLY); ++ initialized = 1; ++ } ++ flags = 0; ++ memset(porthash,0,sizeof(porthash)); ++ dh = SLPDatabaseOpen(&G_SlpdDatabase.database); ++ while ((entry = SLPDatabaseEnum(dh)) != 0) { ++ srvreg = &(entry->msg->body.srvreg); ++ if (!srvreg->watchflags) ++ continue; ++ flags |= srvreg->watchflags; ++ port = srvreg->watchport; ++ porthash[(port / 8) & 255] |= 1 << (port & 7); ++ srvreg->watchflags |= SLP_REG_WATCH_CHECKING; ++ } ++ SLPDatabaseClose(dh); ++ if ((flags & SLP_REG_WATCH_TCP) != 0) { ++ SLPDDatabaseWatcher_fd(proctcp, SLP_REG_WATCH_TCP, porthash); ++ SLPDDatabaseWatcher_fd(proctcp6, SLP_REG_WATCH_TCP, porthash); ++ } ++ if ((flags & SLP_REG_WATCH_UDP) != 0) { ++ SLPDDatabaseWatcher_fd(procudp, SLP_REG_WATCH_UDP, porthash); ++ SLPDDatabaseWatcher_fd(procudp6, SLP_REG_WATCH_UDP, porthash); ++ } ++ dh = SLPDatabaseOpen(&G_SlpdDatabase.database); ++ while ((entry = SLPDatabaseEnum(dh)) != 0) { ++ srvreg = &(entry->msg->body.srvreg); ++ if (!srvreg->watchflags) ++ continue; ++ switch (srvreg->watchflags & (SLP_REG_WATCH_CHECKING | SLP_REG_WATCH_DEAD)) { ++ case SLP_REG_WATCH_CHECKING: ++ srvreg->watchflags |= SLP_REG_WATCH_DEAD; ++ SLPDKnownDADeRegisterWithAllDas(entry->msg, entry->buf); ++ SLPDLogRegistration("port dead",entry); ++ break; ++ case SLP_REG_WATCH_DEAD: ++ srvreg->watchflags ^= SLP_REG_WATCH_DEAD; ++ SLPDKnownDARegisterWithAllDas(entry->msg, entry->buf); ++ SLPDLogRegistration("port living",entry); ++ break; ++ } ++ srvreg->watchflags &= ~SLP_REG_WATCH_CHECKING; ++ } ++ SLPDatabaseClose(dh); ++} ++ ++ ++ ++ ++/*=========================================================================*/ ++int SLPDDatabaseReInit() + /* Re-initialize the database with changed registrations from a regfile. */ + /* */ + /* regfile (IN) the regfile to register. */ +@@ -857,6 +1000,8 @@ int SLPDDatabaseReInit(const char* regfi + SLPDatabaseEntry* entry; + SLPMessage msg; + SLPBuffer buf; ++ struct dirent *direntry; ++ DIR *dirfp; + FILE* fd; + + /*------------------------------------------------------------------*/ +@@ -882,19 +1027,40 @@ int SLPDDatabaseReInit(const char* regfi + /*--------------------------------------*/ + /* Read static registration file if any */ + /*--------------------------------------*/ +- if ( regfile ) ++ if ( regfileFP ) + { +- fd = fopen(regfile,"rb"); +- if ( fd ) ++ rewind(regfileFP); ++ while ( SLPDRegFileReadSrvReg(regfileFP, &msg, &buf) == 0 ) + { +- while ( SLPDRegFileReadSrvReg(fd, &msg, &buf) == 0 ) +- { +- SLPDDatabaseReg(msg, buf); +- } ++ SLPDDatabaseReg(msg, buf); ++ } ++ } + +- fclose(fd); ++ /*------------------------------------------------------------------*/ ++ /* Read all static registration file, which comes with any package */ ++ /* SuSE ONLY */ ++ /*------------------------------------------------------------------*/ ++ dirfp = opendir(reg_file_dir); ++ while ( dirfp && (direntry = readdir(dirfp)) != 0) { ++ if ( direntry->d_name && direntry->d_name[0] != '.' ){ ++ char filename[1024]; ++ snprintf( filename, 1023, "%s/%s", reg_file_dir, direntry->d_name ); ++ ++ if ( strlen(filename)>4 && ++ strcmp(filename+strlen(filename)-4, ".reg") == 0 && ++ (fd=fopen(filename,"rb")) ) ++ { ++ while ( SLPDRegFileReadSrvReg(fd, &msg, &buf) == 0 ) ++ { ++ SLPDDatabaseReg(msg, buf); ++ } ++ ++ fclose(fd); ++ } + } +- } ++ } ++ if ( dirfp ) ++ closedir(dirfp); + + return 0; + } +--- ./slpd/slpd_database.h.orig 2001-05-10 15:04:19.000000000 +0000 ++++ ./slpd/slpd_database.h 2006-11-16 16:19:30.000000000 +0000 +@@ -266,7 +266,7 @@ int SLPDDatabaseIsEmpty(); + + + /*=========================================================================*/ +-int SLPDDatabaseInit(const char* regfile); ++int SLPDDatabaseInit(); + /* Initialize the database with registrations from a regfile. */ + /* */ + /* regfile (IN) the regfile to register. Pass in NULL for no regfile */ +@@ -276,7 +276,7 @@ int SLPDDatabaseInit(const char* regfile + + + /*=========================================================================*/ +-int SLPDDatabaseReInit(const char* regfile); ++int SLPDDatabaseReInit(); + /* Re-initialize the database with changed registrations from a regfile. */ + /* */ + /* regfile (IN) the regfile to register. */ +@@ -284,6 +284,8 @@ int SLPDDatabaseReInit(const char* regfi + /* Returns - zero on success or non-zero on error. */ + /*=========================================================================*/ + ++void SLPDDatabaseWatcher(void); ++ + #ifdef DEBUG + /*=========================================================================*/ + void SLPDDatabaseDeinit(void); +--- ./slpd/slpd_knownda.c.orig 2003-02-04 20:41:15.000000000 +0000 ++++ ./slpd/slpd_knownda.c 2006-11-16 16:19:30.000000000 +0000 +@@ -1640,7 +1640,7 @@ void SLPDKnownDARegisterWithAllDas(SLPMe + /* Returns: None */ + /*=========================================================================*/ + { +- if (msg->header.functionid == SLP_FUNCT_SRVDEREG) ++ if (msg->header.functionid == SLP_FUNCT_SRVREG) + { + /* Simply echo the message through as is */ + SLPDKnownDAEcho(msg,buf); +--- ./slpd/slpd_log.c.orig 2002-12-03 21:04:53.000000000 +0000 ++++ ./slpd/slpd_log.c 2006-11-16 16:19:30.000000000 +0000 +@@ -271,6 +271,7 @@ void SLPDLogSrvTypeRqstMessage(SLPSrvTyp + /*-------------------------------------------------------------------------*/ + { + SLPDLog("Message SRVTYPERQST:\n"); ++ SLPDLogBuffer(" scope = ", srvtyperqst->scopelistlen, srvtyperqst->scopelist); + } + + /*-------------------------------------------------------------------------*/ +--- ./slpd/slpd_main.c.orig 2002-12-03 21:04:53.000000000 +0000 ++++ ./slpd/slpd_main.c 2006-11-16 16:19:30.000000000 +0000 +@@ -54,6 +54,7 @@ + #include "slpd_log.h" + #include "slpd_socket.h" + #include "slpd_incoming.h" ++#include "slpd_mdns.h" + #include "slpd_outgoing.h" + #include "slpd_database.h" + #include "slpd_cmdline.h" +@@ -73,7 +74,9 @@ + /*==========================================================================*/ + int G_SIGALRM; + int G_SIGTERM; +-int G_SIGHUP; ++int G_SIGHUP; ++char *reg_file_dir; ++ + #ifdef DEBUG + int G_SIGINT; /* Signal being used for dumping registrations */ + #endif +@@ -160,6 +163,9 @@ void HandleSigTerm() + + /* close all incoming sockets */ + SLPDIncomingDeinit(); ++#ifdef ENABLE_MDNS_SLPD ++ SLPDMDNSDeinit(); ++#endif + + /* unregister with all DAs */ + SLPDKnownDADeinit(); +@@ -218,15 +224,22 @@ void HandleSigHup() + SLPDKnownDADeinit(); + + /* re-read properties */ ++#if 0 + SLPDPropertyInit(G_SlpdCommandLine.cfgfile); ++#else ++ SLPDPropertyInit((char *)0); ++#endif + + #ifdef ENABLE_SLPv2_SECURITY ++ /* does not work in chroot, sorry */ ++# if 0 + /* Re-initialize SPI stuff*/ + SLPDSpiInit(G_SlpdCommandLine.spifile); ++# endif + #endif + + /* Re-read the static registration file (slp.reg)*/ +- SLPDDatabaseReInit(G_SlpdCommandLine.regfile); ++ SLPDDatabaseReInit(); + + /* Rebuild Known DA database */ + SLPDKnownDAInit(); +@@ -247,6 +260,7 @@ void HandleSigAlrm() + SLPDKnownDAPassiveDAAdvert(SLPD_AGE_INTERVAL,0); + SLPDKnownDAActiveDiscovery(SLPD_AGE_INTERVAL); + SLPDDatabaseAge(SLPD_AGE_INTERVAL,G_SlpdProperty.isDA); ++ SLPDDatabaseWatcher(); + } + + +@@ -377,11 +391,21 @@ int Daemonize(const char* pidfile) + close(2); + setsid(); /* will only fail if we are already the process group leader */ + ++ pwent = getpwnam("daemon"); ++ /*---------------------*/ ++ /* chroot to slp.reg.d */ ++ /*---------------------*/ ++ if (chroot(reg_file_dir)) ++ { ++ exit(1); ++ } ++ free(reg_file_dir); ++ reg_file_dir = strdup("."); ++ + /*----------------*/ + /* suid to daemon */ + /*----------------*/ + /* TODO: why do the following lines mess up my signal handlers? */ +- pwent = getpwnam("daemon"); + if(pwent) + { + if(setgroups(1, &pwent->pw_gid) < 0 || +@@ -389,7 +413,10 @@ int Daemonize(const char* pidfile) + setuid(pwent->pw_uid) < 0) + { + /* TODO: should we log here and return fail */ ++ exit(1); + } ++ }else{ ++ exit(1); + } + + /*--------------------*/ +@@ -469,6 +496,8 @@ int main(int argc, char* argv[]) + int highfd; + int fdcount = 0; + ++ reg_file_dir = strdup("/etc/slp.reg.d"); ++ + #ifdef DEBUG + xmalloc_init("/var/log/slpd_xmalloc.log",0); + #endif +@@ -534,6 +563,9 @@ int main(int argc, char* argv[]) + #endif + SLPDDatabaseInit(G_SlpdCommandLine.regfile) || + SLPDIncomingInit() || ++#ifdef ENABLE_MDNS_SLPD ++ SLPDMDNSInit() || ++#endif + SLPDOutgoingInit() || + SLPDKnownDAInit()) + { +@@ -543,6 +575,11 @@ int main(int argc, char* argv[]) + SLPDLog("Agent URL = %s\n",G_SlpdProperty.myUrl); + + /*---------------------------*/ ++ /* init watcher */ ++ /*---------------------------*/ ++ SLPDDatabaseWatcher(); ++ ++ /*---------------------------*/ + /* make slpd run as a daemon */ + /*---------------------------*/ + if(Daemonize(G_SlpdCommandLine.pidfile)) +@@ -585,6 +622,10 @@ int main(int argc, char* argv[]) + LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds); + LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); + ++#ifdef ENABLE_MDNS_SLPD ++ LoadFdSets(&G_MDNSSocketList, &highfd, &readfds,&writefds); ++#endif ++ + /*--------------------------------------------------*/ + /* Before select(), check to see if we got a signal */ + /*--------------------------------------------------*/ +@@ -601,6 +642,10 @@ int main(int argc, char* argv[]) + { + SLPDIncomingHandler(&fdcount,&readfds,&writefds); + SLPDOutgoingHandler(&fdcount,&readfds,&writefds); ++ ++#ifdef ENABLE_MDNS_SLPD ++ SLPDMDNSHandler(&fdcount,&readfds,&writefds); ++#endif + } + + /*----------------*/ +--- ./slpd/slpd_mdns.c.orig 2006-11-16 16:19:30.000000000 +0000 ++++ ./slpd/slpd_mdns.c 2006-11-16 16:19:30.000000000 +0000 +@@ -0,0 +1,906 @@ ++#include "slpd_mdns.h" ++#include "slpd_socket.h" ++#include "slpd_property.h" ++#include "slpd_database.h" ++#include "slpd_log.h" ++ ++#include "slp_compare.h" ++#ifdef ENABLE_PREDICATES ++# include "slpd_predicate.h" ++#endif ++ ++ ++extern SLPDDatabase G_SlpdDatabase; ++ ++extern int JoinSLPMulticastGroup(sockfd_t sockfd, struct in_addr* maddr, ++ struct in_addr* addr); ++extern int EnableBroadcast(sockfd_t sockfd); ++ ++ ++#define MDNS_MAX_DATAGRAM_SIZE 8000 ++ ++/*=========================================================================*/ ++/* common code includes */ ++/*=========================================================================*/ ++#include "slp_xmalloc.h" ++ ++ ++static void MDNSDatagramRead(SLPList* socklist, SLPDSocket* sock); ++static int MDNSHandleSrvTypeRqst(SLPBuffer buf, SLPBuffer obuf, unsigned char *q, int qtype, unsigned char **an, unsigned char **ad, int ac, int mdnspeer, unsigned char *txtbuf, int txtlen); ++static int MDNSHandleSrvsRqst(SLPBuffer buf, SLPBuffer obuf, unsigned char *q, int qtype, unsigned char **an, unsigned char **ad, int ac, int mdnspeer, unsigned char *txtbuf, int txtlen, struct sockaddr_in *); ++static int MDNSHandleARqst(SLPBuffer buf, SLPBuffer obuf, unsigned char *q, int qtype, unsigned char **an, unsigned char **ad, int ac, int mdnspeer, struct sockaddr_in *ifaddr); ++ ++ ++SLPList G_MDNSSocketList = {0,0,0}; ++ ++ ++SLPDSocket* SLPDMDNSCreateBoundDatagram(struct in_addr* myaddr, ++ struct in_addr* peeraddr, ++ int type) ++{ ++ SLPDSocket* sock; ++ struct in_addr* bindaddr; ++ struct sockaddr_in mysockaddr; ++#ifdef _WIN32 ++ BOOL reuse = TRUE; ++#else ++ int reuse = 1; ++#endif ++ unsigned char ttl = 255; ++ ++ /*------------------------------------------*/ ++ /* Adjust for multicast binding differences */ ++ /*------------------------------------------*/ ++#ifdef LINUX ++ bindaddr = peeraddr; ++#else ++ if(type == DATAGRAM_MULTICAST) ++ bindaddr = NULL; /* must bind to INADDR_ANY for multicast */ ++ else ++ bindaddr = peeraddr; ++#endif ++ ++ /*------------------------*/ ++ /* Create and bind socket */ ++ /*------------------------*/ ++ sock = SLPDSocketAlloc(); ++ if (!sock) ++ return 0; ++ if (myaddr) ++ sock->ifaddr.sin_addr = *myaddr; ++ sock->recvbuf = SLPBufferAlloc(MDNS_MAX_DATAGRAM_SIZE); ++ sock->sendbuf = SLPBufferAlloc(MDNS_MAX_DATAGRAM_SIZE); ++ sock->fd = socket(PF_INET, SOCK_DGRAM, 0); ++ if (sock->fd < 0) ++ { ++ SLPDSocketFree(sock); ++ return 0; ++ } ++ memset(&mysockaddr, 0, sizeof(mysockaddr)); ++ mysockaddr.sin_family = AF_INET; ++ mysockaddr.sin_port = htons(MDNS_RESERVED_PORT); ++ mysockaddr.sin_addr.s_addr = INADDR_ANY; ++ if (bindaddr) ++ mysockaddr.sin_addr = *bindaddr; ++ setsockopt(sock->fd,SOL_SOCKET,SO_REUSEADDR,(const char *)&reuse,sizeof(reuse)); ++ setsockopt(sock->fd,SOL_IP,IP_TTL,(const char *)&ttl,sizeof(ttl)); ++ setsockopt(sock->fd,SOL_IP,IP_MULTICAST_TTL,(const char *)&ttl,sizeof(ttl)); ++ if (bind(sock->fd, (struct sockaddr *) &mysockaddr,sizeof(mysockaddr))) ++ { ++ SLPDSocketFree(sock); ++ return 0; ++ } ++ if(peeraddr != NULL) ++ sock->peeraddr.sin_addr = *peeraddr; ++ switch(type) ++ { ++ case DATAGRAM_MULTICAST: ++ if(JoinSLPMulticastGroup(sock->fd, peeraddr, myaddr) == 0) ++ { ++ sock->state = DATAGRAM_MULTICAST; ++ return sock; ++ } ++ break; ++ case DATAGRAM_BROADCAST: ++ if(EnableBroadcast(sock->fd) == 0) ++ { ++ sock->state = DATAGRAM_BROADCAST; ++ return sock; ++ } ++ break; ++ case DATAGRAM_UNICAST: ++ default: ++ sock->state = DATAGRAM_UNICAST; ++ return sock; ++ } ++ SLPDSocketFree(sock); ++ return 0; ++} ++ ++int SLPDMDNSInit(void) ++{ ++ int iface; ++ struct in_addr myaddr; ++ struct in_addr mcastaddr; ++ SLPDSocket* sock; ++ ++ /*------------------------------------------------------------*/ ++ /* First, remove all of the sockets that might be in the list */ ++ /*------------------------------------------------------------*/ ++ while (G_MDNSSocketList.count) ++ { ++ SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_MDNSSocketList,G_MDNSSocketList.head)); ++ } ++ ++ /*----------------------------------------------------------------*/ ++ /* Create sockets for all of the interfaces in the interface list */ ++ /*----------------------------------------------------------------*/ ++ mcastaddr.s_addr = htonl(MDNS_MCAST_ADDRESS); ++ ++ for (iface = 0; iface < G_SlpdProperty.ifaceInfo.iface_count; iface++) ++ { ++ myaddr = G_SlpdProperty.ifaceInfo.iface_addr[iface].sin_addr; ++ ++ /*----------------------------------------------------------------*/ ++ /* Create socket that will handle multicast UDP. */ ++ /*----------------------------------------------------------------*/ ++ ++ sock = SLPDMDNSCreateBoundDatagram(&myaddr, ++ &mcastaddr, ++ DATAGRAM_MULTICAST); ++ if (sock) ++ { ++ SLPListLinkTail(&G_MDNSSocketList,(SLPListItem*)sock); ++ SLPDLog("Multicast MDNS socket on %s ready\n",inet_ntoa(myaddr)); ++ } ++ else ++ { ++ SLPDLog("Couldn't bind to multicast MDNS for interface %s (%s)\n", ++ inet_ntoa(myaddr), strerror(errno)); ++ } ++ ++ /*--------------------------------------------*/ ++ /* Create socket that will handle unicast UDP */ ++ /*--------------------------------------------*/ ++ sock = SLPDMDNSCreateBoundDatagram(&myaddr, ++ &myaddr, ++ DATAGRAM_UNICAST); ++ if (sock) ++ { ++ SLPListLinkTail(&G_MDNSSocketList,(SLPListItem*)sock); ++ SLPDLog("Unicast MDNS socket on %s ready\n",inet_ntoa(myaddr)); ++ } ++ } ++ ++ if (G_MDNSSocketList.count == 0) ++ { ++ SLPDLog("No usable MDNS interfaces\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/*=========================================================================*/ ++int SLPDMDNSDeinit() ++/* Deinitialize incoming socket list to have appropriate sockets for all */ ++/* network interfaces */ ++/* */ ++/* Returns Zero on success non-zero on error */ ++/*=========================================================================*/ ++{ ++ SLPDSocket* del = 0; ++ SLPDSocket* sock = (SLPDSocket*)G_MDNSSocketList.head; ++ while (sock) ++ { ++ del = sock; ++ sock = (SLPDSocket*)sock->listitem.next; ++ if (del) ++ { ++ SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_MDNSSocketList,(SLPListItem*)del)); ++ del = 0; ++ } ++ } ++ ++ return 0; ++} ++ ++/*=========================================================================*/ ++void SLPDMDNSHandler(int* fdcount, ++ fd_set* readfds, ++ fd_set* writefds) ++/* Handles all outgoing requests that are pending on the specified file */ ++/* discriptors */ ++/* */ ++/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* */ ++/* readfds (IN) file descriptors with pending read IO */ ++/* */ ++/* writefds (IN) file descriptors with pending read IO */ ++/*=========================================================================*/ ++{ ++ SLPDSocket* sock; ++ sock = (SLPDSocket*) G_MDNSSocketList.head; ++ while (sock && *fdcount) ++ { ++ if (FD_ISSET(sock->fd,readfds)) ++ { ++ switch (sock->state) ++ { ++ case DATAGRAM_UNICAST: ++ case DATAGRAM_MULTICAST: ++ case DATAGRAM_BROADCAST: ++ MDNSDatagramRead(&G_MDNSSocketList,sock); ++ break; ++ default: ++ break; ++ } ++ ++ *fdcount = *fdcount - 1; ++ } ++ sock = (SLPDSocket*)sock->listitem.next; ++ } ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++static void MDNSDatagramRead(SLPList* socklist, SLPDSocket* sock) ++/*-------------------------------------------------------------------------*/ ++{ ++ int bytesread; ++ int bytestowrite; ++ int byteswritten; ++ int peeraddrlen = sizeof(struct sockaddr_in); ++ int qcount, acount, ncount, xcount; ++ unsigned char *bp, *end; ++ SLPBuffer buf; ++ int mdnspeer; ++ int qtype = 0; ++ int qclass = 0; ++ unsigned char * an[SLP_MDNS_MAX_RR]; ++ unsigned char * ad[SLP_MDNS_MAX_RR]; ++ int ac; ++ int result; ++ unsigned char * txtbuf = 0; ++ int txtlen = 0; ++ ++ ++ buf = sock->recvbuf; ++ bytesread = recvfrom(sock->fd, ++ buf->start, ++ MDNS_MAX_DATAGRAM_SIZE, ++ 0, ++ (struct sockaddr *) &(sock->peeraddr), ++ &peeraddrlen); ++ if (bytesread < 12) ++ return; ++ buf->end = buf->start + bytesread; ++#ifdef DEBUG ++ SLPMDNSDumpDNS(buf, "mdns incoming"); ++#endif ++ ++ if ((buf->start[2] & 0xf0) != 0x00) ++ return; /* no standard query */ ++ ++ qcount = AsUINT16(buf->start + 4); ++ if (qcount > 1) ++ return; /* not supported at the moment */ ++ if (qcount == 0) ++ return; /* no query to answer */ ++ acount = AsUINT16(buf->start + 6); ++ ncount = AsUINT16(buf->start + 8); ++ xcount = AsUINT16(buf->start + 10); ++ ++ bp = (unsigned char *)buf->start + 12; ++ /* skip query section */ ++ end = buf->end; ++ if (qcount) ++ { ++ while (bp < end && *bp && (*bp & 0xc0) != 0xc0) ++ bp += *bp + 1; ++ if (bp < end && *bp) ++ bp++; ++ bp += 5; ++ if (bp <= end) ++ { ++ qtype = AsUINT16(bp - 4); ++ qclass = AsUINT16(bp - 2); ++ } ++ } ++ bp = SLPMDNSParseRR(bp, end, acount, an, ad, &ac); ++ if (bp > end) ++ return; ++ bp = SLPMDNSParseRR(bp, end, ncount, 0, 0, 0); ++ bp = SLPMDNSParseRR(bp, end, xcount, 0, 0, 0); ++ ++ /* validate DNS request */ ++ if (qcount > 0 && SLPMDNSCheckN(buf->start, bp > end ? end : bp, buf->start + 12, 0)) ++ return; ++ if (SLPMDNSCheckRR(buf->start, bp > end ? end : bp, an, ad, &ac)) ++ return; ++ ++ if (qcount == 0) ++ return; ++ if (qclass != DNS_CLASS_IN && qclass != DNS_CLASS_ANY) ++ return; ++ mdnspeer = (sock->peeraddr.sin_port == htons(MDNS_RESERVED_PORT)); ++ ++ if (qtype == DNS_TYPE_ANY || qtype == DNS_TYPE_A) ++ { ++ unsigned char myhostname[256]; ++ if (MDNSStrToN(myhostname, myhostname + sizeof(myhostname), G_SlpdProperty.myHostname, G_SlpdProperty.myHostnameLen)) ++ { ++ if (!SLPMDNSCmpN(buf->start + 12, buf->start, myhostname, 0)) ++ { ++ result = MDNSHandleARqst(buf, sock->sendbuf, buf->start + 12, qtype, an, ad, ac, mdnspeer, &sock->ifaddr); ++ goto reply; ++ } ++ } ++ } ++ ++ if (qtype != DNS_TYPE_PTR && qtype != DNS_TYPE_ANY) ++ return; ++ if (ac > 0 && !memcmp(an[0], "\011_slpquery\300\014", 12) && AsUINT16(ad[0]) == DNS_TYPE_TXT) ++ { ++ txtlen = AsUINT16(ad[0] + 8); ++ txtbuf = ad[0] + 10; ++ } ++ ++ if (!SLPMDNSCmpN(buf->start + 12, buf->start, "\011_services\007_dns-sd\004_udp\005local\000", 0)) ++ { ++ result = MDNSHandleSrvTypeRqst(buf, sock->sendbuf, buf->start + 12, qtype, an, ad, ac, mdnspeer, txtbuf, txtlen); ++ } ++ else ++ { ++ result = MDNSHandleSrvsRqst(buf, sock->sendbuf, buf->start + 12, qtype, an, ad, ac, mdnspeer, txtbuf, txtlen, &sock->ifaddr); ++ } ++ ++reply: ++ if (result) ++ return; ++ ++ bytestowrite = sock->sendbuf->end - sock->sendbuf->start; ++ if (bytestowrite > 0) ++ { ++ byteswritten = sendto(sock->fd, ++ sock->sendbuf->start, ++ bytestowrite, ++ 0, ++ (struct sockaddr *)&(sock->peeraddr), ++ sizeof(struct sockaddr_in)); ++ if (byteswritten != bytestowrite) ++ { ++ SLPDLog("NETWORK_ERROR - %d replying %s\n", ++ errno, ++ inet_ntoa(sock->peeraddr.sin_addr)); ++ } ++ } ++ ++} ++ ++static int MDNSParseHostPort(const char *url, int urllen, const char **hostp, int *portp) ++{ ++ int l, hl, port; ++ ++ for (l = 0; l < urllen; l++) ++ if (l && url[l] == '/' && url[l - 1] == '/') ++ break; ++ l++; ++ if (l >= urllen) ++ return 0; ++ url += l; ++ urllen -= l; ++ if (hostp) ++ *hostp = url; ++ for (l = 0; l < urllen ; l++) ++ if (url[l] == '/' || url[l] == ':') ++ break; ++ if (l == urllen || url[l] != ':') ++ { ++ if (portp) ++ *portp = 0; ++ return l; ++ } ++ port = 0; ++ hl = l++; ++ url += l; ++ urllen -= l; ++ for (l = 0; l < urllen ; l++) ++ if (url[l] <= '0' || url[l] >= '9') ++ break; ++ else ++ port = port * 10 + (url[l] - '0'); ++ if (l < urllen && url[l] != '/') ++ return 0; ++ if (portp) ++ *portp = port; ++ return hl; ++} ++ ++ ++static int MDNSHandleSrvTypeRqst(SLPBuffer buf, SLPBuffer obuf, unsigned char *q, int qtype, unsigned char **an, unsigned char **ad, int ac, int mdnspeer, unsigned char *txtbuf, int txtlen) ++{ ++ SLPDatabaseHandle dh; ++ SLPDatabaseEntry* entry; ++ SLPSrvReg* entryreg; ++ char srvbuf[80]; ++ unsigned char *md[SLP_MDNS_MAX_RR]; ++ unsigned char *oend, *bp, *oldbp; ++ unsigned char *cvec[256]; ++ int i, port; ++ int ncvec; ++ int nans; ++ char *nameauth; ++ int nameauthlen; ++ ++ nameauthlen = 0xffff; ++ nameauth = SLPMDNSFindInTxt(txtbuf, txtlen, "namingauth=", &nameauthlen); ++ ++ obuf->start[0] = buf->start[0]; /* xid */ ++ obuf->start[1] = buf->start[1]; /* xid */ ++ obuf->start[2] = 0x84; ++ obuf->start[3] = 0x00; ++ obuf->start[4] = obuf->start[5] = 0; /* qcount */ ++ obuf->start[6] = obuf->start[7] = 0; /* acount */ ++ obuf->start[8] = obuf->start[9] = 0; /* ncount */ ++ obuf->start[10] = obuf->start[11] = 0; /* xcount */ ++ ++ ncvec = 0; ++ bp = obuf->start + 12; ++ oend = obuf->start + obuf->allocated; ++ if (!mdnspeer) ++ { ++ bp = SLPMDNSCompN(bp, oend, q, buf->start, cvec, &ncvec, obuf->start); ++ if (!bp || bp + 4 >= oend) ++ return 1; ++ *bp++ = 0; ++ *bp++ = qtype; ++ *bp++ = 0; ++ *bp++ = DNS_CLASS_IN; ++ obuf->start[5] = 1; ++ } ++ ++ nans = 0; ++ dh = SLPDatabaseOpen(&G_SlpdDatabase.database); ++ while ((entry = SLPDatabaseEnum(dh)) != 0) ++ { ++ entryreg = &(entry->msg->body.srvreg); ++ if ((entryreg->watchflags & SLP_REG_WATCH_DEAD) != 0) ++ continue; ++ ++ if (SLPCompareNamingAuth(entryreg->srvtypelen, ++ entryreg->srvtype, ++ nameauthlen, ++ nameauth)) ++ continue; ++ ++#if 0 ++ if (!SLPContainsStringList(entryreg->scopelistlen, entryreg->scopelist, 5, "_mdns")) ++ continue; ++#endif ++ ++ if (!MDNSParseHostPort(entryreg->urlentry.url, entryreg->urlentry.urllen, 0, &port)) ++ continue; ++ if (!port) ++ continue; ++ ++ if (!SLPMDNSSrvtypeToN(srvbuf, srvbuf + sizeof(srvbuf), entryreg->srvtype, entryreg->srvtypelen)) ++ continue; ++ ++ /* check if answer is already known in query */ ++ for (i = 0; i < ac; i++) ++ if (AsUINT16(ad[i]) == DNS_TYPE_PTR && ++ !SLPMDNSCmpN(ad[i] + 10, buf->start, srvbuf, 0)) ++ break; ++ if (i < ac) ++ continue; ++ ++ /* check if answer already in our packet */ ++ for (i = 0; i < nans; i++) ++ if (!SLPMDNSCmpN(md[i] + 10, obuf->start, srvbuf, 0)) ++ break; ++ if (i < nans) ++ continue; ++ ++ /* new answer, add to return buffer */ ++ oldbp = bp; ++ bp = SLPMDNSAddRR(bp, obuf->start, oend, q, buf->start, ++ DNS_TYPE_PTR, mdnspeer ? entryreg->urlentry.lifetime : 10, ++ cvec, &ncvec, 0, srvbuf, md + nans); ++ if (!bp) ++ { ++ bp = oldbp; ++ break; ++ } ++ if (++nans == SLP_MDNS_MAX_RR) ++ break; ++ } ++ ToUINT16(obuf->start + 6, nans); ++ SLPDatabaseClose(dh); ++ if (bp >= oend) ++ return 1; ++ if (nans) ++ { ++ obuf->end = bp; ++#ifdef DEBUG ++ SLPMDNSDumpDNS(obuf, "mdns outgoing"); ++#endif ++ } ++ else ++ obuf->end = obuf->start; ++ return 0; ++} ++ ++ ++static void SLPDAddAttrs(unsigned char *txtbuf, int txtbuflen, int *txtlen, const char *attr, int attrlen, char *taglist, int taglistlen) ++{ ++ const char *ts, *vs; ++ int tl, vl, i; ++ ++ while (attrlen > 0) ++ { ++ if (*attr != '(') ++ { ++ /* keyword */ ++ vs = 0; ++ vl = 0; ++ ts = attr; ++ for (i = 0; i < attrlen; i++) ++ if (attr[i] == ',') ++ break; ++ tl = i; ++ attr += i; ++ attrlen -= i; ++ } ++ else ++ { ++ /* (key=value,value...) */ ++ attr++; ++ attrlen--; ++ ts = attr; ++ for (i = 0; i < attrlen; i++) ++ if (attr[i] == '=') ++ break; ++ tl = i; ++ attr += i + 1; ++ attrlen -= i + 1; ++ if (attrlen <= 0) ++ break; ++ vs = attr; ++ for (i = 0; i < attrlen; i++) ++ if (attr[i] == ')') ++ break; ++ if (i == attrlen) ++ break; ++ vl = i; ++ attr += i + 1; ++ attrlen -= i + 1; ++ } ++ if (!taglistlen || SLPContainsStringList(taglistlen, taglist, tl, ts)) ++ { ++ if (tl + 1 + vl <= 255) ++ { ++ char tagbuf[256]; ++ memcpy(tagbuf, ts, tl); ++ if (vs) ++ { ++ tagbuf[tl] = '='; ++ tl++; ++ } ++ tagbuf[tl] = 0; ++ SLPMDNSAddTxt(txtbuf, txtbuflen, txtlen, tagbuf, vs, vl); ++ } ++ } ++ if (attrlen) ++ { ++ attr++; ++ attrlen--; ++ } ++ } ++} ++ ++static int MDNSHandleSrvsRqst(SLPBuffer buf, SLPBuffer obuf, unsigned char *q, int qtype, unsigned char **an, unsigned char **ad, int ac, int mdnspeer, unsigned char *txtbuf, int txtlen, struct sockaddr_in *ifaddr) ++{ ++ SLPDatabaseHandle dh; ++ SLPDatabaseEntry* entry; ++ SLPSrvReg* entryreg; ++ SLPUrlEntry* urlentry; ++ char srvtype[256]; ++ int srvtypelen; ++ int i; ++ unsigned char *bp, *oend; ++ unsigned char *cvec[256]; ++ int ncvec; ++ const char *host; ++ int hostlen, hostlennq; ++ int port; ++ unsigned char ptr[256]; ++ int nans; ++ unsigned char *oldbp; ++ unsigned char xbuf[8000]; ++ unsigned char *xn[SLP_MDNS_MAX_RR]; ++ unsigned char *xd[SLP_MDNS_MAX_RR]; ++ unsigned char *xp, *xend; ++ int xc = 0; ++ unsigned char *rad[SLP_MDNS_MAX_RR]; ++ int unify; ++#ifdef ENABLE_PREDICATES ++ int predlen; ++ char *pred; ++#endif ++ char *slpurl; ++ int slpurllen; ++ char *taglist; ++ int taglistlen; ++ unsigned char otxtbuf[512]; ++ int otxtlen; ++ ++ slpurllen = 0; ++ slpurl = SLPMDNSFindInTxt(txtbuf, txtlen, "slpurl=", &slpurllen); ++ taglistlen = 0; ++ taglist = SLPMDNSFindInTxt(txtbuf, txtlen, "taglist=", &taglistlen); ++ ++#ifdef ENABLE_PREDICATES ++ predlen = 0; ++ pred = SLPMDNSFindInTxt(txtbuf, txtlen, "predicate=", &predlen); ++#endif ++ ++ xp = xbuf; ++ xend = xbuf + sizeof(xbuf); ++ ++ obuf->start[0] = buf->start[0]; /* xid */ ++ obuf->start[1] = buf->start[1]; /* xid */ ++ obuf->start[2] = 0x84; ++ obuf->start[3] = 0x00; ++ obuf->start[4] = obuf->start[5] = 0; /* qcount */ ++ obuf->start[6] = obuf->start[7] = 0; /* acount */ ++ obuf->start[8] = obuf->start[9] = 0; /* ncount */ ++ obuf->start[10] = obuf->start[11] = 0; /* xcount */ ++ ++ ncvec = 0; ++ bp = obuf->start + 12; ++ oend = obuf->start + obuf->allocated; ++ if (!mdnspeer) ++ { ++ bp = SLPMDNSCompN(bp, oend, q, buf->start, cvec, &ncvec, obuf->start); ++ if (!bp || bp + 4 >= oend) ++ return 1; ++ *bp++ = 0; ++ *bp++ = qtype; ++ *bp++ = 0; ++ *bp++ = DNS_CLASS_IN; ++ obuf->start[5] = 1; ++ } ++ /* convert query in srvtype (query is already checked) */ ++ srvtypelen = SLPMDNSNToSrvtype(q, buf->start, srvtype, sizeof(srvtype) - 1); ++ if (srvtypelen == 0) ++ return 1; ++ srvtype[srvtypelen] = 0; ++ /* printf("srvtype: %s\n", srvtype); */ ++ ++ nans = 0; ++ dh = SLPDatabaseOpen(&G_SlpdDatabase.database); ++ while ((entry = SLPDatabaseEnum(dh)) != 0) ++ { ++ entryreg = &(entry->msg->body.srvreg); ++ if ((entryreg->watchflags & SLP_REG_WATCH_DEAD) != 0) ++ continue; ++ urlentry = &entryreg->urlentry; ++ ++ /* limit to one exact url, used for AttrRqst */ ++ if (slpurllen && SLPCompareString(urlentry->urllen, urlentry->url, slpurllen, slpurl)) ++ continue; ++ ++ /* limit to matching srvtypes */ ++ if (!slpurllen && SLPCompareSrvType(srvtypelen, ++ srvtype, ++ entryreg->srvtypelen, ++ entryreg->srvtype) != 0) ++ continue; ++ ++#ifdef ENABLE_PREDICATES ++ if (!SLPDPredicateTest(2, ++ entryreg->attrlistlen, ++ entryreg->attrlist, ++ predlen, ++ pred)) ++ continue; ++#endif ++ ++ otxtlen = 0; ++ ++ /* printf("HIT: %.*s\n", urlentry->urllen, urlentry->url); */ ++ ++ hostlen = MDNSParseHostPort(urlentry->url, urlentry->urllen, &host, &port); ++ if (!hostlen || !port) ++ continue; ++ if (*host >= '0' && *host <= '9') ++ hostlennq = hostlen; ++ else ++ for (hostlennq = 0; hostlennq < hostlen; hostlennq++) ++ if (host[hostlennq] == '.') ++ break; ++ if (hostlennq == 0 || hostlennq > 63) ++ continue; ++ ++ /* create an unique name */ ++ for (unify = 0; unify < SLP_MDNS_MAX_RR; unify++) ++ { ++ ptr[0] = hostlennq; ++ memcpy(ptr + 1, host, hostlennq); ++ if (unify) ++ { ++ /* will always fit into ptr, as hostlennq < 64 */ ++ sprintf(ptr + 1 + hostlennq, "_%d", unify == 1 ? port : unify); ++ i = strlen(ptr + 1); ++ if (i > 63) ++ break; ++ ptr[0] = i; ++ } ++ /* append query name */ ++ if (!SLPMDNSCopyN(ptr + 1 + *ptr, ptr + sizeof(ptr), q, buf->start)) ++ break; ++ for (i = 0; i < nans; i++) ++ if (!SLPMDNSCmpN(rad[i] + 10, obuf->start, ptr, 0)) ++ break; ++ if (i == nans) ++ { ++ unify = -1; ++ break; ++ } ++ } ++ if (unify != -1) ++ continue; ++ ++ /* check if it is already in the answer section of the query */ ++ for (i = 0; i < ac; i++) ++ if (AsUINT16(ad[i]) == DNS_TYPE_PTR && ++ !SLPMDNSCmpN(ad[i] + 10, buf->start, ptr, 0)) ++ break; ++ if (i < ac) ++ continue; ++ ++ /* great, a new entry */ ++ oldbp = bp; ++ bp = SLPMDNSAddRR(bp, obuf->start, oend, q, buf->start, ++ DNS_TYPE_PTR, mdnspeer ? urlentry->lifetime : 10, ++ cvec, &ncvec, 0, ptr, rad + nans); ++ if (!bp) ++ { ++ bp = oldbp; ++ break; ++ } ++ ++ /* set up extra answers */ ++ if (xp && xc < SLP_MDNS_MAX_RR) ++ { ++ unsigned char data[256]; ++ if (!MDNSStrToN(data, data + sizeof(data), host, hostlen)) ++ continue; ++ xn[xc] = xp; ++ xp = SLPMDNSAddRR(xp, 0, xend, ptr, obuf->start, ++ DNS_TYPE_SRV, mdnspeer ? urlentry->lifetime : 10, ++ 0, 0, port, data, xd + xc); ++ if (xp) ++ xc++; ++ } ++ SLPMDNSAddTxt(otxtbuf, sizeof(otxtbuf), &otxtlen, "slpurl=", urlentry->url, urlentry->urllen); ++ SLPDAddAttrs(otxtbuf, sizeof(otxtbuf), &otxtlen, entryreg->attrlist, entryreg->attrlistlen, taglist, taglistlen); ++ if (xp && xc < SLP_MDNS_MAX_RR && otxtlen) ++ { ++ xn[xc] = xp; ++ xp = SLPMDNSAddRR(xp, 0, xend, ptr, obuf->start, ++ DNS_TYPE_TXT, mdnspeer ? urlentry->lifetime : 10, ++ 0, 0, otxtlen, otxtbuf, xd + xc); ++ if (xp) ++ xc++; ++ } ++ if (++nans == SLP_MDNS_MAX_RR) ++ break; ++ } ++ ToUINT16(obuf->start + 6, nans); ++ SLPDatabaseClose(dh); ++ if (bp >= oend) ++ return 1; ++ ++ /* add an A RR of our hostname to x info */ ++ if (nans && xp && xc < SLP_MDNS_MAX_RR) ++ { ++ unsigned char myhostname[256]; ++ if (MDNSStrToN(myhostname, myhostname + sizeof(myhostname), G_SlpdProperty.myHostname, G_SlpdProperty.myHostnameLen)) ++ { ++ xn[xc] = xp; ++ xp = SLPMDNSAddRR(xp, 0, xend, myhostname, 0, ++ DNS_TYPE_A, 10, ++ 0, 0, 4, (unsigned char *)&ifaddr->sin_addr, ++ xd + xc); ++ if (xp) ++ xc++; ++ } ++ } ++ ++ if (nans) ++ { ++ /* add x info */ ++ int nxans = 0; ++ for (i = 0; i < xc; i++) ++ { ++ int type; ++ type = AsUINT16(xd[i]); ++ oldbp = bp; ++ if (type == DNS_TYPE_SRV) ++ bp = SLPMDNSAddRR(bp, obuf->start, oend, xn[i], 0, type, AsUINT32(xd[i] + 4), cvec, &ncvec, AsUINT16(xd[i] + 14), xd[i] + 16, 0); ++ else if (type == DNS_TYPE_TXT || type == DNS_TYPE_A) ++ bp = SLPMDNSAddRR(bp, obuf->start, oend, xn[i], 0, type, AsUINT32(xd[i] + 4), cvec, &ncvec, AsUINT16(xd[i] + 8), xd[i] + 10, 0); ++ else ++ continue; ++ if (!bp) ++ { ++ bp = oldbp; ++ break; ++ } ++ nxans++; ++ } ++ ToUINT16(obuf->start + 10, nxans); ++ obuf->end = bp; ++#ifdef DEBUG ++ SLPMDNSDumpDNS(obuf, "mdns outgoing"); ++#endif ++ } ++ else ++ obuf->end = obuf->start; ++ return 0; ++} ++ ++static int MDNSHandleARqst(SLPBuffer buf, SLPBuffer obuf, unsigned char *q, int qtype, unsigned char **an, unsigned char **ad, int ac, int mdnspeer, struct sockaddr_in *ifaddr) ++{ ++ unsigned char *data, *bp, *oend; ++ unsigned char *cvec[256]; ++ int i, ncvec; ++ ++ data = (unsigned char *)&ifaddr->sin_addr; ++ ++ obuf->start[0] = buf->start[0]; /* xid */ ++ obuf->start[1] = buf->start[1]; /* xid */ ++ obuf->start[2] = 0x84; ++ obuf->start[3] = 0x00; ++ obuf->start[4] = obuf->start[5] = 0; /* qcount */ ++ obuf->start[6] = obuf->start[7] = 0; /* acount */ ++ obuf->start[8] = obuf->start[9] = 0; /* ncount */ ++ obuf->start[10] = obuf->start[11] = 0; /* xcount */ ++ ++ ncvec = 0; ++ bp = obuf->start + 12; ++ oend = obuf->start + obuf->allocated; ++ if (!mdnspeer) ++ { ++ bp = SLPMDNSCompN(bp, oend, q, buf->start, cvec, &ncvec, obuf->start); ++ if (!bp || bp + 4 >= oend) ++ return 1; ++ *bp++ = 0; ++ *bp++ = qtype; ++ *bp++ = 0; ++ *bp++ = DNS_CLASS_IN; ++ obuf->start[5] = 1; ++ } ++ ++ for (i = 0; i < ac; i++) ++ if (AsUINT16(ad[i]) == DNS_TYPE_A && ++ !memcmp(ad[i] + 10, data, 4)) ++ break; ++ if (i < ac) ++ { ++ obuf->end = obuf->start; ++ return 0; ++ } ++ ++ bp = SLPMDNSAddRR(bp, obuf->start, oend, q, buf->start, DNS_TYPE_A, 10, cvec, &ncvec, 4, data, 0); ++ if (!bp) ++ return 1; ++ obuf->start[7] = 1; ++ obuf->end = bp; ++#ifdef DEBUG ++ SLPMDNSDumpDNS(obuf, "mdns outgoing"); ++#endif ++ return 0; ++} +--- ./slpd/slpd_mdns.h.orig 2006-11-16 16:19:30.000000000 +0000 ++++ ./slpd/slpd_mdns.h 2006-11-16 16:19:30.000000000 +0000 +@@ -0,0 +1,50 @@ ++#ifndef SLPD_MDNS_H_INCLUDE ++#define SLPD_MDNS_H_INCLUDE ++ ++#include "slpd.h" ++ ++/*=========================================================================*/ ++/* common code includes */ ++/*=========================================================================*/ ++#include "slp_linkedlist.h" ++#include "slp_mdns.h" ++ ++ ++/*=========================================================================*/ ++extern SLPList G_MDNSSocketList; ++/*=========================================================================*/ ++ ++ ++/*=========================================================================*/ ++void SLPDMDNSHandler(int* fdcount, ++ fd_set* readfds, ++ fd_set* writefds); ++/* Handles all outgoing requests that are pending on the specified file */ ++/* discriptors */ ++/* */ ++/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* */ ++/* readfds (IN) file descriptors with pending read IO */ ++/* */ ++/* writefds (IN) file descriptors with pending read IO */ ++/*=========================================================================*/ ++ ++ ++/*=========================================================================*/ ++int SLPDMDNSInit(void); ++/* Initialize incoming socket list to have appropriate sockets for all */ ++/* network interfaces */ ++/* */ ++/* Returns Zero on success non-zero on error */ ++/*=========================================================================*/ ++ ++ ++/*=========================================================================*/ ++int SLPDMDNSDeinit(void); ++/* Deinitialize incoming socket list to have appropriate sockets for all */ ++/* network interfaces */ ++/* */ ++/* Returns Zero on success non-zero on error */ ++/*=========================================================================*/ ++ ++#endif +--- ./slpd/slpd_process.c.orig 2003-02-20 16:43:57.000000000 +0000 ++++ ./slpd/slpd_process.c 2006-11-16 16:19:30.000000000 +0000 +@@ -1331,11 +1331,14 @@ int SLPDProcessMessage(struct sockaddr_i + + SLPDLogMessage(SLPDLOG_TRACEMSG_IN,peerinfo,recvbuf); + +- /* set the sendbuf empty */ +- if(*sendbuf) ++ if(!*sendbuf) + { +- (*sendbuf)->end = (*sendbuf)->start; ++ *sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); ++ if (!*sendbuf) ++ return SLP_ERROR_PARSE_ERROR; + } ++ /* set the sendbuf empty */ ++ (*sendbuf)->end = (*sendbuf)->start; + + /* zero out the header before parsing it */ + memset(&header,0,sizeof(header)); +--- ./slpd/slpd_property.c.orig 2002-06-11 17:25:40.000000000 +0000 ++++ ./slpd/slpd_property.c 2006-11-16 16:19:30.000000000 +0000 +@@ -65,6 +65,7 @@ + + /*=========================================================================*/ + SLPDProperty G_SlpdProperty; ++FILE* G_SlpdConffileFP; + /*=========================================================================*/ + + /*=========================================================================*/ +@@ -74,8 +75,18 @@ int SLPDPropertyInit(const char* conffil + char* myname = 0; + char* myinterfaces = 0; + char* myurl = 0; ++ const char* ifaces = 0; ++ extern int * SLPPropertyReadFileFP(FILE *); + +- SLPPropertyReadFile(conffile); ++ if (conffile) ++ { ++ G_SlpdConffileFP = fopen(conffile, "r"); ++ if (G_SlpdConffileFP) ++ { ++ SLPPropertySet("net.slp.OpenSLPConfigFile",conffile); ++ } ++ } ++ SLPPropertyReadFileFP(G_SlpdConffileFP); + + memset(&G_SlpdProperty,0,sizeof(G_SlpdProperty)); + +@@ -125,9 +136,14 @@ int SLPDPropertyInit(const char* conffil + /*-------------------------------------*/ + /* Set the net.slp.interfaces property */ + /*-------------------------------------*/ +- if(SLPIfaceGetInfo(SLPPropertyGet("net.slp.interfaces"),&G_SlpdProperty.ifaceInfo) == 0) ++ ifaces = SLPPropertyGet("net.slp.interfaces"); ++ if (!ifaces || !*ifaces) + { +- if(SLPPropertyGet("net.slp.interfaces")) ++ G_SlpdProperty.updateIfaces = 1; ++ } ++ if(SLPIfaceGetInfo(ifaces, &G_SlpdProperty.ifaceInfo) == 0) ++ { ++ if(ifaces) + { + if(SLPIfaceSockaddrsToString(G_SlpdProperty.ifaceInfo.iface_addr, + G_SlpdProperty.ifaceInfo.iface_count, +@@ -137,39 +153,73 @@ int SLPDPropertyInit(const char* conffil + { + SLPPropertySet("net.slp.interfaces", myinterfaces); + xfree(myinterfaces); ++ ifaces = SLPPropertyGet("net.slp.interfaces"); + } + } + } +- G_SlpdProperty.interfaces = SLPPropertyGet("net.slp.interfaces"); + } +- G_SlpdProperty.interfacesLen = strlen(G_SlpdProperty.interfaces); +- ++ else ++ { ++ G_SlpdProperty.ifaceInfo.iface_count = SLP_MAX_IFACES; ++ if (SLPIfaceStringToSockaddrs(ifaces, G_SlpdProperty.ifaceInfo.iface_addr, &G_SlpdProperty.ifaceInfo.iface_count) != 0) ++ { ++ G_SlpdProperty.ifaceInfo.iface_count = 0; ++ } ++ } ++ G_SlpdProperty.interfaces = ifaces; ++ G_SlpdProperty.interfacesLen = ifaces ? strlen(ifaces) : 0; + ++ /*----------------------------*/ ++ /* Get out canonical hostname */ ++ /*----------------------------*/ ++ if(SLPNetGetThisHostname(&myname,0) == 0) ++ { ++ if (!myname && !G_SlpdProperty.myHostnameLen) ++ myname = xstrdup("127.0.0.1"); ++ if (myname) ++ { ++ SLPPropertySet("net.slp.myHostname",myname); ++ xfree(myname); ++ G_SlpdProperty.myHostname = SLPPropertyGet("net.slp.myHostname"); ++ G_SlpdProperty.myHostnameLen = strlen(G_SlpdProperty.myHostname); ++ } ++ } ++ + /*---------------------------------------------------------*/ + /* Set the value used internally as the url for this agent */ + /*---------------------------------------------------------*/ + /* 27 is the size of "service:directory-agent://(NULL)" */ + if(SLPNetGetThisHostname(&myname,1) == 0) + { +- myurl = (char*)xmalloc(27 + strlen(myname)); +- if(G_SlpdProperty.isDA) +- { +- strcpy(myurl,SLP_DA_SERVICE_TYPE); +- } +- else +- { +- strcpy(myurl,SLP_SA_SERVICE_TYPE); +- } +- strcat(myurl,"://"); +- strcat(myurl,myname); +- +- SLPPropertySet("net.slp.agentUrl",myurl); ++ if (!myname && !G_SlpdProperty.myUrlLen) ++ myname = xstrdup("127.0.0.1"); ++ if (myname) ++ { ++ if (!strncmp(myname, "127.", 4)) ++ { ++ /* cannot run as DA if hostname is loopback */ ++ G_SlpdProperty.isDA = 0; ++ } ++ myurl = (char*)xmalloc(27 + strlen(myname)); ++ if(G_SlpdProperty.isDA) ++ { ++ strcpy(myurl,SLP_DA_SERVICE_TYPE); ++ } ++ else ++ { ++ strcpy(myurl,SLP_SA_SERVICE_TYPE); ++ } ++ strcat(myurl,"://"); ++ strcat(myurl,myname); ++ ++ SLPPropertySet("net.slp.agentUrl",myurl); + +- G_SlpdProperty.myUrl = SLPPropertyGet("net.slp.agentUrl"); +- G_SlpdProperty.myUrlLen = strlen(G_SlpdProperty.myUrl); ++ G_SlpdProperty.myUrl = SLPPropertyGet("net.slp.agentUrl"); ++ G_SlpdProperty.myUrlLen = strlen(G_SlpdProperty.myUrl); + +- xfree(myurl); +- xfree(myname); ++ xfree(myurl); ++ xfree(myname); ++ } + } + + /*----------------------------------*/ +--- ./slpd/slpd_property.h.orig 2002-06-11 17:25:40.000000000 +0000 ++++ ./slpd/slpd_property.h 2006-11-16 16:19:30.000000000 +0000 +@@ -61,6 +61,8 @@ typedef struct _SLPDProperty + { + int myUrlLen; + const char* myUrl; ++ int myHostnameLen; ++ const char* myHostname; + int useScopesLen; + const char* useScopes; + int DAAddressesLen; +@@ -69,6 +71,7 @@ typedef struct _SLPDProperty + SLPIfaceInfo ifaceInfo; + int interfacesLen; + const char* interfaces; ++ int updateIfaces; + int localeLen; + const char* locale; + int isBroadcastOnly; +--- ./slpd/slpd_regfile.c.orig 2002-03-19 23:52:15.000000000 +0000 ++++ ./slpd/slpd_regfile.c 2006-11-16 16:19:30.000000000 +0000 +@@ -153,6 +153,7 @@ int SLPDRegFileReadSrvReg(FILE* fd, + { + char* slider1; + char* slider2; ++ char* p; + char line[4096]; + + struct sockaddr_in peer; +@@ -175,6 +176,8 @@ int SLPDRegFileReadSrvReg(FILE* fd, + unsigned char* attrauth = 0; + int attrauthlen = 0; + #endif ++ int watchport = 0; ++ int watchflags = 0; + + + /*-------------------------------------------*/ +@@ -212,6 +215,17 @@ int SLPDRegFileReadSrvReg(FILE* fd, + result = SLP_ERROR_INTERNAL_ERROR; + goto CLEANUP; + } ++ ++ /* replace "$HOSTNAME" string in url */ ++ while ((p = strchr(url, '$')) && !strncmp(p, "$HOSTNAME", 9)) ++ { ++ char *_url = (char*)malloc(strlen(url) - 9 + G_SlpdProperty.myHostnameLen + 1); ++ strncpy(_url, url, p - url); ++ strncpy(_url + (p - url), G_SlpdProperty.myHostname, G_SlpdProperty.myHostnameLen); ++ strcpy(_url + (p - url) + G_SlpdProperty.myHostnameLen, url + (p - url) + 9); ++ free(url); ++ url = _url; ++ } + urllen = strlen(url); + + /* derive srvtype from srvurl */ +@@ -349,6 +363,22 @@ int SLPDRegFileReadSrvReg(FILE* fd, + } + } + } ++ else if(strncasecmp(slider1,"tcp-port",8) == 0 || strncasecmp(slider1,"watch-port-tcp",14) == 0) ++ { ++ slider2 = strchr(slider1,'='); ++ if (slider2) { ++ watchport = atoi(slider2 + 1); ++ watchflags |= SLP_REG_WATCH_TCP; ++ } ++ } ++ else if(strncasecmp(slider1,"watch-port-udp",14) == 0) ++ { ++ slider2 = strchr(slider1,'='); ++ if (slider2) { ++ watchport = atoi(slider2 + 1); ++ watchflags |= SLP_REG_WATCH_UDP; ++ } ++ } + else + { + /* line contains an attribute (slow but it works)*/ +@@ -554,6 +584,8 @@ int SLPDRegFileReadSrvReg(FILE* fd, + peer.sin_addr.s_addr = htonl(LOOPBACK_ADDRESS); + result = SLPMessageParseBuffer(&peer,*buf,*msg); + (*msg)->body.srvreg.source = SLP_REG_SOURCE_STATIC; ++ (*msg)->body.srvreg.watchflags = watchflags ? (watchflags | SLP_REG_WATCH_DEAD) : 0; ++ (*msg)->body.srvreg.watchport = watchport; + + + CLEANUP: +--- ./slpd/slpd_socket.c.orig 2006-11-16 16:19:17.000000000 +0000 ++++ ./slpd/slpd_socket.c 2006-11-16 16:19:30.000000000 +0000 +@@ -412,6 +412,8 @@ SLPDSocket* SLPDSocketCreateBoundDatagra + sock->fd = socket(PF_INET, SOCK_DGRAM, 0); + if(sock->fd >=0) + { ++ if(myaddr != NULL) ++ sock->ifaddr.sin_addr = *myaddr; + if(BindSocketToInetAddr(sock->fd, bindaddr) == 0) + { + if(peeraddr != NULL) +@@ -479,6 +481,8 @@ SLPDSocket* SLPDSocketCreateListen(struc + sock->fd = socket(PF_INET, SOCK_STREAM, 0); + if(sock->fd >= 0) + { ++ if(peeraddr != NULL) ++ sock->ifaddr.sin_addr = *peeraddr; + if(BindSocketToInetAddr(sock->fd, peeraddr) >= 0) + { + if(listen(sock->fd,5) == 0) +--- ./slpd/slpd_socket.h.orig 2002-12-03 21:04:54.000000000 +0000 ++++ ./slpd/slpd_socket.h 2006-11-16 16:19:30.000000000 +0000 +@@ -97,6 +97,7 @@ typedef struct _SLPDSocket + int fd; + time_t age; /* in seconds */ + int state; ++ struct sockaddr_in ifaddr; /* address of interface */ + struct sockaddr_in peeraddr; + + /* Incoming socket stuff */ +--- ./slpd/slpd_spi.c.orig 2001-04-16 22:17:31.000000000 +0000 ++++ ./slpd/slpd_spi.c 2006-11-16 16:19:30.000000000 +0000 +@@ -68,6 +68,8 @@ int SLPDSpiInit(const char* spifile) + } + + G_SlpdSpiHandle = SLPSpiOpen(spifile,1); ++ if (G_SlpdSpiHandle) ++ SLPSpiFill(G_SlpdSpiHandle); + return (G_SlpdSpiHandle == 0); + } + +--- ./slptool/slptool.c.orig 2003-04-21 11:19:19.000000000 +0000 ++++ ./slptool/slptool.c 2006-11-16 16:47:44.000000000 +0000 +@@ -329,6 +329,20 @@ SLPBoolean mySrvUrlCallback( SLPHandle h + { + if(errcode == SLP_OK) + { ++ SLPToolCommandLine* cmdline = cookie; ++ if (cmdline->peerinfo) ++ { ++ char *peer = SLPGetPeer(hslp, srvurl); ++ if (peer) ++ { ++ printf("%s\t", peer); ++ SLPFree(peer); ++ } ++ else ++ { ++ printf("?\t"); ++ } ++ } + printf("%s,%i\n",srvurl,lifetime); + } + +@@ -350,7 +364,7 @@ void FindSrvs(SLPToolCommandLine* cmdlin + cmdline->scopes, + cmdline->cmdparam2, + mySrvUrlCallback, +- 0); ++ cmdline); + if(result != SLP_OK) + { + printf("errorcode: %i\n",result); +@@ -382,7 +396,7 @@ void FindSrvsUsingIFList(SLPToolCommandL + cmdline->scopes, + cmdline->cmdparam2, + mySrvUrlCallback, +- 0); ++ cmdline); + if(result != SLP_OK) + { + printf("errorcode: %i\n",result); +@@ -414,7 +428,7 @@ void UnicastFindSrvs(SLPToolCommandLine* + cmdline->scopes, + cmdline->cmdparam2, + mySrvUrlCallback, +- 0); ++ cmdline); + if(result != SLP_OK) + { + printf("errorcode: %i\n",result); +@@ -599,6 +613,11 @@ int ParseCommandLine(int argc,char* argv + return 1; + } + } ++ else if( strcasecmp(argv[i],"-p") == 0 || ++ strcasecmp(argv[i],"--peerinfo") == 0 ) ++ { ++ cmdline->peerinfo = SLP_TRUE; ++ } + else if(strcasecmp(argv[i],"findsrvs") == 0) + { + cmdline->cmd = FINDSRVS; +--- ./slptool/slptool.h.orig 2003-04-21 11:17:58.000000000 +0000 ++++ ./slptool/slptool.h 2006-11-16 16:19:30.000000000 +0000 +@@ -40,6 +40,8 @@ + #include + #include + #include ++#include ++#include + + /*=========================================================================*/ + typedef enum _SLPToolCommand +@@ -78,6 +80,7 @@ typedef struct _SLPToolCommandLine + const char* cmdparam1; + const char* cmdparam2; + const char* cmdparam3; ++ SLPBoolean peerinfo; + }SLPToolCommandLine; + + diff --git a/hppa.diff b/hppa.diff new file mode 100644 index 0000000..8ecd840 --- /dev/null +++ b/hppa.diff @@ -0,0 +1,11 @@ +--- configure.in 2004/06/13 12:17:00 1.1 ++++ configure.in 2004/06/13 12:17:19 +@@ -125,7 +125,7 @@ + CFLAGS="$CFLAGS -Werror" + fi + if test X"$debug" = X"no"; then +- OPTFLAGS="-O3" ++ OPTFLAGS="-O2" + fi + + elif $CC -V 2>&1 | grep "WorkShop Compilers"; then diff --git a/openslp-1.2.0.tar.bz2 b/openslp-1.2.0.tar.bz2 new file mode 100644 index 0000000..a66c429 --- /dev/null +++ b/openslp-1.2.0.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf2bbe9102405cdfee8f53d6893073ce7e6ccf0be803ca2399180ac0f6f7a178 +size 417994 diff --git a/openslp-devel.desktop b/openslp-devel.desktop new file mode 100644 index 0000000..a963667 --- /dev/null +++ b/openslp-devel.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Name=Open SLP Developer Guide +DocPath=/usr/share/doc/packages/openslp/html/ProgrammersGuide/index.html +X-DOC-SearchMethod=htdig diff --git a/openslp.audit.diff b/openslp.audit.diff new file mode 100644 index 0000000..783ad8d --- /dev/null +++ b/openslp.audit.diff @@ -0,0 +1,540 @@ +--- ./common/slp_dhcp.c.orig 2005-02-15 18:28:19.332759386 +0000 ++++ ./common/slp_dhcp.c 2005-02-15 18:30:52.797854324 +0000 +@@ -598,6 +598,7 @@ + cpysz = optdatasz < sizeof(ctxp->scopelist)? + optdatasz: sizeof(ctxp->scopelist); + strncpy(ctxp->scopelist, (char*)p, cpysz); ++ ctxp->scopelist[sizeof(ctxp->scopelist) - 1] = 0; + } + else + { +@@ -622,6 +623,7 @@ + cpysz = optdatasz < sizeof(ctxp->scopelist)? + optdatasz: sizeof(ctxp->scopelist); + strncpy(ctxp->scopelist, (char*)p, cpysz); ++ ctxp->scopelist[sizeof(ctxp->scopelist) - 1] = 0; + } + } + break; +--- ./common/slp_message.c.orig 2005-02-15 16:48:20.243994238 +0000 ++++ ./common/slp_message.c 2005-02-15 18:17:16.217402037 +0000 +@@ -68,6 +68,10 @@ + /* header (IN/OUT) pointer to the header structure to fill out */ + /*=========================================================================*/ + { ++ if (buffer->end - buffer->start < 2) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + header->version = *(buffer->curpos); + header->functionid = *(buffer->curpos + 1); + +@@ -75,6 +79,11 @@ + { + return SLP_ERROR_VER_NOT_SUPPORTED; + } ++ /* check for invalid length 18 bytes is the smallest v2 message*/ ++ if (buffer->end - buffer->start < 18) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + header->length = AsUINT24(buffer->curpos + 2); + header->flags = AsUINT16(buffer->curpos + 5); + header->encoding = 0; /* not used for SLPv2 */ +@@ -89,9 +98,7 @@ + return SLP_ERROR_PARSE_ERROR; + } + +- /* check for invalid length 18 bytes is the smallest v2 message*/ +- if(header->length != buffer->end - buffer->start || +- header->length < 18) ++ if(header->length != buffer->end - buffer->start) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -187,7 +194,7 @@ + /* parse out url */ + urlentry->urllen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(urlentry->urllen > buffer->end - buffer->curpos) ++ if(urlentry->urllen + 1 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -235,7 +242,7 @@ + /* parse the prlist */ + srvrqst->prlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvrqst->prlistlen > buffer->end - buffer->curpos) ++ if(srvrqst->prlistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -246,7 +253,7 @@ + /* parse the service type */ + srvrqst->srvtypelen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvrqst->srvtypelen > buffer->end - buffer->curpos) ++ if(srvrqst->srvtypelen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -257,7 +264,7 @@ + /* parse the scope list */ + srvrqst->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvrqst->scopelistlen > buffer->end - buffer->curpos) ++ if(srvrqst->scopelistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -269,7 +276,7 @@ + srvrqst->predicatever = 2; /* SLPv2 predicate (LDAPv3) */ + srvrqst->predicatelen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvrqst->predicatelen > buffer->end - buffer->curpos) ++ if(srvrqst->predicatelen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -358,10 +365,14 @@ + return result; + } + ++ if(buffer->end - buffer->curpos < 2) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + /* parse the service type */ + srvreg->srvtypelen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvreg->srvtypelen > buffer->end - buffer->curpos) ++ if(srvreg->srvtypelen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -372,7 +383,7 @@ + /* parse the scope list */ + srvreg->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvreg->scopelistlen > buffer->end - buffer->curpos) ++ if(srvreg->scopelistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -383,7 +394,7 @@ + /* parse the attribute list*/ + srvreg->attrlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvreg->attrlistlen > buffer->end - buffer->curpos) ++ if(srvreg->attrlistlen + 1 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -447,6 +458,10 @@ + } + + /* parse the tag list */ ++ if(buffer->end - buffer->curpos < 2) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + srvdereg->taglistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; + if(srvdereg->taglistlen > buffer->end - buffer->curpos) +@@ -482,7 +497,7 @@ + /* parse the prlist */ + attrrqst->prlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrqst->prlistlen > buffer->end - buffer->curpos) ++ if(attrrqst->prlistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -492,7 +507,7 @@ + /* parse the url */ + attrrqst->urllen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrqst->urllen > buffer->end - buffer->curpos) ++ if(attrrqst->urllen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -503,7 +518,7 @@ + /* parse the scope list */ + attrrqst->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrqst->scopelistlen > buffer->end - buffer->curpos) ++ if(attrrqst->scopelistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -514,7 +529,7 @@ + /* parse the taglist string */ + attrrqst->taglistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrqst->taglistlen > buffer->end - buffer->curpos) ++ if(attrrqst->taglistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -563,7 +578,7 @@ + /* parse out the attrlist */ + attrrply->attrlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrply->attrlistlen > buffer->end - buffer->curpos) ++ if(attrrply->attrlistlen + 1 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -619,13 +634,17 @@ + buffer->curpos = buffer->curpos + 2; + + /* parse out the bootstamp */ ++ if(buffer->end - buffer->curpos < 6) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + daadvert->bootstamp = AsUINT32(buffer->curpos); + buffer->curpos = buffer->curpos + 4; + + /* parse out the url */ + daadvert->urllen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(daadvert->urllen > buffer->end - buffer->curpos) ++ if(daadvert->urllen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -635,7 +654,7 @@ + /* parse the scope list */ + daadvert->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(daadvert->scopelistlen > buffer->end - buffer->curpos) ++ if(daadvert->scopelistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -645,7 +664,7 @@ + /* parse the attr list */ + daadvert->attrlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(daadvert->attrlistlen > buffer->end - buffer->curpos) ++ if(daadvert->attrlistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -655,7 +674,7 @@ + /* parse the SPI list */ + daadvert->spilistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(daadvert->spilistlen > buffer->end - buffer->curpos) ++ if(daadvert->spilistlen + 1 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -704,7 +723,7 @@ + /* parse out the url */ + saadvert->urllen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(saadvert->urllen > buffer->end - buffer->curpos) ++ if(saadvert->urllen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -714,7 +733,7 @@ + /* parse the scope list */ + saadvert->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(saadvert->scopelistlen > buffer->end - buffer->curpos) ++ if(saadvert->scopelistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -724,7 +743,7 @@ + /* parse the attr list */ + saadvert->attrlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(saadvert->attrlistlen > buffer->end - buffer->curpos) ++ if(saadvert->attrlistlen + 1 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -769,7 +788,7 @@ + /* parse the prlist */ + srvtyperqst->prlistlen = AsUINT16(buffer->curpos); + buffer->curpos += 2; +- if(srvtyperqst->prlistlen > buffer->end - buffer->curpos) ++ if(srvtyperqst->prlistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -794,6 +813,10 @@ + } + + /* parse the scope list */ ++ if(buffer->end - buffer->curpos < 2) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + srvtyperqst->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos += 2; + if(srvtyperqst->scopelistlen > buffer->end - buffer->curpos) +--- ./common/slp_network.c.orig 2005-02-15 17:48:00.831814261 +0000 ++++ ./common/slp_network.c 2005-02-15 17:51:29.856000181 +0000 +@@ -300,7 +300,7 @@ + /* EINVAL parse error */ + /*=========================================================================*/ + { +- int xferbytes; ++ int xferbytes, recvlen; + fd_set readfds; + char peek[16]; + int peeraddrlen = sizeof(struct sockaddr_in); +@@ -359,10 +359,14 @@ + /* Read the rest of the message */ + /*------------------------------*/ + /* check the version */ +- if(*peek == 2) ++ if(xferbytes >= 5 && *peek == 2) + { + /* allocate the recvmsg big enough for the whole message */ +- *buf = SLPBufferRealloc(*buf, AsUINT24(peek + 2)); ++ recvlen = AsUINT24(peek + 2); ++ /* one byte is minimum */ ++ if (recvlen <= 0) ++ recvlen = 1; ++ *buf = SLPBufferRealloc(*buf, recvlen); + if(*buf) + { + while((*buf)->curpos < (*buf)->end) +--- ./common/slp_v1message.c.orig 2005-02-15 16:52:12.613798586 +0000 ++++ ./common/slp_v1message.c 2005-02-15 18:26:47.632848004 +0000 +@@ -60,6 +60,11 @@ + /* SLP_ERROR_PARSE_ERROR. */ + /*=========================================================================*/ + { ++ if (buffer->end - buffer->start < 12) ++ { ++ /* invalid length 12 bytes is the smallest v1 message*/ ++ return SLP_ERROR_PARSE_ERROR; ++ } + header->version = *(buffer->curpos); + header->functionid = *(buffer->curpos + 1); + +@@ -85,10 +90,8 @@ + return SLP_ERROR_CHARSET_NOT_UNDERSTOOD; + } + +- if(header->length != buffer->end - buffer->start || +- header->length < 12) ++ if(header->length != buffer->end - buffer->start) + { +- /* invalid length 12 bytes is the smallest v1 message*/ + return SLP_ERROR_PARSE_ERROR; + } + +@@ -114,7 +117,7 @@ + int result; + + /* make sure that min size is met */ +- if(buffer->end - buffer->curpos < 6) ++ if(buffer->end - buffer->curpos < 4) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -160,7 +163,7 @@ + int result; + + /* make sure that min size is met */ +- if(buffer->end - buffer->curpos < 10) ++ if(buffer->end - buffer->curpos < 4) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -168,7 +171,7 @@ + /* parse the prlist */ + srvrqst->prlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(srvrqst->prlistlen > buffer->end - buffer->curpos) ++ if(srvrqst->prlistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -272,6 +275,10 @@ + srvreg->srvtypelen = tmp - srvreg->srvtype; + + /* parse the attribute list */ ++ if(buffer->end - buffer->curpos < 2) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + srvreg->attrlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; + if(srvreg->attrlistlen > buffer->end - buffer->curpos) +@@ -335,7 +342,7 @@ + srvdereg->urlentry.lifetime = 0; /* not present in SLPv1 */ + srvdereg->urlentry.urllen = AsUINT16(buffer->curpos); + buffer->curpos += 2; +- if(srvdereg->urlentry.urllen > buffer->end - buffer->curpos) ++ if(srvdereg->urlentry.urllen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -381,7 +388,7 @@ + /* parse the prlist */ + attrrqst->prlistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrqst->prlistlen > buffer->end - buffer->curpos) ++ if(attrrqst->prlistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -396,7 +403,7 @@ + /* parse the url */ + attrrqst->urllen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrqst->urllen > buffer->end - buffer->curpos) ++ if(attrrqst->urllen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -411,7 +418,7 @@ + /* parse the scope list */ + attrrqst->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos = buffer->curpos + 2; +- if(attrrqst->scopelistlen > buffer->end - buffer->curpos) ++ if(attrrqst->scopelistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -469,7 +476,7 @@ + /* parse the prlist */ + srvtyperqst->prlistlen = AsUINT16(buffer->curpos); + buffer->curpos += 2; +- if(srvtyperqst->prlistlen > buffer->end - buffer->curpos) ++ if(srvtyperqst->prlistlen + 2 > buffer->end - buffer->curpos) + { + return SLP_ERROR_PARSE_ERROR; + } +@@ -504,6 +511,10 @@ + } + + /* parse the scope list */ ++ if(buffer->end - buffer->curpos < 2) ++ { ++ return SLP_ERROR_PARSE_ERROR; ++ } + srvtyperqst->scopelistlen = AsUINT16(buffer->curpos); + buffer->curpos += 2; + if(srvtyperqst->scopelistlen > buffer->end - buffer->curpos) +--- ./libslp/libslp_parse.c.orig 2005-02-15 18:39:01.505072256 +0000 ++++ ./libslp/libslp_parse.c 2005-02-15 18:41:21.510075488 +0000 +@@ -168,7 +168,10 @@ + if((isTag) && strchr(ATTRIBUTE_BAD_TAG, *current_inbuf)) + return(SLP_PARSE_ERROR); + +- if(strchr(ATTRIBUTE_RESERVE_STRING, *current_inbuf)) ++ if((strchr(ATTRIBUTE_RESERVE_STRING, *current_inbuf)) || ++ ((*current_inbuf >= 0x00) && (*current_inbuf <= 0x1F)) || ++ (*current_inbuf == 0x7F) ++ ) + amount_of_escape_characters++; + + current_inbuf++; +--- ./slpd/slpd_incoming.c.orig 2005-02-15 17:01:07.456383345 +0000 ++++ ./slpd/slpd_incoming.c 2005-02-15 17:47:18.244888341 +0000 +@@ -189,13 +189,16 @@ + MSG_PEEK, + (struct sockaddr *)&(sock->peeraddr), + &peeraddrlen); +- if (bytesread > 0) ++ if (bytesread > 0 && bytesread >= (*peek == 2 ? 5 : 4)) + { + + if (*peek == 2) + recvlen = AsUINT24(peek + 2); + else if (*peek == 1) /* SLPv1 packet */ + recvlen = AsUINT16(peek + 2); ++ /* one byte is minimum */ ++ if (recvlen <= 0) ++ recvlen = 1; + /* allocate the recvbuf big enough for the whole message */ + sock->recvbuf = SLPBufferRealloc(sock->recvbuf,recvlen); + if (sock->recvbuf) +@@ -249,7 +252,7 @@ + } + else + { +- /* error in recv() */ ++ /* error in recv() or eof */ + sock->state = SOCKET_CLOSE; + } + } +--- ./slpd/slpd_outgoing.c.orig 2005-02-15 17:29:22.366303963 +0000 ++++ ./slpd/slpd_outgoing.c 2005-02-15 17:46:47.727240947 +0000 +@@ -190,7 +190,7 @@ + void OutgoingStreamRead(SLPList* socklist, SLPDSocket* sock) + /*-------------------------------------------------------------------------*/ + { +- int bytesread; ++ int bytesread, recvlen; + char peek[16]; + int peeraddrlen = sizeof(struct sockaddr_in); + +@@ -205,10 +205,14 @@ + MSG_PEEK, + (struct sockaddr *)&(sock->peeraddr), + &peeraddrlen); +- if ( bytesread > 0 ) ++ if ( bytesread >= 5 && *peek == 2 ) + { ++ recvlen = AsUINT24(peek + 2); ++ /* one byte is minimum */ ++ if (recvlen <= 0) ++ recvlen = 1; + /* allocate the recvbuf big enough for the whole message */ +- sock->recvbuf = SLPBufferRealloc(sock->recvbuf,AsUINT24(peek+2)); ++ sock->recvbuf = SLPBufferRealloc(sock->recvbuf, recvlen); + if ( sock->recvbuf ) + { + sock->state = STREAM_READ; +@@ -219,7 +223,7 @@ + sock->state = SOCKET_CLOSE; + } + } +- else ++ else if ( bytesread == -1 ) + { + #ifdef _WIN32 + if ( WSAEWOULDBLOCK != WSAGetLastError() ) +@@ -232,6 +236,10 @@ + OutgoingStreamReconnect(socklist,sock); + } + } ++ else ++ { ++ sock->state = SOCKET_CLOSE; ++ } + } + + if ( sock->state == STREAM_READ ) +--- ./slpd/slpd_v1process.c.orig 2005-02-15 17:05:42.710057099 +0000 ++++ ./slpd/slpd_v1process.c 2005-02-15 17:29:06.518563216 +0000 +@@ -808,11 +808,16 @@ + { + /* SLPv1 messages are handled only by DAs */ + errorcode = SLP_ERROR_VER_NOT_SUPPORTED; ++ return errorcode; + } + + /* Parse just the message header the reset the buffer "curpos" pointer */ + recvbuf->curpos = recvbuf->start; + errorcode = SLPv1MessageParseHeader(recvbuf, &header); ++ if (errorcode != 0) ++ { ++ return errorcode; ++ } + + /* TRICKY: Duplicate SRVREG recvbufs *before* parsing them */ + /* it because we are going to keep them in the */ diff --git a/openslp.changes b/openslp.changes new file mode 100644 index 0000000..9ef5ffb --- /dev/null +++ b/openslp.changes @@ -0,0 +1,258 @@ +------------------------------------------------------------------- +Thu Nov 16 17:13:01 CET 2006 - mls@suse.de + +- truncate oversized udp messages, finally fixes [#185483] + (can be turned of with "net.slp.oversizedUDP" option) +- do not try to send back empty answers +- add option "net.slp.allowDoubleEqualInPredicate" to make openslp + work with some buggy clients that use "==" for comparison [#95043] +- changed SLPGetPeer interface to support IPv6 + +------------------------------------------------------------------- +Tue Sep 12 15:23:43 CEST 2006 - mls@suse.de + +- obey OVERFLOW bit of incoming udp messages [#185483] +- use right length in send() calls [#185483] +- fix errno check in IncomingStreamWrite +- add SLPGetPeer method in libslp +- add --peerinfo option to slptool to print peerinfo + +------------------------------------------------------------------- +Wed May 10 20:41:30 CEST 2006 - mls@suse.de + +- fix unaligned memory access on ia64 [#171932] + +------------------------------------------------------------------- +Fri Mar 24 14:23:39 CET 2006 - mls@suse.de + +- fix listening on multiple interfaces [#160008] + +------------------------------------------------------------------- +Sat Mar 18 03:33:51 CET 2006 - schwab@suse.de + +- Fix file descritor leak [#159303]. + +------------------------------------------------------------------- +Mon Jan 30 16:35:37 CET 2006 - mls@suse.de + +- fix bug in DropSLPMulticastGroup +- add -fstack-protector to CFLAGS +- added logrotate script [#143069] + +------------------------------------------------------------------- +Wed Jan 25 21:30:39 CET 2006 - mls@suse.de + +- converted neededforbuild to BuildRequires + +------------------------------------------------------------------- +Fri Dec 23 15:41:12 CET 2005 - mls@suse.de + +- clear overflow bit on TCP connections [#135248] + +------------------------------------------------------------------- +Thu Sep 29 03:15:17 CEST 2005 - dmueller@suse.de + + - add norootforbuild + +------------------------------------------------------------------- +Mon Aug 22 19:31:23 CEST 2005 - mls@suse.de + +- also listen on SLPv1 General Multicast address [#64138] +- use poll instead of select [#65673] + +------------------------------------------------------------------- +Tue Feb 15 19:52:01 CET 2005 - mls@suse.de + +- update to version 1.2.0 +- fixed security audit findings +- disable mdns in slpd for now, libslp still supports it + +------------------------------------------------------------------- +Fri Dec 3 12:39:40 CET 2004 - mls@suse.de + +- fix slpv DA discovery scope handling (#48728) +- use _dns-sd instead of _mdns in mdns findsrvtypes query (#48325) + +------------------------------------------------------------------- +Thu Oct 14 13:55:00 CEST 2004 - adrian@suse.de + +- add meta information for suse help. + +------------------------------------------------------------------- +Sun Jun 13 14:27:28 CEST 2004 - bg@suse.de + +- reduce hardcoded optimization from -O3 to -O2 to circumvent + ICE on hppa + +------------------------------------------------------------------- +Tue Jun 1 16:17:17 CEST 2004 - mls@suse.de + +- added fillup and insserv prereq + +------------------------------------------------------------------- +Thu May 27 14:30:41 CEST 2004 - mls@suse.de + +- use /proc/net/tcp_listen and /proc/net/tcp6_listen if + available to keep things fast on systems with lots of + network connections [#40888] + +------------------------------------------------------------------- +Wed May 5 20:08:02 CEST 2004 - mls@suse.de + +- treat empty attributes as illegal [#39669] +- always start slpd on SLES [#39863] + +------------------------------------------------------------------- +Fri Apr 23 12:04:20 CEST 2004 - mls@suse.de + +- libslp: use configured TTL settings [#39030] + +------------------------------------------------------------------- +Fri Apr 2 12:17:42 CEST 2004 - mls@suse.de + +- beta is over, don't always start slpd + +------------------------------------------------------------------- +Fri Apr 2 09:18:03 CEST 2004 - kukuk@suse.de + +- Fix init script + +------------------------------------------------------------------- +Wed Mar 31 13:03:35 CEST 2004 - mls@suse.de + +- fix sighup processing +- clean up spi code +- fix spi null pointer reference +- fix namingauth comparison +- added try-restart to rcslpd +- fix slp.conf re-read +- fix prlist buffer overrun + +------------------------------------------------------------------- +Mon Mar 29 14:58:00 CEST 2004 - mls@suse.de + +- turn around srvtypes order in mdns + +------------------------------------------------------------------- +Thu Mar 18 17:12:34 CET 2004 - mls@suse.de + +- code cleanup +- provide A RR with SRV RRs +- don't pack .xvpics + +------------------------------------------------------------------- +Fri Mar 12 15:48:09 CET 2004 - mls@suse.de + +- added missing SLPGetMDNSName prototype to slp.h + +------------------------------------------------------------------- +Fri Mar 12 12:38:38 CET 2004 - mls@suse.de + +- slpd: fix hostname detection segfault +- slpd: use ttl 255 for mdns +- slpd: put attrs in mdns TXT RR +- libslp: check mdns ttl +- libslp: make getattr work with mdns +- libslp: make mdns name available via new SLPGetMDNSName() function + +------------------------------------------------------------------- +Thu Mar 4 18:45:35 CET 2004 - mls@suse.de + +- libslp: add scope/nameingauth/predicate to query +- slpd: reply to mdns service requests +- slpd: don't play DA if our hostname expands to loopback +- slpd: fix null pointer reference if SrvReg request is sent + over tcp (as done by apple) + +------------------------------------------------------------------- +Fri Feb 27 18:07:46 CET 2004 - mls@suse.de + +- slpd: check port status every 15 seconds for watch-port-tcp/udp + entries +- libslp: send MDNS queries for scope _mdns + +------------------------------------------------------------------- +Sun Feb 15 18:17:19 CET 2004 - adrian@suse.de + +- export full qualified hostnames for $HOSTNAME +- replace several $HOSTNAME tags in a srvurl +- do only accept .reg files (no .rpmsave for instance) + +------------------------------------------------------------------- +Sat Feb 14 01:33:22 CET 2004 - adrian@suse.de + +- fix /proc/net/tcp* parsing +- ONLY FOR BETA: start slpd always + +------------------------------------------------------------------- +Thu Jan 29 13:59:26 CET 2004 - adrian@suse.de + +- fix reading from slpd.reg.d directory + (was broken since chroot run) + +------------------------------------------------------------------- +Wed Jan 14 13:42:41 CET 2004 - adrian@suse.de + +- slptool register now services with max timeout. + +------------------------------------------------------------------- +Tue Dec 16 09:14:12 CET 2003 - adrian@suse.de + +- fix sig11 when using the library without spi file + +------------------------------------------------------------------- +Mon Dec 8 12:06:21 CET 2003 - adrian@suse.de + +- security enhancements: + * use chroot and open needed file descriptors before + * panic if chroot or setuid fails + * pid-file= option in reg files is useless now, so + tcp-port= must be used for this now +- add SSL support again + +------------------------------------------------------------------- +Wed Nov 26 15:53:52 CET 2003 - adrian@suse.de + +- add buffer fix from cvs +- add README.SuSE with config howto + +------------------------------------------------------------------- +Thu Nov 20 13:06:13 CET 2003 - adrian@suse.de + +- drop the multicast route creation in runlevel script. + we do not need it anymore with 1.1.5 + +------------------------------------------------------------------- +Wed Nov 19 16:45:08 CET 2003 - adrian@suse.de + +- update to version 1.1.5 + * development version, but it contains lots of fixes +- use $HOSTNAME instead of $LOCALHOST in reg files + +------------------------------------------------------------------- +Fri Nov 14 10:53:01 CET 2003 - adrian@suse.de + +- use correct keyword "X-UnitedLinux-Should-Start" in init script + (seen by Martin Vidner) + +------------------------------------------------------------------- +Thu Nov 13 22:58:49 CET 2003 - adrian@suse.de + +- add "tcp-port=" option to test services running via (x)inted +- start after (x)inetd + +------------------------------------------------------------------- +Wed Nov 12 13:28:17 CET 2003 - adrian@suse.de + +- add code to parse .reg files from any package below /etc/slp.reg.d/ + +------------------------------------------------------------------- +Sun Nov 9 23:26:04 CET 2003 - adrian@suse.de + +- fix security issue in init script + +------------------------------------------------------------------- +Sat Nov 8 17:56:38 CET 2003 - adrian@suse.de + +- initial package of version 1.0.11 + diff --git a/openslp.checkovr.diff b/openslp.checkovr.diff new file mode 100644 index 0000000..b15457e --- /dev/null +++ b/openslp.checkovr.diff @@ -0,0 +1,57 @@ +--- ./common/slp_xcast.c.orig 2006-06-20 14:52:11.000000000 +0000 ++++ ./common/slp_xcast.c 2006-06-26 10:08:42.000000000 +0000 +@@ -75,6 +75,7 @@ + + #include "slp_xcast.h" + #include "slp_message.h" ++#include "slp_v1message.h" + #include "slp_property.h" + + /*========================================================================*/ +@@ -354,14 +355,26 @@ int SLPXcastRecvMessage(const SLPXcastSo + #endif + ) + { +- if(AsUINT24(peek + 2) <= SLP_MAX_DATAGRAM_SIZE) ++ int ovlbit; ++ size_t size; ++ if (peek[0] == 1) + { +- *buf = SLPBufferRealloc(*buf, AsUINT24(peek + 2)); ++ size = AsUINT16(peek + 2); ++ ovlbit = peek[4] & SLPv1_FLAG_OVERFLOW; ++ } ++ else ++ { ++ size = AsUINT24(peek + 2); ++ ovlbit = peek[5] & (SLP_FLAG_OVERFLOW >> 8); ++ } ++ if(size <= SLP_MAX_DATAGRAM_SIZE && !ovlbit) ++ { ++ *buf = SLPBufferRealloc(*buf, size); + bytesread = recv(sockets->sock[i], + (*buf)->curpos, + (*buf)->end - (*buf)->curpos, + 0); +- if(bytesread != AsUINT24(peek + 2)) ++ if(bytesread != size) + { + /* This should never happen but we'll be paranoid*/ + (*buf)->end = (*buf)->curpos + bytesread; +@@ -377,12 +390,14 @@ int SLPXcastRecvMessage(const SLPXcastSo + /* we got a bad message, or one that is too big! */ + #ifndef UNICAST_NOT_SUPPORTED + /* Reading SLP_MAX_DATAGRAM_SIZE bytes on the socket */ +- *buf = SLPBufferRealloc(*buf, SLP_MAX_DATAGRAM_SIZE); ++ if (size > SLP_MAX_DATAGRAM_SIZE) ++ size = SLP_MAX_DATAGRAM_SIZE; ++ *buf = SLPBufferRealloc(*buf, size); + bytesread = recv(sockets->sock[i], + (*buf)->curpos, + (*buf)->end - (*buf)->curpos, + 0); +- if(bytesread != SLP_MAX_DATAGRAM_SIZE) ++ if(bytesread != size) + { + /* This should never happen but we'll be paranoid*/ + (*buf)->end = (*buf)->curpos + bytesread; diff --git a/openslp.desktop b/openslp.desktop new file mode 100644 index 0000000..e4fef1a --- /dev/null +++ b/openslp.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Name=Open SLP User Guide +DocPath=/usr/share/doc/packages/openslp/html/UsersGuide/index.html +X-DOC-SearchMethod=htdig diff --git a/openslp.diff b/openslp.diff new file mode 100644 index 0000000..cf08f64 --- /dev/null +++ b/openslp.diff @@ -0,0 +1,136 @@ +--- ./common/slp_iface.c.orig 2006-09-12 13:17:00.000000000 +0000 ++++ ./common/slp_iface.c 2006-09-12 13:17:08.000000000 +0000 +@@ -128,6 +128,7 @@ int SLPIfaceGetInfo(const char* useiface + #endif + { + perror("ioctl failed"); ++ close(fd); + return 1; + } + +@@ -183,6 +184,7 @@ int SLPIfaceGetInfo(const char* useiface + } + } + ++ close(fd); + return 0; + } + #else +--- ./common/slp_net.c.orig 2006-09-12 13:17:00.000000000 +0000 ++++ ./common/slp_net.c 2006-09-12 13:17:08.000000000 +0000 +@@ -92,7 +92,7 @@ int SLPNetGetThisHostname(char** hostfdn + } + else + { +- ifaddr.s_addr = *((unsigned long*)he->h_addr); ++ ifaddr = *((struct in_addr *)he->h_addr); + *hostfdn = xstrdup(inet_ntoa(ifaddr)); + } + +--- ./common/slp_spi.c.orig 2006-09-12 13:17:00.000000000 +0000 ++++ ./common/slp_spi.c 2006-09-12 13:17:08.000000000 +0000 +@@ -267,9 +267,9 @@ SLPSpiHandle SLPSpiOpen(const char* spif + fp = fopen(spifile,"r"); + if(fp) + { +- result = xmalloc(sizeof(structSLPSpiHandle)); ++ result = xmalloc(sizeof(struct _SLPSpiHandle)); + if(result == 0) return 0; +- memset(result, 0, sizeof(structSLPSpiHandle)); ++ memset(result, 0, sizeof(struct _SLPSpiHandle)); + + result->spifile = xstrdup(spifile); + result->cacheprivate = cacheprivate; +--- ./configure.in.orig 2006-09-12 13:17:00.000000000 +0000 ++++ ./configure.in 2006-09-12 13:17:08.000000000 +0000 +@@ -171,5 +171,12 @@ AC_CHECK_LIB(socket, main) + AC_CHECK_LIB(nsl, gethostbyname) + AC_CHECK_LIB(m, main) + AC_CHECK_FUNCS(ceil log10 strncasecmp strcasecmp ) +-AC_OUTPUT(Makefile common/Makefile libslpattr/Makefile libslp/Makefile \ +- slpd/Makefile slptool/Makefile test/Makefile slp.list) ++AC_CONFIG_FILES([ Makefile ]) ++AC_CONFIG_FILES([ common/Makefile ]) ++AC_CONFIG_FILES([ libslpattr/Makefile ]) ++AC_CONFIG_FILES([ libslp/Makefile ]) ++AC_CONFIG_FILES([ slpd/Makefile ]) ++AC_CONFIG_FILES([ slptool/Makefile ]) ++AC_CONFIG_FILES([ test/Makefile ]) ++AC_CONFIG_FILES([ slp.list ]) ++AC_OUTPUT +--- ./etc/slp.reg.orig 2006-09-12 13:17:00.000000000 +0000 ++++ ./etc/slp.reg 2006-09-12 13:17:08.000000000 +0000 +@@ -37,3 +37,10 @@ + ##Register telnet service with no attributes + #service:telnet.myorg://192.168.100.1,en,65535 + #use default scopes ++ ++##Register vnc kdm service, can be used via krdc ++#service:remotedesktop.kde:vnc://192.168.100.1:1,en,65535 ++#attrid=(type=shared),(username=joe),(fullname=Joe User),(serviceid=1235456) ++#description=KDE remote login ++ ++ +--- ./slpd/slpd_incoming.c.orig 2006-09-12 13:17:00.000000000 +0000 ++++ ./slpd/slpd_incoming.c 2006-09-12 13:19:18.000000000 +0000 +@@ -137,11 +137,11 @@ void IncomingStreamWrite(SLPList* sockli + sock->state = STREAM_WRITE; + } + +- if (sock->sendbuf->end - sock->sendbuf->start != 0) ++ if (sock->sendbuf->end - sock->sendbuf->curpos != 0) + { + byteswritten = send(sock->fd, + sock->sendbuf->curpos, +- sock->sendbuf->end - sock->sendbuf->start, ++ sock->sendbuf->end - sock->sendbuf->curpos, + flags); + if (byteswritten > 0) + { +@@ -157,9 +157,9 @@ void IncomingStreamWrite(SLPList* sockli + else + { + #ifdef _WIN32 +- if (WSAEWOULDBLOCK == WSAGetLastError()) ++ if (WSAEWOULDBLOCK != WSAGetLastError()) + #else +- if (errno == EWOULDBLOCK) ++ if (errno != EWOULDBLOCK) + #endif + { + /* Error occured or connection was closed */ +@@ -516,6 +516,7 @@ int SLPDIncomingInit() + /* Create socket that will handle multicast UDP. */ + /*----------------------------------------------------------------*/ + ++ mcastaddr.s_addr = htonl(SLP_MCAST_ADDRESS); + sock = SLPDSocketCreateBoundDatagram(&myaddr, + &mcastaddr, + DATAGRAM_MULTICAST); +--- ./slpd/slpd_outgoing.c.orig 2002-12-03 21:04:54.000000000 +0000 ++++ ./slpd/slpd_outgoing.c 2006-09-12 13:19:47.000000000 +0000 +@@ -328,11 +328,11 @@ void OutgoingStreamWrite(SLPList* sockli + sock->state = STREAM_WRITE; + } + +- if ( sock->sendbuf->end - sock->sendbuf->start > 0 ) ++ if ( sock->sendbuf->end - sock->sendbuf->curpos > 0 ) + { + byteswritten = send(sock->fd, + sock->sendbuf->curpos, +- sock->sendbuf->end - sock->sendbuf->start, ++ sock->sendbuf->end - sock->sendbuf->curpos, + flags); + if ( byteswritten > 0 ) + { +--- ./slpd/slpd_socket.c.orig 2006-09-12 13:17:00.000000000 +0000 ++++ ./slpd/slpd_socket.c 2006-09-12 13:17:08.000000000 +0000 +@@ -183,7 +183,7 @@ int DropSLPMulticastGroup(sockfd_t sockf + memcpy(&mreq.imr_multiaddr, maddr, sizeof(struct in_addr)); + + /* drop for the specified interface */ +- memcpy(&mreq.imr_interface,addr,sizeof(addr)); ++ memcpy(&mreq.imr_interface,addr,sizeof(struct in_addr)); + + return setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&mreq,sizeof(mreq)); + } diff --git a/openslp.doubleequal.diff b/openslp.doubleequal.diff new file mode 100644 index 0000000..52430e4 --- /dev/null +++ b/openslp.doubleequal.diff @@ -0,0 +1,59 @@ +--- slpd/slpd_predicate.c.orig 2006-11-16 12:40:22.000000000 +0100 ++++ slpd/slpd_predicate.c 2006-11-16 12:45:22.000000000 +0100 +@@ -78,10 +78,11 @@ + *********/ + + #include +-#include ++#include + #include + + #include "slpd_predicate.h" ++#include "slpd_property.h" + + #include "../libslpattr/libslpattr.h" + #include "../libslpattr/libslpattr_internal.h" +@@ -1389,6 +1390,10 @@ + } + } + ++ if (op == EQUAL && G_SlpdProperty.allowDoubleEqualInPredicate && operator[1] == '=') ++ { ++ val_start++; ++ } + + /***** Get operands. *****/ + /**** Left. ****/ +--- slpd/slpd_property.h.orig2 2006-11-16 12:43:26.000000000 +0100 ++++ slpd/slpd_property.h 2006-11-16 12:43:48.000000000 +0100 +@@ -95,6 +95,7 @@ + int checkSourceAddr; + int DAHeartBeat; + int oversizedUDP; ++ int allowDoubleEqualInPredicate; + }SLPDProperty; + + +--- slpd/slpd_property.c.orig2 2006-11-16 12:42:24.000000000 +0100 ++++ slpd/slpd_property.c 2006-11-16 12:43:11.000000000 +0100 +@@ -132,6 +132,7 @@ + G_SlpdProperty.checkSourceAddr = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.checkSourceAddr")); + G_SlpdProperty.DAHeartBeat = SLPPropertyAsInteger(SLPPropertyGet("net.slp.DAHeartBeat")); + G_SlpdProperty.oversizedUDP = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.oversizedUDP")); ++ G_SlpdProperty.allowDoubleEqualInPredicate = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.allowDoubleEqualInPredicate")); + + + /*-------------------------------------*/ +--- test/SLPD_predicate_test/slpd_predicate_test.c.orig 2006-11-16 13:09:05.000000000 +0100 ++++ test/SLPD_predicate_test/slpd_predicate_test.c 2006-11-16 13:10:31.000000000 +0100 +@@ -5,6 +5,10 @@ + + #ifdef ENABLE_PREDICATES + ++#include ++ ++SLPDProperty G_SlpdProperty; ++ + typedef void* SLPDPredicate; + int SLPDPredicateTest(SLPDPredicate predicate, SLPAttributes attr); + diff --git a/openslp.emptyanswer.diff b/openslp.emptyanswer.diff new file mode 100644 index 0000000..45aae17 --- /dev/null +++ b/openslp.emptyanswer.diff @@ -0,0 +1,20 @@ +--- slpd/slpd_incoming.c.orig 2006-11-16 12:19:04.000000000 +0100 ++++ slpd/slpd_incoming.c 2006-11-16 12:22:00.000000000 +0100 +@@ -251,10 +251,16 @@ + sock->state = SOCKET_CLOSE; + break; + default: ++ if (!sock->sendbuf || sock->sendbuf->end == sock->sendbuf->start) ++ { ++ /* no answer available, just close socket */ ++ sock->state = SOCKET_CLOSE; ++ break; ++ } + /* some clients cannot cope with the OVERFLOW + * bit set on a TCP stream, so always clear it + */ +- if (sock->sendbuf && sock->sendbuf->end - sock->sendbuf->start > 5) ++ if (sock->sendbuf->end - sock->sendbuf->start > 5) + { + if (sock->sendbuf->start[0] == 1) + sock->sendbuf->start[4] &= ~SLPv1_FLAG_OVERFLOW; diff --git a/openslp.logrotate b/openslp.logrotate new file mode 100644 index 0000000..6769c83 --- /dev/null +++ b/openslp.logrotate @@ -0,0 +1,14 @@ +/var/log/slpd.log { + compress + dateext + maxage 14 + rotate 99 + size +1024k + notifempty + missingok + create 600 root root + sharedscripts + postrotate + /etc/init.d/slpd restart + endscript +} diff --git a/openslp.poll.diff b/openslp.poll.diff new file mode 100644 index 0000000..cc061c1 --- /dev/null +++ b/openslp.poll.diff @@ -0,0 +1,853 @@ +--- ./common/slp_dhcp.c.orig 2005-08-22 17:24:56.813080069 +0000 ++++ ./common/slp_dhcp.c 2005-08-22 17:25:15.753392664 +0000 +@@ -69,6 +69,9 @@ + #include + #include + #endif ++#ifdef HAVE_POLL ++#include ++#endif + + #include + #include +@@ -166,7 +169,11 @@ static int dhcpSendRequest(int sockfd, v + ETIMEDOUT read timed out + =========================================================================*/ + { ++#ifdef HAVE_POLL ++ struct pollfd writefd; ++#else + fd_set writefds; ++#endif + int xferbytes; + int flags = 0; + +@@ -174,10 +181,17 @@ static int dhcpSendRequest(int sockfd, v + flags = MSG_NOSIGNAL; + #endif + ++#ifdef HAVE_POLL ++ writefd.fd = sockfd; ++ writefd.events = POLLOUT; ++ writefd.revents = 0; ++ xferbytes = poll(&writefd, 1, timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1); ++#else + FD_ZERO(&writefds); + FD_SET(sockfd, &writefds); +- +- if((xferbytes = select(sockfd + 1, 0, &writefds, 0, timeout)) > 0) ++ xferbytes = select(sockfd + 1, 0, &writefds, 0, timeout); ++#endif ++ if(xferbytes > 0) + { + if((xferbytes = sendto(sockfd, (char*)buf, (int)bufsz, flags, + peeraddr, sizeof(struct sockaddr_in))) <= 0) +@@ -214,12 +228,23 @@ static int dhcpRecvResponse(int sockfd, + =========================================================================*/ + { + int xferbytes; ++#ifdef HAVE_POLL ++ struct pollfd readfd; ++#else + fd_set readfds; ++#endif + ++#ifdef HAVE_POLL ++ readfd.fd = sockfd; ++ readfd.events = POLLIN; ++ readfd.revents = 0; ++ xferbytes = poll(&readfd, 1, timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1); ++#else + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); +- +- if((xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout)) > 0) ++ xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout); ++#endif ++ if(xferbytes > 0) + { + if((xferbytes = recvfrom(sockfd, (char*)buf, (int)bufsz, 0, 0, 0)) <= 0) + { +--- ./common/slp_network.c.orig 2005-08-22 17:24:56.814079927 +0000 ++++ ./common/slp_network.c 2005-08-22 17:25:15.754392523 +0000 +@@ -221,7 +221,11 @@ int SLPNetworkSendMessage(int sockfd, + /* ETIME read timed out */ + /*=========================================================================*/ + { ++#ifdef HAVE_POLL ++ struct pollfd writefd; ++#else + fd_set writefds; ++#endif + int xferbytes; + int flags = 0; + +@@ -233,10 +237,17 @@ int SLPNetworkSendMessage(int sockfd, + + while(buf->curpos < buf->end) + { ++#ifdef HAVE_POLL ++ writefd.fd = sockfd; ++ writefd.events = POLLOUT; ++ writefd.revents = 0; ++ xferbytes = poll(&writefd, 1, timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1); ++#else + FD_ZERO(&writefds); + FD_SET(sockfd, &writefds); + + xferbytes = select(sockfd + 1, 0, &writefds, 0, timeout); ++#endif + if(xferbytes > 0) + { + if(socktype == SOCK_DGRAM) +@@ -301,16 +312,27 @@ int SLPNetworkRecvMessage(int sockfd, + /*=========================================================================*/ + { + int xferbytes, recvlen; ++#ifdef HAVE_POLL ++ struct pollfd readfd; ++#else + fd_set readfds; ++#endif + char peek[16]; + int peeraddrlen = sizeof(struct sockaddr_in); + + /*---------------------------------------------------------------*/ + /* take a peek at the packet to get version and size information */ + /*---------------------------------------------------------------*/ ++#ifdef HAVE_POLL ++ readfd.fd = sockfd; ++ readfd.events = POLLIN; ++ readfd.revents = 0; ++ xferbytes = poll(&readfd, 1, timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1); ++#else + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); + xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout); ++#endif + if(xferbytes > 0) + { + if(socktype == SOCK_DGRAM) +@@ -371,9 +393,16 @@ int SLPNetworkRecvMessage(int sockfd, + { + while((*buf)->curpos < (*buf)->end) + { ++#ifdef HAVE_POLL ++ readfd.fd = sockfd; ++ readfd.events = POLLIN; ++ readfd.revents = 0; ++ xferbytes = poll(&readfd, 1, timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1); ++#else + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); + xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout); ++#endif + if(xferbytes > 0) + { + xferbytes = recv(sockfd, +--- ./common/slp_network.h.orig 2005-08-22 17:24:56.815079785 +0000 ++++ ./common/slp_network.h 2005-08-22 17:25:15.754392523 +0000 +@@ -72,6 +72,9 @@ + #include + #include + #endif ++#ifdef HAVE_POLL ++#include ++#endif + + #include "slp_buffer.h" + #include "slp_property.h" +--- ./common/slp_xcast.c.orig 2005-08-22 17:24:56.815079785 +0000 ++++ ./common/slp_xcast.c 2005-08-22 17:25:15.755392381 +0000 +@@ -65,6 +65,9 @@ + #include + #include + #endif ++#ifdef HAVE_POLL ++#include ++#endif + + #ifndef UNICAST_NOT_SUPPORTED + #include "../libslp/slp.h" +@@ -281,8 +284,12 @@ int SLPXcastRecvMessage(const SLPXcastSo +  *    Zero on success, non-zero with errno set on failure. +  *========================================================================*/ + { ++#ifdef HAVE_POLL ++ struct pollfd readfds[SLP_MAX_IFACES]; ++#else + fd_set readfds; + int highfd; ++#endif + int i; + int readable; + size_t bytesread; +@@ -295,6 +302,15 @@ int SLPXcastRecvMessage(const SLPXcastSo + recvloop = 1; + while(recvloop) + { ++#ifdef HAVE_POLL ++ for (i=0; isock_count; i++) ++ { ++ readfds[i].fd = sockets->sock[i]; ++ readfds[i].events = POLLIN; ++ readfds[i].revents = 0; ++ } ++ readable = poll(readfds, sockets->sock_count, timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1); ++#else + /* Set the readfds */ + FD_ZERO(&readfds); + highfd = 0; +@@ -309,12 +325,17 @@ int SLPXcastRecvMessage(const SLPXcastSo + + /* Select */ + readable = select(highfd + 1,&readfds,NULL,NULL,timeout); ++#endif + if(readable > 0) + { + /* Read the datagram */ + for (i=0; isock_count; i++) + { ++#ifdef HAVE_POLL ++ if((readfds[i].revents & POLLIN) != 0) ++#else + if(FD_ISSET(sockets->sock[i],&readfds)) ++#endif + { + /* Peek at the first 16 bytes of the header */ + bytesread = recvfrom(sockets->sock[i], +--- ./configure.in.orig 2005-08-22 17:24:56.816079643 +0000 ++++ ./configure.in 2005-08-22 17:25:15.756392239 +0000 +@@ -170,7 +170,7 @@ AC_CHECK_LIB(resolv, inet_aton) + AC_CHECK_LIB(socket, main) + AC_CHECK_LIB(nsl, gethostbyname) + AC_CHECK_LIB(m, main) +-AC_CHECK_FUNCS(ceil log10 strncasecmp strcasecmp ) ++AC_CHECK_FUNCS(ceil log10 strncasecmp strcasecmp poll ) + AC_CONFIG_FILES([ Makefile ]) + AC_CONFIG_FILES([ common/Makefile ]) + AC_CONFIG_FILES([ libslpattr/Makefile ]) +--- ./libslp/libslp_mdns.c.orig 2005-08-22 17:24:56.817079502 +0000 ++++ ./libslp/libslp_mdns.c 2005-08-22 17:25:15.757392097 +0000 +@@ -742,8 +742,12 @@ int SLPMDNSXcastRecvMessage(const SLPXca + * Zero on success, non-zero with errno set on failure. + *========================================================================*/ + { ++#ifdef HAVE_POLL ++ struct pollfd readfds[SLP_MAX_IFACES * 2]; ++#else + fd_set readfds; + int highfd; ++#endif + int i; + int readable; + size_t bytesread; +@@ -761,6 +765,21 @@ int SLPMDNSXcastRecvMessage(const SLPXca + recvloop = 1; + while(recvloop) + { ++#ifdef HAVE_POLL ++ for (i=0; isock_count; i++) ++ { ++ readfds[i].fd = sockets->sock[i]; ++ readfds[i].events = POLLIN; ++ readfds[i].revents = 0; ++ } ++ for (i=0; isock_count; i++) ++ { ++ readfds[i + sockets->sock_count].fd = mdnssockets->sock[i]; ++ readfds[i + sockets->sock_count].events = POLLIN; ++ readfds[i + sockets->sock_count].revents = 0; ++ } ++ readable = poll(readfds, sockets->sock_count + mdnssockets->sock_count, timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1); ++#else + /* Set the readfds */ + FD_ZERO(&readfds); + highfd = 0; +@@ -779,12 +798,17 @@ int SLPMDNSXcastRecvMessage(const SLPXca + + /* Select */ + readable = select(highfd + 1,&readfds,NULL,NULL,timeout); ++#endif + if(readable > 0) + { + /* Read the datagram */ + for (i=0; isock_count; i++) + { ++#ifdef HAVE_POLL ++ if((readfds[i].revents & POLLIN) != 0) ++#else + if(FD_ISSET(sockets->sock[i],&readfds)) ++#endif + { + /* Peek at the first 16 bytes of the header */ + bytesread = recvfrom(sockets->sock[i], +@@ -850,7 +874,11 @@ int SLPMDNSXcastRecvMessage(const SLPXca + } + for (i=0; isock_count; i++) + { ++#ifdef HAVE_POLL ++ if((readfds[sockets->sock_count + i].revents & POLLIN) == 0) ++#else + if(!FD_ISSET(mdnssockets->sock[i],&readfds)) ++#endif + continue; + *buf = SLPBufferRealloc(*buf, 8000); + (*buf)->curpos = (*buf)->start; +--- ./slpd/slpd_incoming.c.orig 2005-08-22 17:24:56.818079360 +0000 ++++ ./slpd/slpd_incoming.c 2005-08-22 17:25:15.758391955 +0000 +@@ -313,23 +313,20 @@ void IncomingSocketListen(SLPList* sockl + + /*=========================================================================*/ + void SLPDIncomingHandler(int* fdcount, +- fd_set* readfds, +- fd_set* writefds) ++ SLPD_fdset *fdset) + /* Handles all outgoing requests that are pending on the specified file */ + /* discriptors */ + /* */ +-/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* fdcount (IN/OUT) number of file descriptors marked in fdset */ + /* */ +-/* readfds (IN) file descriptors with pending read IO */ +-/* */ +-/* writefds (IN) file descriptors with pending read IO */ ++/* fdset (IN) file descriptors with pending read/write IO */ + /*=========================================================================*/ + { + SLPDSocket* sock; + sock = (SLPDSocket*) G_IncomingSocketList.head; + while (sock && *fdcount) + { +- if (FD_ISSET(sock->fd,readfds)) ++ if (SLPD_fdset_readok(fdset, sock)) + { + switch (sock->state) + { +@@ -354,7 +351,7 @@ void SLPDIncomingHandler(int* fdcount, + + *fdcount = *fdcount - 1; + } +- else if (FD_ISSET(sock->fd,writefds)) ++ else if (SLPD_fdset_writeok(fdset, sock)) + { + switch (sock->state) + { +--- ./slpd/slpd_incoming.h.orig 2005-08-22 17:24:56.818079360 +0000 ++++ ./slpd/slpd_incoming.h 2005-08-22 17:25:15.758391955 +0000 +@@ -57,6 +57,7 @@ + /* common code includes */ + /*=========================================================================*/ + #include "slp_linkedlist.h" ++#include "slpd_socket.h" + + + /*=========================================================================*/ +@@ -74,16 +75,13 @@ void SLPDIncomingAge(time_t seconds); + + /*=========================================================================*/ + void SLPDIncomingHandler(int* fdcount, +- fd_set* readfds, +- fd_set* writefds); ++ SLPD_fdset *fdset); + /* Handles all outgoing requests that are pending on the specified file */ + /* discriptors */ + /* */ +-/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* fdcount (IN/OUT) number of file descriptors marked in fdset */ + /* */ +-/* readfds (IN) file descriptors with pending read IO */ +-/* */ +-/* writefds (IN) file descriptors with pending read IO */ ++/* fdset (IN) file descriptors with pending read/write IO */ + /*=========================================================================*/ + + +--- ./slpd/slpd_main.c.orig 2005-08-22 17:29:17.587046733 +0000 ++++ ./slpd/slpd_main.c 2005-08-22 17:28:13.043216959 +0000 +@@ -82,12 +82,11 @@ int G_SIGINT; /* Signal being used for + #endif + /*==========================================================================*/ + ++#ifdef HAVE_POLL + + /*-------------------------------------------------------------------------*/ +-void LoadFdSets(SLPList* socklist, +- int* highfd, +- fd_set* readfds, +- fd_set* writefds) ++void LoadFdSets(SLPList* socklist, ++ SLPD_fdset *fdset) + /*-------------------------------------------------------------------------*/ + { + SLPDSocket* sock = 0; +@@ -96,9 +95,87 @@ void LoadFdSets(SLPList* socklist, + sock = (SLPDSocket*)socklist->head; + while(sock) + { +- if(sock->fd > *highfd) ++ if (fdset->used == fdset->allocated) { ++ fdset->allocated += 32; ++ if (fdset->used) ++ fdset->fds = xrealloc(fdset->fds, fdset->allocated * sizeof(*fdset->fds)); ++ else ++ fdset->fds = xmalloc(fdset->allocated * sizeof(*fdset->fds)); ++ if (!fdset->fds) ++ SLPDFatal("No memory for fdset.\n"); ++ } ++ fdset->fds[fdset->used].fd = sock->fd; ++ fdset->fds[fdset->used].events = 0; ++ fdset->fds[fdset->used].revents = 0; ++ switch(sock->state) ++ { ++ case DATAGRAM_UNICAST: ++ case DATAGRAM_MULTICAST: ++ case DATAGRAM_BROADCAST: ++ fdset->fds[fdset->used].events |= POLLIN; ++ break; ++ ++ case SOCKET_LISTEN: ++ if(socklist->count < SLPD_MAX_SOCKETS) ++ { ++ fdset->fds[fdset->used].events |= POLLIN; ++ } ++ break; ++ ++ case STREAM_READ: ++ case STREAM_READ_FIRST: ++ fdset->fds[fdset->used].events |= POLLIN; ++ break; ++ ++ case STREAM_WRITE: ++ case STREAM_WRITE_FIRST: ++ case STREAM_CONNECT_BLOCK: ++ fdset->fds[fdset->used].events |= POLLOUT; ++ break; ++ ++ case SOCKET_CLOSE: ++ del = sock; ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (fdset->fds[fdset->used].events) + { +- *highfd = sock->fd; ++ sock->fdsetnr = fdset->used++; ++ } ++ else ++ { ++ sock->fdsetnr = -1; ++ } ++ ++ sock = (SLPDSocket*)sock->listitem.next; ++ ++ if(del) ++ { ++ SLPDSocketFree((SLPDSocket*)SLPListUnlink(socklist,(SLPListItem*)del)); ++ del = 0; ++ } ++ } ++} ++ ++#else ++ ++/*-------------------------------------------------------------------------*/ ++void LoadFdSets(SLPList* socklist, ++ SLPD_fdset *fdset) ++/*-------------------------------------------------------------------------*/ ++{ ++ SLPDSocket* sock = 0; ++ SLPDSocket* del = 0; ++ ++ sock = (SLPDSocket*)socklist->head; ++ while(sock) ++ { ++ if(sock->fd > fdset->highfd) ++ { ++ fdset->highfd = sock->fd; + } + + switch(sock->state) +@@ -106,25 +183,25 @@ void LoadFdSets(SLPList* socklist, + case DATAGRAM_UNICAST: + case DATAGRAM_MULTICAST: + case DATAGRAM_BROADCAST: +- FD_SET(sock->fd,readfds); ++ FD_SET(sock->fd,&fdset->readfds); + break; + + case SOCKET_LISTEN: + if(socklist->count < SLPD_MAX_SOCKETS) + { +- FD_SET(sock->fd,readfds); ++ FD_SET(sock->fd,&fdset->readfds); + } + break; + + case STREAM_READ: + case STREAM_READ_FIRST: +- FD_SET(sock->fd,readfds); ++ FD_SET(sock->fd,&fdset->readfds); + break; + + case STREAM_WRITE: + case STREAM_WRITE_FIRST: + case STREAM_CONNECT_BLOCK: +- FD_SET(sock->fd,writefds); ++ FD_SET(sock->fd,&fdset->writefds); + break; + + case SOCKET_CLOSE: +@@ -145,17 +222,18 @@ void LoadFdSets(SLPList* socklist, + } + } + ++#endif ++ + + /*------------------------------------------------------------------------*/ + void HandleSigTerm() + /*------------------------------------------------------------------------*/ + { + struct timeval timeout; +- fd_set readfds; +- fd_set writefds; +- int highfd = 0; ++ SLPD_fdset fdset; + int fdcount = 0; + ++ SLPD_fdset_init(&fdset); + SLPDLog("****************************************\n"); + SLPDLogTime(); + SLPDLog("SLPD daemon shutting down\n"); +@@ -179,16 +257,19 @@ void HandleSigTerm() + /* if possible wait until all outgoing socket are done and closed */ + while(SLPDOutgoingDeinit(1)) + { +- FD_ZERO(&writefds); +- FD_ZERO(&readfds); +- LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); +- fdcount = select(highfd+1,&readfds,&writefds,0,&timeout); ++ SLPD_fdset_reset(&fdset); ++ LoadFdSets(&G_OutgoingSocketList, &fdset); ++#ifdef HAVE_POLL ++ fdcount = poll(fdset.fds, fdset.used, timeout.tv_sec * 1000 + timeout.tv_usec / 1000); ++#else ++ fdcount = select(fdset.highfd+1,&fdset.readfds,&fdset.writefds,0,&timeout); ++#endif + if(fdcount == 0) + { + break; + } + +- SLPDOutgoingHandler(&fdcount,&readfds,&writefds); ++ SLPDOutgoingHandler(&fdcount,&fdset); + } + + SLPDOutgoingDeinit(0); +@@ -491,11 +572,10 @@ int SetUpSignalHandlers() + int main(int argc, char* argv[]) + /*=========================================================================*/ + { +- fd_set readfds; +- fd_set writefds; +- int highfd; ++ SLPD_fdset fdset; + int fdcount = 0; + ++ SLPD_fdset_init(&fdset); + reg_file_dir = strdup("/etc/slp.reg.d"); + + #ifdef DEBUG +@@ -616,14 +696,12 @@ int main(int argc, char* argv[]) + /*--------------------------------------------------------*/ + /* Load the fdsets up with all valid sockets in the list */ + /*--------------------------------------------------------*/ +- highfd = 0; +- FD_ZERO(&readfds); +- FD_ZERO(&writefds); +- LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds); +- LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); ++ SLPD_fdset_reset(&fdset); ++ LoadFdSets(&G_IncomingSocketList, &fdset); ++ LoadFdSets(&G_OutgoingSocketList, &fdset); + + #ifdef ENABLE_MDNS_SLPD +- LoadFdSets(&G_MDNSSocketList, &highfd, &readfds,&writefds); ++ LoadFdSets(&G_MDNSSocketList, &fdset); + #endif + + /*--------------------------------------------------*/ +@@ -637,14 +715,18 @@ int main(int argc, char* argv[]) + /*-------------*/ + /* Main select */ + /*-------------*/ +- fdcount = select(highfd+1,&readfds,&writefds,0,0); ++#ifdef HAVE_POLL ++ fdcount = poll(fdset.fds, fdset.used, -1); ++#else ++ fdcount = select(fdset.highfd+1,&fdset.readfds,&fdset.writefds,0,0); ++#endif + if(fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */ + { +- SLPDIncomingHandler(&fdcount,&readfds,&writefds); +- SLPDOutgoingHandler(&fdcount,&readfds,&writefds); ++ SLPDIncomingHandler(&fdcount,&fdset); ++ SLPDOutgoingHandler(&fdcount,&fdset); + + #ifdef ENABLE_MDNS_SLPD +- SLPDMDNSHandler(&fdcount,&readfds,&writefds); ++ SLPDMDNSHandler(&fdcount,&fdset); + #endif + } + +--- ./slpd/slpd_mdns.c.orig 2005-08-22 17:24:56.821078934 +0000 ++++ ./slpd/slpd_mdns.c 2005-08-22 17:25:15.761391529 +0000 +@@ -207,23 +207,20 @@ int SLPDMDNSDeinit() + + /*=========================================================================*/ + void SLPDMDNSHandler(int* fdcount, +- fd_set* readfds, +- fd_set* writefds) ++ SLPD_fdset* fdset) + /* Handles all outgoing requests that are pending on the specified file */ + /* discriptors */ + /* */ +-/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* fdcount (IN/OUT) number of file descriptors marked in fdset */ + /* */ +-/* readfds (IN) file descriptors with pending read IO */ +-/* */ +-/* writefds (IN) file descriptors with pending read IO */ ++/* fdset (IN) file descriptors with pending read/write IO */ + /*=========================================================================*/ + { + SLPDSocket* sock; + sock = (SLPDSocket*) G_MDNSSocketList.head; + while (sock && *fdcount) + { +- if (FD_ISSET(sock->fd,readfds)) ++ if (SLPD_fdset_readok(fdset, sock)) + { + switch (sock->state) + { +--- ./slpd/slpd_mdns.h.orig 2005-08-22 17:24:56.821078934 +0000 ++++ ./slpd/slpd_mdns.h 2005-08-22 17:25:15.761391529 +0000 +@@ -8,6 +8,7 @@ + /*=========================================================================*/ + #include "slp_linkedlist.h" + #include "slp_mdns.h" ++#include "slpd_socket.h" + + + /*=========================================================================*/ +@@ -17,16 +18,13 @@ extern SLPList G_MDNSSocketList; + + /*=========================================================================*/ + void SLPDMDNSHandler(int* fdcount, +- fd_set* readfds, +- fd_set* writefds); ++ SLPD_fdset* fdset); + /* Handles all outgoing requests that are pending on the specified file */ + /* discriptors */ + /* */ +-/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* fdcount (IN/OUT) number of file descriptors marked in fdset */ + /* */ +-/* readfds (IN) file descriptors with pending read IO */ +-/* */ +-/* writefds (IN) file descriptors with pending read IO */ ++/* fdset (IN) file descriptors with pending read/write IO */ + /*=========================================================================*/ + + +--- ./slpd/slpd_outgoing.c.orig 2005-08-22 17:24:56.822078792 +0000 ++++ ./slpd/slpd_outgoing.c 2005-08-22 17:25:15.762391388 +0000 +@@ -451,24 +451,21 @@ void SLPDOutgoingDatagramWrite(SLPDSocke + + /*=========================================================================*/ + void SLPDOutgoingHandler(int* fdcount, +- fd_set* readfds, +- fd_set* writefds) ++ SLPD_fdset* fdset) + + /* Handles all outgoing requests that are pending on the specified file */ + /* discriptors */ + /* */ +-/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* fdcount (IN/OUT) number of file descriptors marked in fdset */ + /* */ +-/* readfds (IN) file descriptors with pending read IO */ +-/* */ +-/* writefds (IN) file descriptors with pending read IO */ ++/* fdset (IN) file descriptors with pending read/write IO */ + /*=========================================================================*/ + { + SLPDSocket* sock; + sock = (SLPDSocket*)G_OutgoingSocketList.head; + while ( sock && *fdcount ) + { +- if ( FD_ISSET(sock->fd,readfds) ) ++ if (SLPD_fdset_readok(fdset, sock)) + { + switch ( sock->state ) + { +@@ -490,7 +487,7 @@ void SLPDOutgoingHandler(int* fdcount, + + *fdcount = *fdcount - 1; + } +- else if ( FD_ISSET(sock->fd,writefds) ) ++ else if (SLPD_fdset_writeok(fdset, sock)) + { + switch ( sock->state ) + { +--- ./slpd/slpd_outgoing.h.orig 2005-08-22 17:24:56.823078650 +0000 ++++ ./slpd/slpd_outgoing.h 2005-08-22 17:25:15.763391246 +0000 +@@ -74,17 +74,14 @@ void SLPDOutgoingAge(time_t seconds); + + /*=========================================================================*/ + void SLPDOutgoingHandler(int* fdcount, +- fd_set* readfds, +- fd_set* writefds); ++ SLPD_fdset* fdset); + + /* Handles all incoming requests that are pending on the specified file */ + /* discriptors */ + /* */ +-/* fdcount (IN/OUT) number of file descriptors marked in fd_sets */ ++/* fdcount (IN/OUT) number of file descriptors marked in fdset */ + /* */ +-/* readfds (IN) file descriptors with pending read IO */ +-/* */ +-/* writefds (IN) file descriptors with pending read IO */ ++/* fdset (IN) file descriptors with pending read/write IO */ + /*=========================================================================*/ + + +--- ./slpd/slpd_socket.h.orig 2005-08-22 17:24:56.823078650 +0000 ++++ ./slpd/slpd_socket.h 2005-08-22 17:25:15.763391246 +0000 +@@ -107,8 +107,50 @@ typedef struct _SLPDSocket + /* Outgoing socket stuff */ + int reconns; + SLPList sendlist; ++#ifdef HAVE_POLL ++ int fdsetnr; ++#endif + }SLPDSocket; + ++#ifdef HAVE_POLL ++ ++#include ++ ++typedef struct _SLPD_fdset { ++ struct pollfd *fds; ++ int used; ++ int allocated; ++} SLPD_fdset; ++ ++/* the following code supports only one fdset at a time */ ++ ++#define SLPD_fdset_readok(fdset, sock) ((sock)->fdsetnr != -1 && (sock)->fdsetnr < (fdset)->used && (fdset)->fds[(sock)->fdsetnr].fd == (sock)->fd ? ((fdset)->fds[(sock)->fdsetnr].revents & ((fdset)->fds[(sock)->fdsetnr].events & POLLIN ? (POLLIN|POLLERR|POLLHUP) : POLLIN)) != 0 : 0) ++#define SLPD_fdset_writeok(fdset, sock) ((sock)->fdsetnr != -1 && (sock)->fdsetnr < (fdset)->used && (fdset)->fds[(sock)->fdsetnr].fd == (sock)->fd ? ((fdset)->fds[(sock)->fdsetnr].revents & ((fdset)->fds[(sock)->fdsetnr].events & POLLOUT ? (POLLOUT|POLLERR|POLLHUP) : POLLOUT)) != 0 : 0) ++ ++#define SLPD_fdset_reset(fdset) ((fdset)->used = 0) ++#define SLPD_fdset_init(fdset) ((fdset)->used = (fdset)->allocated = 0, (fdset)->fds = 0) ++#define SLPD_fdset_free(fdset) ((fdset)->allocated && xfree((fdset)->fds), SLPD_fdset_init(fdset)) ++ ++#else ++ ++typedef struct _SLPD_fdset { ++ fd_set readfds; ++ fd_set writefds; ++ int highfd; ++} SLPD_fdset; ++ ++#define SLPD_fdset_readok(fdset, sock) (FD_ISSET((sock)->fd, &(fdset)->readfds)) ++#define SLPD_fdset_writeok(fdset, sock) (FD_ISSET((sock)->fd, &(fdset)->writefds)) ++ ++#define SLPD_fdset_reset(fdset) do { \ ++ FD_ZERO(&(fdset)->readfds); \ ++ FD_ZERO(&(fdset)->writefds); \ ++ (fdset)->highfd = 0; \ ++ } while(0) ++#define SLPD_fdset_init(fdset) ++#define SLPD_fdset_free(fdset) ++ ++#endif + + /*==========================================================================*/ + SLPDSocket* SLPDSocketCreateConnected(struct in_addr* addr); +--- ./slpd/slpd_win32.c.orig 2005-08-22 17:24:56.824078508 +0000 ++++ ./slpd/slpd_win32.c 2005-08-22 17:25:15.764391104 +0000 +@@ -81,9 +81,7 @@ extern int G_SIGTERM; + + /*-------------------------------------------------------------------------*/ + void LoadFdSets(SLPList* socklist, +- int* highfd, +- fd_set* readfds, +- fd_set* writefds); ++ SLPD_fdset *fdset); + /* see slpd_main.c */ + /*-------------------------------------------------------------------------*/ + +@@ -221,16 +219,18 @@ void ServiceStop() + void ServiceStart (int argc, char **argv) + /*--------------------------------------------------------------------------*/ + { +- fd_set readfds; +- fd_set writefds; +- int highfd; ++ SLPD_fdset fdset; + int fdcount = 0; + time_t curtime; + time_t alarmtime; ++#ifndef HAVE_POLL + struct timeval timeout; ++#endif + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(1,1); + ++ SLPD_fdset_init(&fdset); ++ + /*------------------------*/ + /* Service initialization */ + /*------------------------*/ +@@ -335,11 +335,9 @@ void ServiceStart (int argc, char **argv + /*--------------------------------------------------------*/ + /* Load the fdsets up with all valid sockets in the list */ + /*--------------------------------------------------------*/ +- highfd = 0; +- FD_ZERO(&readfds); +- FD_ZERO(&writefds); +- LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds); +- LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds); ++ SLPD_fdset_reset(&fdset); ++ LoadFdSets(&G_IncomingSocketList, &fdset); ++ LoadFdSets(&G_OutgoingSocketList, &fdset); + + /*--------------------------------------------------*/ + /* Before select(), check to see if we got a signal */ +@@ -352,13 +350,17 @@ void ServiceStart (int argc, char **argv + /*-------------*/ + /* Main select */ + /*-------------*/ ++#ifdef HAVE_POLL ++ fdcount = poll(fdset.fds, fdset.used, SLPD_AGE_INTERVAL * 1000); ++#else + timeout.tv_sec = SLPD_AGE_INTERVAL; + timeout.tv_usec = 0; +- fdcount = select(highfd+1,&readfds,&writefds,0,&timeout); ++ fdcount = select(fdset.highfd+1,&fdset.readfds,&fdset.writefds,0,&timeout); ++#endif + if(fdcount > 0) /* fdcount will be < 0 when timed out */ + { +- SLPDIncomingHandler(&fdcount,&readfds,&writefds); +- SLPDOutgoingHandler(&fdcount,&readfds,&writefds); ++ SLPDIncomingHandler(&fdcount,&fdset); ++ SLPDOutgoingHandler(&fdcount,&fdset); + } + + /*----------------*/ diff --git a/openslp.spec b/openslp.spec new file mode 100644 index 0000000..daecdbf --- /dev/null +++ b/openslp.spec @@ -0,0 +1,385 @@ +# +# spec file for package openslp (Version 1.2.0) +# +# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +# norootforbuild + +Name: openslp +BuildRequires: openssl-devel +Summary: An OpenSLP Implementation of Service Location Protocol V2 +Version: 1.2.0 +Release: 43 +License: BSD License and BSD-like, Other License(s), see package +Group: System/Daemons +URL: http://www.openslp.org/ +PreReq: %fillup_prereq %insserv_prereq +BuildRoot: %{_tmppath}/%{name}-%{version}-build +Source0: %name-%version.tar.bz2 +Source1: slpd.init +Source2: README.SuSE +Source3: openslp.desktop +Source4: openslp-devel.desktop +Source5: openslp.logrotate +Patch1: openslp.diff +Patch2: openslp.audit.diff +Patch3: extensions.diff +Patch4: slptool-timeout.diff +Patch5: hppa.diff +Patch6: v1dadiscovery.diff +Patch7: openslp.poll.diff +Patch8: openslp.v1sladdr.diff +Patch9: openslp.tcpclearovr.diff +Patch10: openslp.checkovr.diff +Patch11: openslp.truncate.diff +Patch12: openslp.emptyanswer.diff +Patch13: openslp.doubleequal.diff + +%description +Service Location Protocol is an IETF standards track protocol that +provides a framework that allows networking applications to discover +the existence, location, and configuration of networked services in +enterprise networks. + +OpenSLP is an open source implementation of the SLPv2 protocol as +defined by RFC 2608 and RFC 2614. This package includes the slptool +and runtime libraries. + + + +Authors: +-------- + Matthew Peterson + Ganesan Rajagopal + David McCormack + Evan Hughes + Matthieu Desmons + Praveen Kumar Amritaluru + +%package server +Group: System/Daemons +Summary: The OpenSLP Implementation of the Service Location Protocol V2 + +%description server +Service Location Protocol is an IETF standards track protocol that +provides a framework that allows networking applications to discover +the existence, location, and configuration of networked services in +enterprise networks. + +This package contains the SLP server. Every system, which provides any +services that should be used via an SLP client must run this server and +register the service. + + + +Authors: +-------- + Matthew Peterson + Ganesan Rajagopal + David McCormack + Evan Hughes + Matthieu Desmons + Praveen Kumar Amritaluru + +%package devel +Requires: openssl-devel openslp = %version +Group: System/Daemons +Summary: OpenSLP Development SDK + +%description devel +Service Location Protocol is an IETF standards track protocol that +provides a framework that allows networking applications to discover +the existence, location, and configuration of networked services in +enterprise networks. + +This package contains header and library files to compile applications +with SLP support. It also contains developer documentation to develop +such applications. + + + +Authors: +-------- + Matthew Peterson + Ganesan Rajagopal + David McCormack + Evan Hughes + Matthieu Desmons + Praveen Kumar Amritaluru + +%prep +%setup -q +%patch1 +%patch2 +%patch3 +%patch4 +%ifarch hppa +%patch5 +%endif +%patch6 +%patch7 +%patch8 +%patch9 +%patch10 +%patch11 +%patch12 +%patch13 +autoreconf --force --install + +%build +export CFLAGS="$RPM_OPT_FLAGS -fstack-protector" +./configure \ + --prefix=/usr \ + --libdir=%_libdir \ + --sysconfdir=%_sysconfdir \ + --enable-slpv1 \ + --enable-async-api \ + --enable-slpv2-security +make + +%install +rm -rf ${RPM_BUILD_ROOT} +mkdir -p ${RPM_BUILD_ROOT}/etc/slp.reg.d +cp etc/slp.conf ${RPM_BUILD_ROOT}/etc +cp etc/slp.reg ${RPM_BUILD_ROOT}/etc +cp etc/slp.spi ${RPM_BUILD_ROOT}/etc +mkdir -p ${RPM_BUILD_ROOT}/%_libdir +libtool install libslp/libslp.la ${RPM_BUILD_ROOT}/%_libdir +mkdir -p ${RPM_BUILD_ROOT}/usr/sbin +libtool install slpd/slpd ${RPM_BUILD_ROOT}/usr/sbin +mkdir -p ${RPM_BUILD_ROOT}/usr/bin +libtool install slptool/slptool ${RPM_BUILD_ROOT}/usr/bin +mkdir -p ${RPM_BUILD_ROOT}/usr/include +cp libslp/slp.h ${RPM_BUILD_ROOT}/usr/include +mkdir -p ${RPM_BUILD_ROOT}%_defaultdocdir/%name +find . -name CVS -o -name .cvsignore -o -name .xvpics | xargs rm -rf +cp -a AUTHORS COPYING README FAQ doc/rfc doc/html %SOURCE2 \ + ${RPM_BUILD_ROOT}%_defaultdocdir/%name +mkdir -p ${RPM_BUILD_ROOT}/etc/init.d/ +install -m 755 %{SOURCE1} ${RPM_BUILD_ROOT}/etc/init.d/slpd +ln -sf ../../etc/init.d/slpd ${RPM_BUILD_ROOT}/usr/sbin/rcslpd +ln -sf ../../etc/init.d/slpd ${RPM_BUILD_ROOT}/usr/sbin/rcopenslp +install -D -m 0644 %{SOURCE5} ${RPM_BUILD_ROOT}/etc/logrotate.d/openslp-server +# install susehelp file +mkdir -p $RPM_BUILD_ROOT/usr/share/susehelp/meta/Administration/ +install -m 0644 %SOURCE3 \ + $RPM_BUILD_ROOT/usr/share/susehelp/meta/Administration/ +mkdir -p $RPM_BUILD_ROOT/usr/share/susehelp/meta/Development/Libraries/ +install -m 0644 %SOURCE4 \ + $RPM_BUILD_ROOT/usr/share/susehelp/meta/Development/Libraries/ +%if 0 +# actually, these files should get translated, but do we really want to +# add update-desktop-files to needed_for_build ? +%suse_update_desktop_file $RPM_BUILD_ROOT/usr/share/susehelp/meta/Administration/openslp.desktop +%suse_update_desktop_file $RPM_BUILD_ROOT/usr/share/susehelp/meta/Development/Libraries/openslp-devel.desktop +%endif + +%post +%run_ldconfig + +%postun +%run_ldconfig + +%post server +%if %sles_version > 0 +%{fillup_and_insserv -y slpd} +%else +%{fillup_and_insserv slpd} +%endif + +%postun server +%restart_on_update slpd +%insserv_cleanup + +%preun server +%stop_on_removal slpd + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%dir %_defaultdocdir/%name +%dir %_defaultdocdir/%name/html +%doc %_defaultdocdir/%name/AUTHORS +%doc %_defaultdocdir/%name/COPYING +%doc %_defaultdocdir/%name/README +%doc %_defaultdocdir/%name/README.SuSE +%_libdir/libslp.so.* +/usr/bin/slptool +%config(noreplace) /etc/slp.conf +%config(noreplace) /etc/slp.spi + +%files server +%defattr(-,root,root) +%dir /usr/share/susehelp +%dir /usr/share/susehelp/meta +%dir /usr/share/susehelp/meta/Administration +%doc %dir %_defaultdocdir/%name/FAQ +%doc %_defaultdocdir/%name/html/IntroductionToSLP +%doc %_defaultdocdir/%name/html/UsersGuide +%doc %_defaultdocdir/%name/html/faq.html +%doc %_defaultdocdir/%name/rfc +%doc /usr/share/susehelp/meta/Administration/openslp.desktop +%dir /etc/slp.reg.d/ +/usr/sbin/rcopenslp +/usr/sbin/rcslpd +/usr/sbin/slpd +/etc/init.d/slpd +%config(noreplace) /etc/slp.reg +%config(noreplace) /etc/logrotate.d/openslp-server + +%files devel +%defattr(-,root,root) +%dir /usr/share/susehelp +%dir /usr/share/susehelp/meta +%dir /usr/share/susehelp/meta/Development +%dir /usr/share/susehelp/meta/Development/Libraries +%doc %_defaultdocdir/%name/html/ProgrammersGuide +%doc /usr/share/susehelp/meta/Development/Libraries/openslp-devel.desktop +/usr/include/slp.h +%_libdir/libslp.a +%_libdir/libslp.la +%_libdir/libslp.so + +%changelog -n openslp +* Thu Nov 16 2006 - mls@suse.de +- truncate oversized udp messages, finally fixes [#185483] + (can be turned of with "net.slp.oversizedUDP" option) +- do not try to send back empty answers +- add option "net.slp.allowDoubleEqualInPredicate" to make openslp + work with some buggy clients that use "==" for comparison [#95043] +- changed SLPGetPeer interface to support IPv6 +* Tue Sep 12 2006 - mls@suse.de +- obey OVERFLOW bit of incoming udp messages [#185483] +- use right length in send() calls [#185483] +- fix errno check in IncomingStreamWrite +- add SLPGetPeer method in libslp +- add --peerinfo option to slptool to print peerinfo +* Wed May 10 2006 - mls@suse.de +- fix unaligned memory access on ia64 [#171932] +* Fri Mar 24 2006 - mls@suse.de +- fix listening on multiple interfaces [#160008] +* Sat Mar 18 2006 - schwab@suse.de +- Fix file descritor leak [#159303]. +* Mon Jan 30 2006 - mls@suse.de +- fix bug in DropSLPMulticastGroup +- add -fstack-protector to CFLAGS +- added logrotate script [#143069] +* Wed Jan 25 2006 - mls@suse.de +- converted neededforbuild to BuildRequires +* Fri Dec 23 2005 - mls@suse.de +- clear overflow bit on TCP connections [#135248] +* Thu Sep 29 2005 - dmueller@suse.de +- add norootforbuild +* Mon Aug 22 2005 - mls@suse.de +- also listen on SLPv1 General Multicast address [#64138] +- use poll instead of select [#65673] +* Tue Feb 15 2005 - mls@suse.de +- update to version 1.2.0 +- fixed security audit findings +- disable mdns in slpd for now, libslp still supports it +* Fri Dec 03 2004 - mls@suse.de +- fix slpv DA discovery scope handling (#48728) +- use _dns-sd instead of _mdns in mdns findsrvtypes query (#48325) +* Thu Oct 14 2004 - adrian@suse.de +- add meta information for suse help. +* Sun Jun 13 2004 - bg@suse.de +- reduce hardcoded optimization from -O3 to -O2 to circumvent + ICE on hppa +* Tue Jun 01 2004 - mls@suse.de +- added fillup and insserv prereq +* Thu May 27 2004 - mls@suse.de +- use /proc/net/tcp_listen and /proc/net/tcp6_listen if + available to keep things fast on systems with lots of + network connections [#40888] +* Wed May 05 2004 - mls@suse.de +- treat empty attributes as illegal [#39669] +- always start slpd on SLES [#39863] +* Fri Apr 23 2004 - mls@suse.de +- libslp: use configured TTL settings [#39030] +* Fri Apr 02 2004 - mls@suse.de +- beta is over, don't always start slpd +* Fri Apr 02 2004 - kukuk@suse.de +- Fix init script +* Wed Mar 31 2004 - mls@suse.de +- fix sighup processing +- clean up spi code +- fix spi null pointer reference +- fix namingauth comparison +- added try-restart to rcslpd +- fix slp.conf re-read +- fix prlist buffer overrun +* Mon Mar 29 2004 - mls@suse.de +- turn around srvtypes order in mdns +* Thu Mar 18 2004 - mls@suse.de +- code cleanup +- provide A RR with SRV RRs +- don't pack .xvpics +* Fri Mar 12 2004 - mls@suse.de +- added missing SLPGetMDNSName prototype to slp.h +* Fri Mar 12 2004 - mls@suse.de +- slpd: fix hostname detection segfault +- slpd: use ttl 255 for mdns +- slpd: put attrs in mdns TXT RR +- libslp: check mdns ttl +- libslp: make getattr work with mdns +- libslp: make mdns name available via new SLPGetMDNSName() function +* Thu Mar 04 2004 - mls@suse.de +- libslp: add scope/nameingauth/predicate to query +- slpd: reply to mdns service requests +- slpd: don't play DA if our hostname expands to loopback +- slpd: fix null pointer reference if SrvReg request is sent + over tcp (as done by apple) +* Fri Feb 27 2004 - mls@suse.de +- slpd: check port status every 15 seconds for watch-port-tcp/udp + entries +- libslp: send MDNS queries for scope _mdns +* Sun Feb 15 2004 - adrian@suse.de +- export full qualified hostnames for $HOSTNAME +- replace several $HOSTNAME tags in a srvurl +- do only accept .reg files (no .rpmsave for instance) +* Sat Feb 14 2004 - adrian@suse.de +- fix /proc/net/tcp* parsing +- ONLY FOR BETA: start slpd always +* Thu Jan 29 2004 - adrian@suse.de +- fix reading from slpd.reg.d directory + (was broken since chroot run) +* Wed Jan 14 2004 - adrian@suse.de +- slptool register now services with max timeout. +* Tue Dec 16 2003 - adrian@suse.de +- fix sig11 when using the library without spi file +* Mon Dec 08 2003 - adrian@suse.de +- security enhancements: + * use chroot and open needed file descriptors before + * panic if chroot or setuid fails + * pid-file= option in reg files is useless now, so + tcp-port= must be used for this now +- add SSL support again +* Wed Nov 26 2003 - adrian@suse.de +- add buffer fix from cvs +- add README.SuSE with config howto +* Thu Nov 20 2003 - adrian@suse.de +- drop the multicast route creation in runlevel script. + we do not need it anymore with 1.1.5 +* Wed Nov 19 2003 - adrian@suse.de +- update to version 1.1.5 + * development version, but it contains lots of fixes +- use $HOSTNAME instead of $LOCALHOST in reg files +* Fri Nov 14 2003 - adrian@suse.de +- use correct keyword "X-UnitedLinux-Should-Start" in init script + (seen by Martin Vidner) +* Thu Nov 13 2003 - adrian@suse.de +- add "tcp-port=" option to test services running via (x)inted +- start after (x)inetd +* Wed Nov 12 2003 - adrian@suse.de +- add code to parse .reg files from any package below /etc/slp.reg.d/ +* Sun Nov 09 2003 - adrian@suse.de +- fix security issue in init script +* Sat Nov 08 2003 - adrian@suse.de +- initial package of version 1.0.11 diff --git a/openslp.tcpclearovr.diff b/openslp.tcpclearovr.diff new file mode 100644 index 0000000..7b67a70 --- /dev/null +++ b/openslp.tcpclearovr.diff @@ -0,0 +1,27 @@ +--- ./slpd/slpd_incoming.c.orig 2005-12-23 14:13:55.000000000 +0000 ++++ ./slpd/slpd_incoming.c 2005-12-23 14:42:26.000000000 +0000 +@@ -63,6 +63,7 @@ + /*=========================================================================*/ + #include "slp_xmalloc.h" + #include "slp_message.h" ++#include "slp_v1message.h" + + + /*=========================================================================*/ +@@ -242,6 +243,16 @@ void IncomingStreamRead(SLPList* socklis + sock->state = SOCKET_CLOSE; + break; + default: ++ /* some clients cannot cope with the OVERFLOW ++ * bit set on a TCP stream, so always clear it ++ */ ++ if (sock->sendbuf && sock->sendbuf->end - sock->sendbuf->start > 5) ++ { ++ if (sock->sendbuf->start[0] == 1) ++ sock->sendbuf->start[4] &= ~SLPv1_FLAG_OVERFLOW; ++ else ++ sock->sendbuf->start[5] &= ~(SLP_FLAG_OVERFLOW >> 8); ++ } + sock->state = STREAM_WRITE_FIRST; + IncomingStreamWrite(socklist, sock); + } diff --git a/openslp.truncate.diff b/openslp.truncate.diff new file mode 100644 index 0000000..3441b91 --- /dev/null +++ b/openslp.truncate.diff @@ -0,0 +1,188 @@ +--- ./slpd/slpd_incoming.c.orig 2006-11-14 16:25:18.000000000 +0000 ++++ ./slpd/slpd_incoming.c 2006-11-15 18:20:10.000000000 +0000 +@@ -79,6 +79,7 @@ void IncomingDatagramRead(SLPList* sockl + int bytestowrite; + int byteswritten; + int peeraddrlen = sizeof(struct sockaddr_in); ++ int truncate; + + bytesread = recvfrom(sock->fd, + sock->recvbuf->start, +@@ -90,9 +91,13 @@ void IncomingDatagramRead(SLPList* sockl + { + sock->recvbuf->end = sock->recvbuf->start + bytesread; + ++ truncate = SLP_MAX_DATAGRAM_SIZE; ++ if (G_SlpdProperty.oversizedUDP) ++ truncate = 0; + switch (SLPDProcessMessage(&sock->peeraddr, + sock->recvbuf, +- &(sock->sendbuf))) ++ &(sock->sendbuf), ++ truncate)) + { + case SLP_ERROR_PARSE_ERROR: + case SLP_ERROR_VER_NOT_SUPPORTED: +@@ -238,7 +243,7 @@ void IncomingStreamRead(SLPList* socklis + { + switch (SLPDProcessMessage(&sock->peeraddr, + sock->recvbuf, +- &(sock->sendbuf))) ++ &(sock->sendbuf), 0)) + { + case SLP_ERROR_PARSE_ERROR: + case SLP_ERROR_VER_NOT_SUPPORTED: +--- ./slpd/slpd_outgoing.c.orig 2006-11-14 16:26:13.000000000 +0000 ++++ ./slpd/slpd_outgoing.c 2006-11-15 18:29:31.000000000 +0000 +@@ -89,7 +89,7 @@ void OutgoingDatagramRead(SLPList* sockl + + SLPDProcessMessage(&(sock->peeraddr), + sock->recvbuf, +- &(sock->sendbuf)); ++ &(sock->sendbuf), 0); + + /* Completely ignore the message */ + } +@@ -264,7 +264,7 @@ void OutgoingStreamRead(SLPList* socklis + { + switch ( SLPDProcessMessage(&(sock->peeraddr), + sock->recvbuf, +- &(sock->sendbuf)) ) ++ &(sock->sendbuf), 0) ) + { + case SLP_ERROR_DA_BUSY_NOW: + sock->state = STREAM_WRITE_WAIT; +--- ./slpd/slpd_process.c.orig 2006-11-14 16:18:24.000000000 +0000 ++++ ./slpd/slpd_process.c 2006-11-15 15:22:05.000000000 +0000 +@@ -301,7 +301,8 @@ int ProcessDASrvRqst(SLPMessage message, + /*-------------------------------------------------------------------------*/ + int ProcessSrvRqst(SLPMessage message, + SLPBuffer* sendbuf, +- int errorcode) ++ int errorcode, ++ int truncate) + /*-------------------------------------------------------------------------*/ + { + int i; +@@ -310,12 +311,6 @@ int ProcessSrvRqst(SLPMessage message, + int size = 0; + SLPBuffer result = *sendbuf; + +-#ifdef ENABLE_SLPv2_SECURITY +- SLPAuthBlock* authblock = 0; +- int j; +-#endif +- +- + /*--------------------------------------------------------------*/ + /* If errorcode is set, we can not be sure that message is good */ + /* Go directly to send response code */ +@@ -445,33 +440,24 @@ int ProcessSrvRqst(SLPMessage message, + { + for (i=0;iurlcount;i++) + { ++ /* check size limitation */ ++ if (truncate && size > truncate) ++ break; ++ + /* urlentry is the url from the db result */ + urlentry = db->urlarray[i]; + +- size += urlentry->urllen + 6; /* 1 byte for reserved */ +- /* 2 bytes for lifetime */ +- /* 2 bytes for urllen */ +- /* 1 byte for authcount */ +-#ifdef ENABLE_SLPv2_SECURITY +- +- /* make room to include the authblock that was asked for */ +- if (G_SlpdProperty.securityEnabled && +- message->body.srvrqst.spistrlen ) ++ if (urlentry->opaque == 0) + { +- for (j=0; jauthcount;j++) +- { +- if (SLPCompareString(urlentry->autharray[j].spistrlen, +- urlentry->autharray[j].spistr, +- message->body.srvrqst.spistrlen, +- message->body.srvrqst.spistr) == 0) +- { +- authblock = &(urlentry->autharray[j]); +- size += authblock->length; +- break; +- } +- } ++ size += urlentry->urllen + 6; /* 1 byte for reserved */ ++ /* 2 bytes for lifetime */ ++ /* 2 bytes for urllen */ ++ /* 1 byte for authcount */ ++ } ++ else ++ { ++ size += urlentry->opaquelen; + } +-#endif + } + } + +@@ -523,6 +509,10 @@ int ProcessSrvRqst(SLPMessage message, + + for (i=0;iurlcount;i++) + { ++ /* check size limitation */ ++ if (truncate && result->curpos - result->start > truncate) ++ break; ++ + /* urlentry is the url from the db result */ + urlentry = db->urlarray[i]; + +@@ -1312,7 +1302,8 @@ int ProcessSAAdvert(SLPMessage message, + /*=========================================================================*/ + int SLPDProcessMessage(struct sockaddr_in* peerinfo, + SLPBuffer recvbuf, +- SLPBuffer* sendbuf) ++ SLPBuffer* sendbuf, ++ int truncate) + /* Processes the recvbuf and places the results in sendbuf */ + /* */ + /* peerinfo - the socket the message was received on */ +@@ -1390,7 +1381,7 @@ int SLPDProcessMessage(struct sockaddr_i + switch (message->header.functionid) + { + case SLP_FUNCT_SRVRQST: +- errorcode = ProcessSrvRqst(message,sendbuf,errorcode); ++ errorcode = ProcessSrvRqst(message,sendbuf,errorcode,truncate); + break; + + case SLP_FUNCT_SRVREG: +--- ./slpd/slpd_process.h.orig 2006-11-14 16:23:21.000000000 +0000 ++++ ./slpd/slpd_process.h 2006-11-14 16:23:38.000000000 +0000 +@@ -60,7 +60,8 @@ + /*=========================================================================*/ + int SLPDProcessMessage(struct sockaddr_in* peerinfo, + SLPBuffer recvbuf, +- SLPBuffer* sendbuf) ; ++ SLPBuffer* sendbuf, ++ int truncate) ; + /* Processes the recvbuf and places the results in sendbuf */ + /* */ + /* peerinfo - the socket the message was received on */ +--- ./slpd/slpd_property.c.orig 2006-11-15 18:14:47.000000000 +0000 ++++ ./slpd/slpd_property.c 2006-11-15 18:16:28.000000000 +0000 +@@ -131,6 +131,7 @@ int SLPDPropertyInit(const char* conffil + G_SlpdProperty.securityEnabled = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.securityEnabled")); + G_SlpdProperty.checkSourceAddr = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.checkSourceAddr")); + G_SlpdProperty.DAHeartBeat = SLPPropertyAsInteger(SLPPropertyGet("net.slp.DAHeartBeat")); ++ G_SlpdProperty.oversizedUDP = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.oversizedUDP")); + + + /*-------------------------------------*/ +--- ./slpd/slpd_property.h.orig 2006-11-15 18:14:05.000000000 +0000 ++++ ./slpd/slpd_property.h 2006-11-15 18:15:28.000000000 +0000 +@@ -94,6 +94,7 @@ typedef struct _SLPDProperty + int securityEnabled; + int checkSourceAddr; + int DAHeartBeat; ++ int oversizedUDP; + }SLPDProperty; + + diff --git a/openslp.v1sladdr.diff b/openslp.v1sladdr.diff new file mode 100644 index 0000000..28f62fb --- /dev/null +++ b/openslp.v1sladdr.diff @@ -0,0 +1,34 @@ +--- ./common/slp_message.h.orig 2005-04-13 17:21:37.000000000 +0000 ++++ ./common/slp_message.h 2005-04-13 17:22:47.527724927 +0000 +@@ -93,6 +93,7 @@ + #define SLP_RESERVED_PORT 427 + #define SLP_MCAST_ADDRESS 0xeffffffd /* 239.255.255.253 */ + #define SLP_BCAST_ADDRESS 0xffffffff /* 255.255.255.255 */ ++#define SLPv1_SL_MCAST_ADDRESS 0xe0000116 /* 224.0.1.22 */ + #define SLPv1_DA_MCAST_ADDRESS 0xe0000123 /* 224.0.1.35 */ + #define LOOPBACK_ADDRESS 0x7f000001 /* 127.0.0.1 */ + #define SLP_MAX_DATAGRAM_SIZE 1400 +--- ./slpd/slpd_incoming.c.orig 2005-04-13 15:58:18.000000000 +0000 ++++ ./slpd/slpd_incoming.c 2005-04-13 17:29:26.486900643 +0000 +@@ -534,6 +531,21 @@ + } + + #if defined(ENABLE_SLPv1) ++ /*------------------------------------------------------------*/ ++ /* Create socket that will handle multicast UDP for SLPv1 */ ++ /* Service Location General Multicast address. */ ++ /*------------------------------------------------------------*/ ++ mcastaddr.s_addr = htonl(SLPv1_SL_MCAST_ADDRESS); ++ sock = SLPDSocketCreateBoundDatagram(&myaddr, ++ &mcastaddr, ++ DATAGRAM_MULTICAST); ++ if (sock) ++ { ++ SLPListLinkTail(&G_IncomingSocketList,(SLPListItem*)sock); ++ SLPDLog("SLPv1 Service Location General Multicast socket on %s ready\n", ++ inet_ntoa(myaddr)); ++ } ++ + if (G_SlpdProperty.isDA) + { + /*------------------------------------------------------------*/ diff --git a/ready b/ready new file mode 100644 index 0000000..473a0f4 diff --git a/slpd.init b/slpd.init new file mode 100644 index 0000000..cd4e5b8 --- /dev/null +++ b/slpd.init @@ -0,0 +1,72 @@ +#! /bin/sh +# Copyright (c) 2003 SuSE AG Nuernberg, Germany. +# +# Author: adrian@suse.de, based on template from source package +# +# /etc/init.d/slpd +# and its symbolic link +# /usr/sbin/rcslpd +# +### BEGIN INIT INFO +# Provides: openslp slpd +# Required-Start: $network $named +# Required-Stop: +# Default-Start: 3 5 +# Default-Stop: 0 1 2 4 6 +# Description: slpd - OpenSLP daemon for the Service Location Protocol +### END INIT INFO + +. /etc/rc.status + +# Determine the base and follow a runlevel link name. +base=${0##*/} +link=${base#*[SK][0-9][0-9]} + +# Force execution if not called by a runlevel directory. +test -x /usr/sbin/slpd || exit 0 + + +case "$1" in + start) + echo -n 'Starting slpd ' + startproc /usr/sbin/slpd + rc_status -v + ;; + stop) + echo -n "Shutting down slpd " + killproc -TERM /usr/sbin/slpd + rc_status -v + ;; + restart) + $0 stop + $0 start + rc_status + ;; + try-restart) + $0 status + if test $? = 0; then + $0 restart + else + rc_reset + fi + rc_status + ;; + force-reload) + $0 stop; sleep 1 && $0 start + rc_status + ;; + reload) + echo -n "Reload service slpd " + killproc -HUP /usr/sbin/slpd + rc_status -v + ;; + status) + echo -n "Checking for slpd " + checkproc /usr/sbin/slpd + rc_status -v + ;; + *) + echo "Usage: $0 {start|stop|try-restart|restart|force-reload|reload|status}" + exit 1 +esac +rc_exit diff --git a/slptool-timeout.diff b/slptool-timeout.diff new file mode 100644 index 0000000..14788a0 --- /dev/null +++ b/slptool-timeout.diff @@ -0,0 +1,11 @@ +--- slptool/slptool.c ++++ slptool/slptool.c 2004/01/14 12:26:12 +@@ -481,7 +481,7 @@ + + result = SLPReg(hslp, + cmdline->cmdparam1, +- SLP_LIFETIME_DEFAULT, ++ SLP_LIFETIME_MAXIMUM, + srvtype, + cmdline->cmdparam2, + SLP_TRUE, diff --git a/v1dadiscovery.diff b/v1dadiscovery.diff new file mode 100644 index 0000000..35f3a7b --- /dev/null +++ b/v1dadiscovery.diff @@ -0,0 +1,67 @@ +--- ./common/slp_v1message.c.orig 2002-12-03 21:04:50.000000000 +0000 ++++ ./common/slp_v1message.c 2004-12-03 18:48:44.740573934 +0000 +@@ -40,6 +40,7 @@ + + #include "slp_v1message.h" + #include "slp_utf8.h" ++#include "slp_compare.h" + + /* Implementation Note: + * +@@ -215,7 +216,8 @@ + srvrqst->predicate += srvrqst->srvtypelen + 1; + + /* Now split out the scope (if any) */ +- if(*srvrqst->predicate == '/') ++ /* Special case DA discovery, empty scope is allowed here */ ++ if(*srvrqst->predicate == '/' && SLPCompareString(srvrqst->srvtypelen, srvrqst->srvtype, 15, "directory-agent") != 0) + { + /* no scope - so set default scope */ + srvrqst->scopelist = "default"; +--- ./slpd/slpd_v1process.c.orig 2004-12-03 18:49:08.656163167 +0000 ++++ ./slpd/slpd_v1process.c 2004-12-03 19:10:09.159293506 +0000 +@@ -76,25 +76,32 @@ + int errorcode) + /*-------------------------------------------------------------------------*/ + { +- if (message->body.srvrqst.scopelistlen == 0 || +- SLPIntersectStringList(message->body.srvrqst.scopelistlen, +- message->body.srvrqst.scopelist, +- G_SlpdProperty.useScopesLen, +- G_SlpdProperty.useScopes)) ++ if (G_SlpdProperty.isDA) + { +- /* fill out real structure */ +- errorcode = SLPDKnownDAGenerateMyV1DAAdvert(errorcode, +- message->header.encoding, +- message->header.xid, +- sendbuf); ++ if (message->body.srvrqst.scopelistlen == 0 || ++ SLPIntersectStringList(message->body.srvrqst.scopelistlen, ++ message->body.srvrqst.scopelist, ++ G_SlpdProperty.useScopesLen, ++ G_SlpdProperty.useScopes)) ++ { ++ /* fill out real structure */ ++ errorcode = SLPDKnownDAGenerateMyV1DAAdvert(errorcode, ++ message->header.encoding, ++ message->header.xid, ++ sendbuf); ++ } ++ else ++ { ++ errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED; ++ } + } + else + { +- errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED; ++ errorcode = SLP_ERROR_MESSAGE_NOT_SUPPORTED; + } + + /* don't return errorcodes to multicast messages */ +- if (errorcode == 0) ++ if (errorcode != 0) + { + if (message->header.flags & SLP_FLAG_MCAST || + ISMCAST(peeraddr->sin_addr))