/** Formats and sends an SLPReg wire buffer request. * * @param handle - The OpenSLP session handle, containing request * parameters. See docs for SLPReg. * * @return Zero on success, or an SLP API error code. * * @internal */ static SLPError ProcessSrvReg(SLPHandleInfo * handle) { sockfd_t sock; uint8_t * buf; uint8_t * curpos; SLPError serr; size_t extoffset = 0; int urlauthlen = 0; uint8_t * urlauth = 0; int attrauthlen = 0; uint8_t * attrauth = 0; SLPBoolean watchRegPID; struct sockaddr_storage saaddr; #ifdef ENABLE_SLPv2_SECURITY if (SLPPropertyAsBoolean("net.slp.securityEnabled")) { int err = SLPAuthSignUrl(handle->hspi, 0, 0, handle->params.reg.urllen, handle->params.reg.url, &urlauthlen, &urlauth); if (err == 0) err = SLPAuthSignString(handle->hspi, 0, 0, handle->params.reg.attrlistlen, handle->params.reg.attrlist, &attrauthlen, &attrauth); if (err != 0) return SLP_AUTHENTICATION_ABSENT; } #endif /* Should we send the "Watch Registration PID" extension? */ watchRegPID = SLPPropertyAsBoolean("net.slp.watchRegistrationPID"); /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | <URL-Entry> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of service type string | <service-type> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of <scope-list> | <scope-list> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | length of attr-list string | <attr-list> \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |# of AttrAuths |(if present) Attribute Authentication Blocks...\ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | WATCH-PID extension ID | next extension offset \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | nxo (cont) | process identifier to be monitored \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | PID (cont) | +-+-+-+-+-+-+-+-+ */ buf = curpos = xmalloc( + SizeofURLEntry(handle->params.reg.urllen, urlauthlen) + 2 + handle->params.reg.srvtypelen + 2 + handle->params.reg.scopelistlen + 2 + handle->params.reg.attrlistlen + 1 + attrauthlen + (watchRegPID? (2 + 3 + 4): 0)); if (buf == 0) { xfree(urlauth); xfree(attrauth); return SLP_MEMORY_ALLOC_FAILED; } /* URL entry */ PutURLEntry(&curpos, handle->params.reg.lifetime, handle->params.reg.url, handle->params.reg.urllen, urlauth, urlauthlen); /* <service-type> */ PutL16String(&curpos, handle->params.reg.srvtype, handle->params.reg.srvtypelen); /* <scope-list> */ PutL16String(&curpos, handle->params.reg.scopelist, handle->params.reg.scopelistlen); /* <attr-list> */ PutL16String(&curpos, handle->params.reg.attrlist, handle->params.reg.attrlistlen); /** @todo Handle multiple attribute authentication blocks. */ /* Attribute Authentication Blocks */ *curpos++ = attrauth? 1: 0; memcpy(curpos, attrauth, attrauthlen); curpos += attrauthlen; /* SLP_EXTENSION_ID_REG_PID */ if (watchRegPID) { extoffset = curpos - buf; /** @todo In some future code base, this should be changed to use the * non-deprecated official version, SLP_EXTENSION_ID_REG_PID. For now * we need to use the EXPerimental version in order to interoperate * properly with OpenSLP 1.x SA's. */ PutUINT16(&curpos, SLP_EXTENSION_ID_REG_PID_EXP); PutUINT24(&curpos, 0); PutUINT32(&curpos, SLPPidGet()); } /* Call the Request-Reply engine. */ sock = NetworkConnectToSA(handle, handle->params.reg.scopelist, handle->params.reg.scopelistlen, &saaddr); if (sock != SLP_INVALID_SOCKET) { serr = NetworkRqstRply(sock, &saaddr, handle->langtag, extoffset, buf, SLP_FUNCT_SRVREG, curpos - buf, CallbackSrvReg, handle); if (serr) NetworkDisconnectSA(handle); } else serr = SLP_NETWORK_INIT_FAILED; xfree(buf); xfree(urlauth); xfree(attrauth); return serr; }
void CivArchive::PerformMagic(uint32 id) { PutUINT32(k_ARCHIVE_MAGIC_VALUE_1) ; PutUINT32(k_ARCHIVE_MAGIC_VALUE_2) ; PutUINT32(id) ; }
/** Queries a DHCP server and calls a callback once for each option. * * Queries the sub-net DHCP server for a specified set of DHCP options * and then calls a user-supplied callback function once for each of * the desired options returned by the server. * * @param[in] dhcpOptCodes - An array of option codes to query for. * @param[in] dhcpOptCodeCnt - The number of elements in @p dhcpOptCodes. * @param[in] dhcpInfoCB - The callback function to call for each option. * @param[in] context - callback context. * * @return Zero on success; non-zero on failure, with errno set to * ENOTCONN (read error), ETIMEDOUT (read timeout), ENOMEM (out of * memory), or EINVAL (on parse error). */ int DHCPGetOptionInfo(unsigned char * dhcpOptCodes, int dhcpOptCodeCnt, DHCPInfoCallBack * dhcpInfoCB, void * context) { uint32_t xid; time_t timer; struct timeval tv; sockfd_t sockfd; int retries; struct sockaddr_storage sendaddr; unsigned char chaddr[MAX_MACADDR_SIZE]; unsigned char hlen, htype; uint8_t sndbuf[512]; uint8_t rcvbuf[512]; struct hostent * hep; uint8_t * p; int rcvbufsz = 0; char host[256]; /* Get our IP and MAC addresses */ if (gethostname(host, (int)sizeof(host)) || (hep = gethostbyname(host)) == 0 || dhcpGetAddressInfo((unsigned char *)hep->h_addr, chaddr, &hlen, &htype)) return -1; /* get a reasonably random transaction id value */ xid = (uint32_t)time(&timer); /* BOOTP request header */ p = sndbuf; *p++ = BOOTREQUEST; /* opcode */ *p++ = htype; *p++ = hlen; *p++ = 0; /* hops */ PutUINT32(&p, xid); PutUINT16(&p, 0); /* seconds */ PutUINT16(&p, 0); /* flags */ memcpy(p, hep->h_addr, 4); /* ciaddr */ p += 4; PutUINT32(&p, 0); /* yiaddr */ PutUINT32(&p, 0); /* siaddr */ PutUINT32(&p, 0); /* giaddr */ memcpy(p, chaddr, hlen); /* chaddr */ p += hlen; memset(p, 0, 16-hlen); /* remaining chaddr space */ p += 16-hlen; memset(p, 0, 64 + 128); /* server host name, boot file */ p += 64 + 128; /* BOOTP options field */ *p++ = DHCP_COOKIE1; /* options, cookies 1-4 */ *p++ = DHCP_COOKIE2; *p++ = DHCP_COOKIE3; *p++ = DHCP_COOKIE4; /* DHCP Message Type option */ *p++ = TAG_DHCP_MSG_TYPE; *p++ = 1; /* option length */ *p++ = DHCP_MSG_INFORM; /* message type is DHCPINFORM */ /* DHCP Parameter Request option */ *p++ = TAG_DHCP_PARAM_REQ; /* request for DHCP parms */ *p++ = (unsigned char)dhcpOptCodeCnt; memcpy(p, dhcpOptCodes, dhcpOptCodeCnt); p += dhcpOptCodeCnt; /* DHCP Client Identifier option */ *p++ = TAG_CLIENT_IDENTIFIER; *p++ = hlen + 1; /* option length */ *p++ = htype; /* client id is htype/haddr */ memcpy(p, chaddr, hlen); p += hlen; /* End option */ *p++ = TAG_END; /* get a broadcast send/recv socket and address */ if ((sockfd = dhcpCreateBCSkt(&sendaddr)) == SLP_INVALID_SOCKET) return -1; /* setup select timeout */ tv.tv_sec = 0; tv.tv_usec = INIT_TMOUT_USECS; retries = 0; srand((unsigned)time(&timer)); while (retries++ < MAX_DHCP_RETRIES) { if (dhcpSendRequest(sockfd, sndbuf, p - sndbuf, &sendaddr, sizeof(sendaddr), &tv) < 0) { if (errno != ETIMEDOUT) { closesocket(sockfd); return -1; } } else if ((rcvbufsz = dhcpRecvResponse(sockfd, rcvbuf, sizeof(rcvbuf), &tv)) < 0) { if (errno != ETIMEDOUT) { closesocket(sockfd); return -1; } } else if (rcvbufsz >= 236 && AS_UINT32(&rcvbuf[4]) == xid) break; /* exponential backoff randomized by a * uniform number between -1 and 1 */ tv.tv_usec = tv.tv_usec * 2 + (rand() % 3) - 1; tv.tv_sec = tv.tv_usec / USECS_PER_SEC; tv.tv_usec %= USECS_PER_SEC; } closesocket(sockfd); return rcvbufsz? dhcpProcessOptions(rcvbuf + 236, rcvbufsz - 236, dhcpInfoCB, context): -1; }