Esempio n. 1
0
int main(void)
{
   SLPIfaceInfo ifaceinfo;
   SLPIfaceInfo ifaceinfo6;
   SLPXcastSockets socks;
   SLPBuffer buffer;
   /* multicast srvloc address */
   uint8_t v6Addr[] = {0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x16};
   struct sockaddr_storage dst;
   int mtu;

#ifdef _WIN32
   WSADATA wsadata;
   WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif

   mtu = SLPPropertyGetMTU();
   //const struct in6_addr in6addr;
   buffer = SLPBufferAlloc(mtu);
   if (buffer)
   {
      strcpy((char *)buffer->start, "testdata");

      SLPIfaceGetInfo(NULL,&ifaceinfo, AF_INET);
      SLPIfaceGetInfo(NULL,&ifaceinfo6, AF_INET6);

      if (SLPBroadcastSend(&ifaceinfo, buffer, &socks) !=0)
         printf("\n SLPBroadcastSend failed \n");
      SLPXcastSocketsClose(&socks);

      /* for v6 */
      if (SLPBroadcastSend(&ifaceinfo6, buffer,&socks) !=0)
         printf("\n SLPBroadcastSend failed for ipv6\n");
      SLPXcastSocketsClose(&socks);

      if (SLPMulticastSend(&ifaceinfo, buffer, &socks, 0) !=0)
         printf("\n SLPMulticast failed \n");
      SLPXcastSocketsClose(&socks);

      /* set up address and scope for v6 multicast */
      SLPNetSetAddr(&dst, AF_INET6, 0, (uint8_t *)v6Addr);
      if (SLPMulticastSend(&ifaceinfo6, buffer, &socks, &dst) !=0)
         printf("\n SLPMulticast failed for ipv\n");
      SLPXcastSocketsClose(&socks);

      printf("Success\n");

      SLPBufferFree(buffer);
   }

#ifdef _WIN32
   WSACleanup();
#endif

   return 0;
}
Esempio n. 2
0
/** Create a DHCP broadcast socket.
 *
 * Creates a socket and provides a broadcast addr to which DHCP requests
 * should be sent. Also binds the socket to the DHCP client port.
 *
 * @param[out] peeraddr - A pointer to receive the address to which 
 *    DHCP requests are to be sent.
 *
 * @return A valid socket, or -1 if no DA connection can be made.
 * 
 * @internal
 */
static sockfd_t dhcpCreateBCSkt(void * peeraddr) 
{
   sockfd_t sockfd;
   so_bool_t on = 1;

   /* setup dhcp broadcast-to-server address structure */
   if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != SLP_INVALID_SOCKET)
   {
      int addr = INADDR_ANY;
      struct sockaddr_storage localaddr;

      SLPNetSetAddr(&localaddr, AF_INET, IPPORT_BOOTPC, &addr);
      if (bind(sockfd, (struct sockaddr *)&localaddr, sizeof(localaddr))
            || setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
                  (char *)&on, sizeof(on)))
      {
         closesocket(sockfd);
         return SLP_INVALID_SOCKET;
      }
      addr = INADDR_BROADCAST;
      SLPNetSetAddr(peeraddr, AF_INET, IPPORT_BOOTPS, &addr);
   }
   return sockfd;
}
Esempio n. 3
0
/** Broadcast a message.
 *
 * @param[in] ifaceinfo - A pointer to the SLPIfaceInfo structure that 
 *    contains information about the interfaces on which to send.
 * @param[in] msg - The buffer to be sent.
 * @param[out] socks - The address of storage for returning the sockets
 *    that were used to broadcast. 
 *
 * @return Zero on sucess, or a non-zero value with @a errno set on error.
 *
 * @remarks The sockets returned in @p socks may be used to receive 
 *    responses. Must be close by caller using SLPXcastSocketsClose.
 */                        
