📄 slpd_socket.c
字号:
/***************************************************************************//* *//* Project: OpenSLP - OpenSource implementation of Service Location *//* Protocol Version 2 *//* *//* File: slpd_socket.c *//* *//* Abstract: Socket specific functions implementation *//* *//* WARNING: NOT thread safe! *//*-------------------------------------------------------------------------*//* *//* Please submit patches to http://www.openslp.org *//* *//*-------------------------------------------------------------------------*//* *//* Copyright (C) 2000 Caldera Systems, Inc *//* All rights reserved. *//* *//* Redistribution and use in source and binary forms, with or without *//* modification, are permitted provided that the following conditions are *//* met: */ /* *//* Redistributions of source code must retain the above copyright *//* notice, this list of conditions and the following disclaimer. *//* *//* Redistributions in binary form must reproduce the above copyright *//* notice, this list of conditions and the following disclaimer in *//* the documentation and/or other materials provided with the *//* distribution. *//* *//* Neither the name of Caldera Systems nor the names of its *//* contributors may be used to endorse or promote products derived *//* from this software without specific prior written permission. *//* *//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *//* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *//* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *//* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA *//* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *//* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *//* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *//* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* *//***************************************************************************//*=========================================================================*//* slpd includes *//*=========================================================================*/#include "slpd_socket.h"#include "slpd_property.h"/*=========================================================================*//* common code includes *//*=========================================================================*/#include "slp_message.h"#include "slp_xmalloc.h"/*-------------------------------------------------------------------------*/int EnableBroadcast(sockfd_t sockfd)/* Sets the socket options to receive broadcast traffic *//* *//* sockfd - the socket file descriptor to set option on *//* *//* returns - zero on success *//*-------------------------------------------------------------------------*/{#ifdef _WIN32 const char on = 1;#else const int on = 1; #endif return setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));}/*-------------------------------------------------------------------------*/int SetMulticastTTL(sockfd_t sockfd, int ttl)/* Set the socket options for ttl *//* *//* sockfd - the socket file descriptor to set option on *//* *//* returns - zero on success *//*-------------------------------------------------------------------------*/{#if defined(linux) int optarg = ttl;#else /* Solaris and Tru64 expect a unsigned char parameter */ unsigned char optarg = (unsigned char)ttl;#endif#ifdef _WIN32 BOOL Reuse = TRUE; int TTLArg; struct sockaddr_in mysockaddr; memset(&mysockaddr, 0, sizeof(mysockaddr)); mysockaddr.sin_family = AF_INET; mysockaddr.sin_port = 0; TTLArg = ttl; if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&Reuse, sizeof(Reuse)) || bind(sockfd, (struct sockaddr *)&mysockaddr, sizeof(mysockaddr)) || setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&TTLArg, sizeof(TTLArg))) { return -1; }#else if(setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_TTL,&optarg,sizeof(optarg))) { return -1; }#endif return 0;}/*-------------------------------------------------------------------------*/int JoinSLPMulticastGroup(sockfd_t sockfd, struct in_addr* maddr, struct in_addr* addr)/* Sets the socket options to receive multicast traffic from the specified *//* interface. *//* *//* sockfd - the socket file descriptor to set the options on. *//* *//* maddr - pointer to multicast group to join *//* *//* addr - pointer to address of the interface to join on *//* *//* returns - zero on success *//*-------------------------------------------------------------------------*/{ struct ip_mreq mreq; /* join using the multicast address passed in */ memcpy(&mreq.imr_multiaddr, maddr, sizeof(struct in_addr)); /* join with specified interface */ memcpy(&mreq.imr_interface, addr, sizeof(struct in_addr)); return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)); }/*-------------------------------------------------------------------------*/int DropSLPMulticastGroup(sockfd_t sockfd, struct in_addr* maddr, struct in_addr* addr)/* Sets the socket options to not receive multicast traffic from the *//* specified interface. *//* *//* sockfd - the socket file descriptor to set the options on. *//* *//* maddr - pointer to the multicast address *//* *//* addr - pointer to the multicast address *//*-------------------------------------------------------------------------*/{ struct ip_mreq mreq; /* drop from the multicast group passed in */ memcpy(&mreq.imr_multiaddr, maddr, sizeof(struct in_addr)); /* drop for the specified interface */ memcpy(&mreq.imr_interface,addr,sizeof(addr)); return setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&mreq,sizeof(mreq)); }/*-------------------------------------------------------------------------*/int BindSocketToInetAddr(int sock, struct in_addr* addr)/* Binds the specified socket to the SLP port and interface. *//* *//* sock - the socket to be bound *//* *//* addr - the in_addr to bind to. *//* *//* Returns - zero on success, -1 on error. *//*-------------------------------------------------------------------------*/{ int result;#ifdef _WIN32 char lowat; BOOL reuse = TRUE;#else int lowat; int reuse = 1;#endif struct sockaddr_in mysockaddr; memset(&mysockaddr, 0, sizeof(mysockaddr)); mysockaddr.sin_family = AF_INET; mysockaddr.sin_port = htons(SLP_RESERVED_PORT); setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&reuse,sizeof(reuse)); if(addr != NULL) { mysockaddr.sin_addr = *addr; } else { mysockaddr.sin_addr.s_addr = INADDR_ANY; } result = bind(sock, (struct sockaddr *) &mysockaddr,sizeof(mysockaddr)); if(result == 0) { /* set the receive and send buffer low water mark to 18 bytes (the length of the smallest slpv2 message) */ lowat = 18; setsockopt(sock,SOL_SOCKET,SO_RCVLOWAT,&lowat,sizeof(lowat)); setsockopt(sock,SOL_SOCKET,SO_SNDLOWAT,&lowat,sizeof(lowat)); } return result;}/*-------------------------------------------------------------------------*/int BindSocketToLoopback(int sock)/* Binds the specified socket to the specified port of the loopback *//* interface. *//* *//* sock - the socket to be bound *//* *//* Returns - zero on success, -1 on error. *//*-------------------------------------------------------------------------*/{ struct in_addr loaddr; loaddr.s_addr = htonl(LOOPBACK_ADDRESS); return BindSocketToInetAddr(sock,&loaddr);}/*=========================================================================*/SLPDSocket* SLPDSocketAlloc()/* Allocate memory for a new SLPDSocket. *//* *//* Returns: pointer to a newly allocated SLPDSocket, or NULL if out of *//* memory. *//*=========================================================================*/{ SLPDSocket* sock; sock = (SLPDSocket*)xmalloc(sizeof(SLPDSocket)); if(sock) { memset(sock,0,sizeof(SLPDSocket)); sock->fd = -1; } return sock;}/*=========================================================================*/void SLPDSocketFree(SLPDSocket* sock)/* Frees memory associated with the specified SLPDSocket *//* *//* sock (IN) pointer to the socket to free *//*=========================================================================*/{ /* close the socket descriptor */ CloseSocket(sock->fd); /* free receive buffer */ if(sock->recvbuf) { SLPBufferFree(sock->recvbuf); } /* free send buffer(s) */ if(sock->sendlist.count) { while(sock->sendlist.count) { SLPBufferFree((SLPBuffer)SLPListUnlink(&(sock->sendlist), sock->sendlist.head)); } } if(sock->sendbuf) { SLPBufferFree(sock->sendbuf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -