Пример #1
0
/** 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;
}
Пример #2
0
void CivArchive::PerformMagic(uint32 id)
	{
	PutUINT32(k_ARCHIVE_MAGIC_VALUE_1) ;
	PutUINT32(k_ARCHIVE_MAGIC_VALUE_2) ;
	PutUINT32(id) ;
	}
Пример #3
0
/** 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;
}