int SLPBroadcastSend(const SLPIfaceInfo * ifaceinfo, 
      const SLPBuffer msg, SLPXcastSockets * socks)
{
   int xferbytes;
   so_bool_t on = 1;

   for (socks->sock_count = 0; 
         socks->sock_count < ifaceinfo->bcast_count; 
         socks->sock_count++)
   {
      if (ifaceinfo[socks->sock_count].bcast_addr->ss_family == AF_INET) 
      {
         socks->sock[socks->sock_count] = socket(ifaceinfo[socks->sock_count]
               .bcast_addr->ss_family, SOCK_DGRAM, 0);

         if (socks->sock[socks->sock_count] == SLP_INVALID_SOCKET)
            return -1;  /* error creating socket */

         SLPNetworkSetSndRcvBuf(socks->sock[socks->sock_count]);

         if (setsockopt(socks->sock[socks->sock_count], SOL_SOCKET,
               SO_BROADCAST, &on, sizeof(on)) != 0)
            return -1;  /* Error setting socket option */

         memcpy(&socks->peeraddr[socks->sock_count], 
               &ifaceinfo->bcast_addr[socks->sock_count], 
               sizeof(ifaceinfo->bcast_addr[socks->sock_count]));

         SLPNetSetAddr(&socks->peeraddr[socks->sock_count], AF_INET, 
               (uint16_t)SLPPropertyAsInteger("net.slp.port"), 0);
         xferbytes = sendto(socks->sock[socks->sock_count],
               (char *)msg->start, (int)(msg->end - msg->start), 0, 
               (struct sockaddr *)&socks->peeraddr[socks->sock_count],
               SLPNetAddrLen(&socks->peeraddr[socks->sock_count]));
         if (xferbytes  < 0)
            return -1;  /* Error sending to broadcast */
      }
      else 
         socks->sock[socks->sock_count] = 0; /* assume bcast for IPV4 only */
   }
   return 0;
}
Esempio n. 4
0
int main(int argc, char * argv[])
{
   char addrString[1024];
   int sts;
   int errorCount = 0;
   struct sockaddr_storage addr;

#ifdef _WIN32
   WSADATA wsadata;
   WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif

   sts = SLPNetResolveHostToAddr("localhost", &addr);
   if (sts != 0)
   {
      printf("error %d with SLPNetResolveHostToAddr.\r\n", sts);
      errorCount++;
   }
   else
   {
      printf("addr family = %d\r\n", addr.ss_family);
      SLPNetSockAddrStorageToString(&addr, addrString, sizeof(addrString));
      printf("address = %s\r\n", addrString);
   }

   sts = SLPNetResolveHostToAddr("::1", &addr);
   if (sts != 0)
   {
      printf("error %d with SLPNetResolveHostToAddr.\r\n", sts);
      errorCount++;
   }
   else
   {
      printf("addr family = %d\r\n", addr.ss_family);
      SLPNetSockAddrStorageToString(&addr, addrString, sizeof(addrString));
      printf("address = %s\r\n", addrString);
   }

   sts = SLPPropertyReadFile("e:\\source\\Hogwarts_ActiveX\\OpenSLP\\"
                         "ipv6\\win32\\slpd\\slp.conf");
   if (sts == 0)
      printf("Read config file\r\n");
   else
      printf("No config file found - using defaults.\r\n");

   sts = SLPNetIsIPV6();
   if (sts == 0)
      printf("Not using ipv6\r\n");
   else
      printf("Using ipv6\r\n");

   sts = SLPNetIsIPV4();
   if (sts == 0)
      printf("Not using ipv4\r\n");
   else
      printf("Using ipv4\r\n");
   {
      struct sockaddr_storage a1;
      struct sockaddr_storage a2;
      char testaddr[] = "1:2:3:4:5::6";
      struct sockaddr_in * p41 = (struct sockaddr_in *)&a1;
      struct sockaddr_in6 * p61 = (struct sockaddr_in6 *)&a1;
      struct sockaddr_in * p42 = (struct sockaddr_in *)&a2;
      struct sockaddr_in6 * p62 = (struct sockaddr_in6 *)&a2;

      memset(&a1, 0, sizeof(a1));
      memset(&a2, 0, sizeof(a2));
      SLPNetSetAddr(&a1, AF_INET6, 2, testaddr, sizeof(testaddr));
      memcpy(&a2, &a1, sizeof(a1));
      sts = SLPNetCompareAddrs(&a1, &a2);
      if (sts != 0)
         printf("Error, address a1 does not equal a2 - copy failed\r\n");
      memset(&a2, 0, sizeof(a2));
      a2.ss_family = AF_INET6;
      memcpy(p62->sin6_addr.s6_addr, testaddr, sizeof(testaddr));
      p62->sin6_family = AF_INET6;
      p62->sin6_port = htons(2);
      sts = SLPNetCompareAddrs(&a1, &a2);
      if (sts != 0)
         printf("Error, address a1 does not equal a2\r\n");
   }
   /* now test the ipv6 expansion */
   {
      char t1[] = "::";
      char a1[] = "0000:0000:0000:0000:0000:0000:0000:0000";

      char t2[] = "1::";
      char a2[] = "0001:0000:0000:0000:0000:0000:0000:0000";

      char t3[] = "::1";
      char a3[] = "0000:0000:0000:0000:0000:0000:0000:0001";

      char t4[] = "12::34";
      char a4[] = "0012:0000:0000:0000:0000:0000:0000:0034";

      char t5[] = "1111:2222:3333::5555:6666:7777:8888";
      char a5[] = "1111:2222:3333:0000:5555:6666:7777:8888";

      char t6[] = "1:02::003:0004";
      char a6[] = "0001:0002:0000:0000:0000:0000:0003:0004";

      char t7[] = "0001:0002:0003:0004:0005:0006:0007:0008";
      char a7[] = "0001:0002:0003:0004:0005:0006:0007:0008";

      char t8[] = "1:02:003:0004:0005:006:07:8";
      char a8[] = "0001:0002:0003:0004:0005:0006:0007:0008";

      char i1[] = "1::2::3";
      char i2[] = "1:::3";

      char buf[40];  /* min buf size - 8*4 + 7 + null */
      int sts;

      sts = SLPNetExpandIpv6Addr(t1, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a1) != 0))
         printf("Error expanding ipv6 address t1\r\n");

      sts = SLPNetExpandIpv6Addr(t2, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a2) != 0))
         printf("Error expanding ipv6 address t2\r\n");

      sts = SLPNetExpandIpv6Addr(t3, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a3) != 0))
         printf("Error expanding ipv6 address t3\r\n");

      sts = SLPNetExpandIpv6Addr(t4, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a4) != 0))
         printf("Error expanding ipv6 address t4\r\n");

      sts = SLPNetExpandIpv6Addr(t5, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a5) != 0))
         printf("Error expanding ipv6 address t5\r\n");

      sts = SLPNetExpandIpv6Addr(t6, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a6) != 0))
         printf("Error expanding ipv6 address t6\r\n");

      sts = SLPNetExpandIpv6Addr(t7, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a7) != 0))
         printf("Error expanding ipv6 address t7\r\n");

      sts = SLPNetExpandIpv6Addr(t8, buf, sizeof(buf));
      if ((sts != 0) || (strcmp(buf, a8) != 0))
         printf("Error expanding ipv6 address t8\r\n");

      sts = SLPNetExpandIpv6Addr(i1, buf, sizeof(buf));
      sts = SLPNetExpandIpv6Addr(i2, buf, sizeof(buf));
      sts = SLPNetExpandIpv6Addr(t6, buf, 5);
      if (sts == 0)
         printf("Error, size not checked for expansion\r\n");
   }

   /* int SLPNetIsMCast(const struct sockaddr_storage *addr);
    * int SLPNetIsLocal(const struct sockaddr_storage *addr);
    */

