/*=========================================================================*/ void SLPDSocketInit(SLPDSocketList* list) /* Adds SLPSockets (UDP and TCP) for all the interfaces and the loopback */ /* */ /* list - pointer to SLPSocketList to initialize */ /* */ /* Returns - zero on success, -1 on failure. */ /*=========================================================================*/ { char* begin; char* end; int finished; struct in_addr myaddr; struct in_addr mcastaddr; struct in_addr bcastaddr; SLPDSocket* sock; /*----------------------------------------------------*/ /* Decide what address to use for multicast/broadcast */ /*----------------------------------------------------*/ mcastaddr.s_addr = htonl(SLP_MCAST_ADDRESS); bcastaddr.s_addr = htonl(0xffffffff); /*-----------------------------------------------------------------*/ /* Create SOCKET_LISTEN socket for LOOPBACK for the library to talk to*/ /*-----------------------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { return; } memset(sock,0,sizeof(SLPDSocket)); sock->fd = socket(PF_INET, SOCK_STREAM, 0); if(sock->fd >= 0) { if(BindSocketToLoopback(sock->fd) >= 0) { if(listen(sock->fd,5) == 0) { sock->state = SOCKET_LISTEN; if(SLPDSocketListAdd(list,sock) == 0) { SLPFatal("Out of memory"); } SLPLog("SLPLIB API socket listening\n"); } else { /* could not listen(), close the socket*/ close(sock->fd); free(sock); SLPLog("ERROR: Could not listen on loopback\n"); SLPLog("ERROR: No SLPLIB support will be available\n"); } } else { /* could not bind, close the socket*/ close(sock->fd); free(sock); SLPLog("ERROR: Could not bind loopback port 427.\n"); SLPLog("ERROR: slpd may already be running\n"); } } else { /* could not create the socket */ free(sock); SLPLog("ERROR: Could not create socket for loopback.\n"); SLPLog("ERROR: No SLPLIB support will be available\n"); } /*---------------------------------------------------------------------*/ /* Create sockets for all of the interfaces in the interfaces property */ /*---------------------------------------------------------------------*/ begin = (char*)G_SlpdProperty.interfaces; end = begin; finished = 0; while( finished == 0) { while(*end && *end != ',') end ++; if(*end == 0) finished = 1; while(*end <=0x2f) { *end = 0; end--; } /* begin now points to a null terminated ip address string */ myaddr.s_addr = inet_addr(begin); /*--------------------------------------------------------*/ /* Create socket that will handle multicast UDP */ /*--------------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { break; } sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >=0) { if(BindSocketToInetAddr(sock->fd, &mcastaddr) >= 0) { if(JoinSLPMulticastGroup(sock->fd, &myaddr) == 0) { sock->state = DATAGRAM_MULTICAST; sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->peerinfo.peeraddrlen = sizeof(sock->peerinfo.peeraddr); sock->peerinfo.peertype = SLPD_PEER_REMOTE; if(sock->recvbuf == 0 || sock->sendbuf == 0) { SLPFatal("SLPD out of memory !!\n"); } SLPDSocketListAdd(list,sock); SLPLog("Multicast socket on %s ready\n",inet_ntoa(myaddr)); } else { /* could not add multicast membership */ close(sock->fd); free(sock); } } else { /* could not bind(), close the socket*/ close(sock->fd); free(sock); } } /*--------------------------------------------*/ /* Create socket that will handle unicast UDP */ /*--------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { break; } sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >= 0) { if(BindSocketToInetAddr(sock->fd, &myaddr) >= 0) { sock->state = DATAGRAM_UNICAST; sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->peerinfo.peertype = SLPD_PEER_REMOTE; if(sock->recvbuf == 0 || sock->sendbuf == 0) { SLPFatal("SLPD out of memory !!\n"); } SLPDSocketListAdd(list,sock); SLPLog("UDP socket on %s ready\n",inet_ntoa(myaddr)); } else { /* could not bind(), close the socket*/ close(sock->fd); free(sock); } } /*------------------------------------------------*/ /* Create TCP_LISTEN that will handle unicast TCP */ /*------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { break; } sock->fd = socket(PF_INET, SOCK_STREAM, 0); if(sock->fd >= 0) { if(BindSocketToInetAddr(sock->fd, &myaddr) >= 0) { if(listen(sock->fd,2) == 0) { sock->state = SOCKET_LISTEN; if(SLPDSocketListAdd(list,sock) == 0) { SLPFatal("Out of memory"); } SLPLog("TCP socket on %s listening\n",inet_ntoa(myaddr)); } else { /* could not listen(), close the socket*/ close(sock->fd); free(sock); } } else { /* could not bind, close the socket*/ close(sock->fd); free(sock); } } begin = end + 1; } /*--------------------------------------------------------*/ /* Create socket that will handle broadcast UDP */ /*--------------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { return; } sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >=0) { if(BindSocketToInetAddr(sock->fd, &bcastaddr) >= 0) { if(EnableBroadcast(sock->fd) == 0) { sock->state = DATAGRAM_BROADCAST; sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->peerinfo.peeraddrlen = sizeof(sock->peerinfo.peeraddr); sock->peerinfo.peertype = SLPD_PEER_REMOTE; if(sock->recvbuf == 0 || sock->sendbuf == 0) { SLPFatal("SLPD out of memory !!\n"); } SLPDSocketListAdd(list,sock); SLPLog("Broadcast socket for %s ready\n", inet_ntoa(bcastaddr)); } else { /* could not add multicast membership */ close(sock->fd); free(sock); } } else { /* could not bind(), close the socket*/ close(sock->fd); free(sock); } } }
/*==========================================================================*/ SLPDSocket* SLPDSocketCreateBoundDatagram(struct in_addr* myaddr, struct in_addr* peeraddr, int type) /* myaddr - (IN) the address of the interface to join mcast on */ /* */ /* peeraddr - (IN) the address of the peer to connect to */ /* */ /* type (IN) DATAGRAM_UNICAST, DATAGRAM_MULTICAST, DATAGRAM_BROADCAST */ /* */ /* Returns: A datagram socket SLPDSocket->state will be set to */ /* DATAGRAM_UNICAST, DATAGRAM_MULTICAST, or DATAGRAM_BROADCAST */ /*==========================================================================*/ { SLPDSocket* sock; struct in_addr* bindaddr; /*------------------------------------------*/ /* 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) { sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >=0) { if(BindSocketToInetAddr(sock->fd, bindaddr) == 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; goto SUCCESS; } break; case DATAGRAM_BROADCAST: if(EnableBroadcast(sock->fd) == 0) { sock->state = DATAGRAM_BROADCAST; goto SUCCESS; } break; case DATAGRAM_UNICAST: default: sock->state = DATAGRAM_UNICAST; goto SUCCESS; break; } } } } if(sock) { SLPDSocketFree(sock); } sock = 0; SUCCESS: return sock; }