#ifdef _WIN32
   WSACleanup();
#endif
}
Esempio n. 5
0
/** Process a DA service request message.
 *
 * @param[in] message - The message to process.
 * @param[out] sendbuf - The response buffer to fill.
 * @param[in] errorcode - The error code from the client request.
 *
 * @return Zero on success, or a non-zero SLP error on failure.
 *
 * @internal
 */
static int ProcessDASrvRqst(SLPMessage * message, SLPBuffer * sendbuf, int errorcode)
{
   SLPBuffer tmp = 0;
   SLPMessage * msg = 0;
   void * eh = 0;
   /* TODO should really be a configurable property, maybe G_SlpdProperty.MTU? Left at 4096 to retain same behaviour */
   size_t initial_buffer_size = 4096;
   size_t grow_size = initial_buffer_size;

   /* Special case for when libslp asks slpd (through the loopback) about
      a known DAs. Fill sendbuf with DAAdverts from all known DAs.        
    */
   if (SLPNetIsLoopback(&message->peer))
   {
      *sendbuf = SLPBufferRealloc(*sendbuf, initial_buffer_size);
      if (*sendbuf == 0)
         return SLP_ERROR_INTERNAL_ERROR;

      if (errorcode == 0)
      {
         /* Note: The weird *sendbuf code is making a single SLPBuffer
            that contains multiple DAAdverts.  This is a special
            process that only happens for the DA SrvRqst through
            loopback to the SLPAPI
          */

         /*If we are a DA, always have ourself at the start of the list, so the
           lib requests can be handled locally for speed */
         if(G_SlpdProperty.isDA)
         {
            struct sockaddr_storage loaddr;

            if(SLPNetIsIPV4())
            {
               int addr = INADDR_LOOPBACK;
               SLPNetSetAddr(&loaddr, AF_INET, G_SlpdProperty.port, &addr);
            }
            else
			{
               SLPNetSetAddr(&loaddr, AF_INET6, G_SlpdProperty.port, &slp_in6addr_loopback);
			}

            if(0 == SLPDKnownDAGenerateMyDAAdvert(&loaddr, 0, 0, 0, message->header.xid, &tmp))
            {
               memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
               (*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);
               SLPBufferFree(tmp);
               tmp = 0;
            }
			else 
			{
				SLPDLog("Unable to add initial DAAdvert due to error\n");
			}
         }

         eh = SLPDKnownDAEnumStart();
         if (eh)
         {
            while (1)
            {
               /* iterate over all database entries */
               if (SLPDKnownDAEnum(eh, &msg, &tmp) == 0) 
			   {
                  break;
			   }

               /* if we resize succesfully.. */
               if( CheckAndResizeBuffer(sendbuf, tmp, grow_size) == 0 )
               {
            	   /* buffer should now be resized to an appropriate size to handle all current database entries */

                   /* TRICKY: Fix up the XID and clear the flags. */
                   tmp->curpos = tmp->start + 10;
                   TO_UINT16(tmp->curpos, message->header.xid);
                   if (*(tmp->start) == 1)
                       *(tmp->start + 4) = 0;
                   else
                       TO_UINT16(tmp->start + 5, 0);   

    			   /* copy all data out of tmp into the sendbuf */
                   memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
    			   /* increment the current position in sendbuf */
                   (*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);
               }
               else
               {
            	   errorcode = SLP_ERROR_INTERNAL_ERROR;
               }
            }
            SLPDKnownDAEnumEnd(eh);
         }
 		/* tmp can store database entries which should not be freed by anyone else so reset the pointer to prevent double deletion */
 		tmp = 0;

 		/* Tack on a "terminator" DAAdvert
 		   Note that this function *always* returns the error code passed as its second parameter (or SLP_ERROR_INTERNAL_ERROR if the buffer fails to resize)
 		   The errorcode is also inserted into the srvrply header by this function
 		*/
 		SLPDKnownDAGenerateMyDAAdvert(&message->localaddr, SLP_ERROR_INTERNAL_ERROR, 0, 0, message->header.xid, &tmp);

 		/* if we resize succesfully.. */
        if ( CheckAndResizeBuffer(sendbuf, tmp, grow_size) == 0 )
        {
     		memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
     		(*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);

     		/* mark the end of the sendbuf */
     		(*sendbuf)->end = (*sendbuf)->curpos;

        }
        else
        {
     	   errorcode = SLP_ERROR_INTERNAL_ERROR;
        }

        SLPBufferFree(tmp);
 		tmp = 0;
      }
      return errorcode;
   }
   
   /* Normal case where a remote Agent asks for a DA */

   *sendbuf = SLPBufferRealloc(*sendbuf, G_SlpdProperty.MTU);
   if (*sendbuf == 0)
      return SLP_ERROR_INTERNAL_ERROR;
   if (G_SlpdProperty.isDA)
   {
      if (message->body.srvrqst.scopelistlen == 0 
            || SLPIntersectStringList(message->body.srvrqst.scopelistlen,
                  message->body.srvrqst.scopelist, G_SlpdProperty.useScopesLen,
                  G_SlpdProperty.useScopes))
      {
         errorcode = SLPDKnownDAGenerateMyDAAdvert(&message->localaddr, 
               errorcode, 0, 0, message->header.xid, sendbuf);           
      }
      else
         errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
   }
   else
      errorcode = SLP_ERROR_MESSAGE_NOT_SUPPORTED;       

   /* don't return errorcodes to multicast messages */
   if (errorcode != 0)
   {
      if (message->header.flags & SLP_FLAG_MCAST 
            || SLPNetIsMCast(&(message->peer)))
         (*sendbuf)->end = (*sendbuf)->start;
   }
   return errorcode;
}
Esempio n. 6
0
/** Get the network interface addresses for this host.
 * 
 * Returns either a complete list or a subset of the list of network interface 
 * addresses for this host. If the user specifies a list, then network interfaces
 *
 * @param[in] useifaces - Pointer to comma delimited string of interface 
 *    IPv4 addresses to get interface information for. Pass 0 or the empty 
 *    string to get all interfaces (except the loopback interface).
 * @param[out] ifaceinfo - The address of a buffer in which to return 
 *    information about the requested interfaces.
 * @param[in] family - A hint indicating the address family to get info 
 *    for - can be AF_INET, AF_INET6, or AF_UNSPEC for both.
 *
 * @return Zero on success; A non-zero value (with errno set) on error.
 *
 * @remarks Does NOT return the loopback interface.
 */
int SLPIfaceGetInfo(const char * useifaces, SLPIfaceInfo * ifaceinfo,
      int family)
{
   size_t useifaceslen = useifaces? strlen(useifaces): 0;
   int sts = 0;

   ifaceinfo->iface_count = 0;
   ifaceinfo->bcast_count = 0;

   if (!useifaceslen)
   {
      /* no specified list - get all available interface addresses */
      if (SLPIfaceGetDefaultInfo(ifaceinfo, family) != 0)
         return -1;
   }
   else
   {
      /* list specified: parse it and use it */
      /* only allow addresses in configured address set */
      char * p = SLPPropertyXDup("net.slp.interfaces");

      /* If there are no configured addresses, use the passed in addresses*/
      if(p && (0 == strlen(p)))
      {
         xfree(p);
         p = xstrdup(useifaces);
      }

      if (p)
      {
         char * ep = p + strlen(p);
         char * slider1 = p;
         char * slider2 = p;

         while (slider1 < ep)
         {
            while (*slider2 != 0 && *slider2 != ',') 
               slider2++;
            *slider2 = 0;

            if (SLPIfaceContainsAddr(useifaceslen, useifaces, 
                  strlen(slider1), slider1))
            {
               sockfd_t fd;
               struct sockaddr_in v4addr;
               struct sockaddr_in6 v6addr;

               /* check if an ipv4 address was given */
               if (inet_pton(AF_INET, slider1, &v4addr.sin_addr) == 1)
               {
                  if (SLPNetIsIPV4() && ((family == AF_INET) || (family == AF_UNSPEC)))
                  {
                     fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                     if (fd != SLP_INVALID_SOCKET)
                     {
                        v4addr.sin_family = AF_INET;
                        v4addr.sin_port = 0;
                        memset(v4addr.sin_zero, 0, sizeof(v4addr.sin_zero));
                        if ((sts = bind(fd, (struct sockaddr *)&v4addr, sizeof(v4addr))) == 0)
                           memcpy(&ifaceinfo->iface_addr[ifaceinfo->iface_count++],
                                 &v4addr, sizeof(v4addr));
                        closesocket(fd);
                     }
                  }
               }
               else if (inet_pton(AF_INET6, slider1, &v6addr.sin6_addr) == 1)
               {
                  if (SLPNetIsIPV6() && ((family == AF_INET6) || (family == AF_UNSPEC)))
                  {
                     v6addr.sin6_family = AF_INET6;
                     v6addr.sin6_port = 0;
                     v6addr.sin6_flowinfo = 0;
                     if((sts = GetV6Scope(&v6addr)) == 0)
                          memcpy(&ifaceinfo->iface_addr[ifaceinfo->iface_count++],
                                    &v6addr, sizeof(v6addr));
                  }
               }
               else
                  sts = (errno = EINVAL), -1;   /* not v4, not v6 */
            }
            slider1 = ++slider2;
         }
      }
      xfree(p);
   }

   /* now stuff in a v4 broadcast address */
   if (SLPNetIsIPV4() && ((family == AF_INET) || (family == AF_UNSPEC)))
   {
      struct sockaddr_storage sa;
      char * str = SLPPropertyXDup("net.slp.broadcastAddr");

      if (!str || !*str)
      {
         unsigned long addr = INADDR_BROADCAST;

         SLPNetSetAddr(&sa, AF_INET, 0, &addr);
         memcpy(&ifaceinfo->bcast_addr[ifaceinfo->bcast_count++], &sa, sizeof(sa));
      }
      else
      {
         unsigned long addr;

         if (inet_pton(AF_INET, str, &addr) == 1)
         {
            SLPNetSetAddr(&sa, AF_INET, 0, &addr);
            memcpy(&ifaceinfo->bcast_addr[ifaceinfo->bcast_count++], &sa, sizeof(sa));
         }
      }
      xfree(str);
   }
   return sts;
}