mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
904 lines
18 KiB
904 lines
18 KiB
/*++
|
|
|
|
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR
|
|
A PARTICULAR PURPOSE.
|
|
|
|
Copyright (c) 1994 Microsoft Corporation. All Rights Reserved.
|
|
|
|
Module Name:
|
|
|
|
sockif.c
|
|
|
|
Abstract:
|
|
|
|
Sockets interface for the Portable Interoperability Tester.
|
|
|
|
Revision History:
|
|
|
|
Version When What
|
|
-------- -------- ----------------------------------------------
|
|
0.1 04-13-94 Created.
|
|
1.0 01-31-95 All '94 bakeoff changes plus some cleanup.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
#ifdef SOCKETS
|
|
|
|
#include <pit.h>
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Type definitions for Windows & Windows NT
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef WIN32
|
|
|
|
/* SOCKET_ERROR is already defined in Windows Sockets */
|
|
|
|
WSADATA WsaData;
|
|
|
|
#define CLOSE_SOCKET closesocket
|
|
|
|
#endif /* WIN32 */
|
|
|
|
#ifdef WIN16
|
|
|
|
#define ERROR_INVALID_USER_BUFFER 1784
|
|
#define ERROR_INVALID_PARAMETER 87
|
|
|
|
#endif /* WIN16 */
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Type definitions for Un*x
|
|
*
|
|
****************************************************************************/
|
|
#ifdef UNX
|
|
|
|
#define SOCKET_ERROR -1
|
|
|
|
#ifndef INADDR_NONE
|
|
#define INADDR_NONE -1
|
|
#endif
|
|
|
|
#define CLOSE_SOCKET close
|
|
|
|
#endif /* UNX */
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Platform-specific function definitions for Windows & Windows NT
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef WIN32
|
|
|
|
void
|
|
PitPrintStringForStatus(
|
|
PIT_STATUS Status,
|
|
char *PrefixString
|
|
)
|
|
{
|
|
/*
|
|
PIT_SUCCESS
|
|
ERROR_INVALID_USER_BUFFER
|
|
ERROR_INVALID_PARAMETER
|
|
*/
|
|
|
|
printf("%s : Error Code %lu\n", PrefixString, Status);
|
|
return;
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitConvertAddressToAddressString(
|
|
IPADDR Address,
|
|
char *String,
|
|
unsigned long StringLength
|
|
)
|
|
{
|
|
char *addressString;
|
|
struct in_addr inAddress;
|
|
|
|
inAddress.S_un.S_addr = htonl(Address);
|
|
|
|
addressString = inet_ntoa(inAddress);
|
|
|
|
if (addressString != NULL) {
|
|
if (strlen(addressString) < StringLength) {
|
|
strcpy(String, addressString);
|
|
return(PIT_SUCCESS);
|
|
}
|
|
return(ERROR_INVALID_USER_BUFFER);
|
|
}
|
|
|
|
return(PitGetLastErrorCode());
|
|
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitConvertAddressStringToAddress(
|
|
char *String,
|
|
IPADDR *Address
|
|
)
|
|
{
|
|
IPADDR addr;
|
|
|
|
|
|
addr = inet_addr(String);
|
|
|
|
if (addr != INADDR_NONE) {
|
|
*Address = ntohl(addr);
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
if (strncmp(String, "255.255.255.255", 15) == 0) {
|
|
*Address = 0xffffffff;
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitInitializeTransportInterface(
|
|
void
|
|
)
|
|
{
|
|
int returnCode;
|
|
|
|
returnCode = WSAStartup(0x0101, &WsaData);
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitCleanupTransportInterface(
|
|
void
|
|
)
|
|
{
|
|
if (!WSACleanup()) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
#endif /* WIN32 */
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Platform-specific function definitions for Un*x
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef UNX
|
|
|
|
void
|
|
PitPrintStringForStatus(Status, PrefixString)
|
|
PIT_STATUS Status;
|
|
char *PrefixString;
|
|
{
|
|
printf("%s : Error Code %lu\n", PrefixString, Status);
|
|
return;
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitConvertAddressToAddressString(Address, String, StringLength)
|
|
IPADDR Address;
|
|
char *String;
|
|
unsigned long StringLength;
|
|
{
|
|
char *addressString;
|
|
struct in_addr inAddress;
|
|
|
|
inAddress.S_un.S_addr = htonl(Address);
|
|
|
|
addressString = inet_ntoa(inAddress);
|
|
|
|
if (addressString != NULL) {
|
|
if (strlen(addressString) < StringLength) {
|
|
strcpy(String, addressString);
|
|
return(PIT_SUCCESS);
|
|
}
|
|
return(EINVAL);
|
|
}
|
|
|
|
return(PitGetLastErrorCode());
|
|
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitConvertAddressStringToAddress(String, Address)
|
|
char *String;
|
|
IPADDR *Address;
|
|
{
|
|
IPADDR addr;
|
|
|
|
addr = inet_addr(String);
|
|
|
|
if (addr != INADDR_NONE) {
|
|
*Address = ntohl(addr);
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
if (strncmp(String, "255.255.255.255", 15) == 0) {
|
|
*Address = 0xffffffff;
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
return(EINVAL);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitInitializeTransportInterface(void)
|
|
{
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
PIT_STATUS
|
|
PitCleanupTransportInterface(
|
|
void
|
|
)
|
|
{
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
#endif /* UNX */
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Common function definitions
|
|
*
|
|
****************************************************************************/
|
|
|
|
PIT_STATUS
|
|
PitResolveNameToAddress(NameString, Address)
|
|
char *NameString;
|
|
IPADDR *Address;
|
|
{
|
|
struct hostent *hostEntry;
|
|
|
|
hostEntry = gethostbyname(NameString);
|
|
|
|
if (hostEntry != NULL) {
|
|
*Address = ntohl(*((IPADDR *) hostEntry->h_addr));
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitOpenEndpoint(Handle, Address, Port, Protocol, Type)
|
|
ENDPOINT *Handle;
|
|
IPADDR Address;
|
|
PORT Port;
|
|
PROTOCOL Protocol;
|
|
int Type;
|
|
{
|
|
ENDPOINT socketHandle;
|
|
struct sockaddr saddr;
|
|
struct sockaddr_in *sin;
|
|
int returnCode;
|
|
PIT_STATUS errorCode;
|
|
|
|
|
|
*Handle = INVALID_ENDPOINT;
|
|
|
|
sin = (struct sockaddr_in *) &saddr;
|
|
|
|
socketHandle = socket(AF_INET, Type, Protocol);
|
|
|
|
if (socketHandle == INVALID_ENDPOINT) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
if (Type == SOCK_DGRAM) {
|
|
int one = 1;
|
|
|
|
if (setsockopt(
|
|
socketHandle,
|
|
SOL_SOCKET,
|
|
SO_BROADCAST,
|
|
(char *)&one,
|
|
sizeof(int)
|
|
)
|
|
) {
|
|
printf("Couldn't set datagram socket for broadcasts\n");
|
|
}
|
|
}
|
|
|
|
PitZeroMemory(&saddr, sizeof(saddr));
|
|
|
|
sin->sin_family = AF_INET;
|
|
sin->sin_port = (Type == SOCK_RAW) ? 0 : htons(Port);
|
|
sin->sin_addr.s_addr = htonl(Address);
|
|
|
|
returnCode = bind(socketHandle, &saddr, sizeof(saddr));
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
errorCode = PitGetLastErrorCode();
|
|
PitCloseEndpoint(socketHandle);
|
|
return(errorCode);
|
|
}
|
|
|
|
*Handle = socketHandle;
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
} /* PitOpenEndpoint */
|
|
|
|
|
|
PIT_STATUS
|
|
PitOpenStreamEndpoint(Handle, Address, Port)
|
|
ENDPOINT *Handle;
|
|
IPADDR Address;
|
|
PORT Port;
|
|
{
|
|
return(PitOpenEndpoint(Handle, Address, Port, 0, SOCK_STREAM));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitOpenDatagramEndpoint(Handle, Address, Port)
|
|
ENDPOINT *Handle;
|
|
IPADDR Address;
|
|
PORT Port;
|
|
{
|
|
return(PitOpenEndpoint(Handle, Address, Port, 0, SOCK_DGRAM));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitOpenRawEndpoint(Handle, Address, Protocol)
|
|
ENDPOINT *Handle;
|
|
IPADDR Address;
|
|
PROTOCOL Protocol;
|
|
{
|
|
return(PitOpenEndpoint(Handle, Address, 0, Protocol, SOCK_RAW));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitCloseEndpoint(Handle)
|
|
ENDPOINT Handle;
|
|
{
|
|
return(CLOSE_SOCKET(Handle));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitConnect(Handle, Address, Port)
|
|
ENDPOINT Handle;
|
|
IPADDR Address;
|
|
PORT Port;
|
|
{
|
|
struct sockaddr saddr;
|
|
struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
|
|
int returnCode;
|
|
|
|
|
|
PitZeroMemory(&saddr, sizeof(saddr));
|
|
|
|
sin->sin_family = AF_INET;
|
|
sin->sin_port = htons(Port);
|
|
sin->sin_addr.s_addr = htonl(Address);
|
|
|
|
returnCode = connect(Handle, &saddr, sizeof(saddr));
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitListenForConnections(Handle)
|
|
ENDPOINT Handle;
|
|
{
|
|
int returnCode;
|
|
|
|
returnCode = listen(Handle, 5);
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitAcceptConnection(ListeningHandle, AcceptingHandle, Address, Port)
|
|
ENDPOINT ListeningHandle;
|
|
ENDPOINT *AcceptingHandle;
|
|
IPADDR *Address;
|
|
PORT *Port;
|
|
{
|
|
int returnCode;
|
|
struct sockaddr saddr;
|
|
struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
|
|
ENDPOINT Handle;
|
|
int saddrLength;
|
|
|
|
|
|
*AcceptingHandle = INVALID_ENDPOINT;
|
|
|
|
PitZeroMemory(&saddr, sizeof(saddr));
|
|
saddrLength = sizeof(saddr);
|
|
|
|
Handle = accept(ListeningHandle, &saddr, &saddrLength);
|
|
|
|
if (Handle == INVALID_ENDPOINT) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
*AcceptingHandle = Handle;
|
|
|
|
if (Address != NULL) {
|
|
*Address = ntohl(sin->sin_addr.s_addr);
|
|
}
|
|
|
|
if (Port != NULL) {
|
|
*Port = ntohs(sin->sin_port);
|
|
}
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitDisconnectSend(Handle)
|
|
ENDPOINT Handle;
|
|
{
|
|
return(shutdown(Handle, 1));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitDisconnectReceive(Handle)
|
|
ENDPOINT Handle;
|
|
{
|
|
return(shutdown(Handle, 0));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitDisconnectBoth(Handle)
|
|
ENDPOINT Handle;
|
|
{
|
|
return(shutdown(Handle, 2));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitSendData(Handle, Buffer, BytesToSend, BytesSent, UrgentFlag)
|
|
ENDPOINT Handle;
|
|
char *Buffer;
|
|
unsigned long BytesToSend;
|
|
unsigned long *BytesSent;
|
|
int UrgentFlag;
|
|
{
|
|
int returnCode;
|
|
char *bufferPtr = Buffer;
|
|
|
|
*BytesSent = 0;
|
|
|
|
while (BytesToSend > 0) {
|
|
returnCode = send(
|
|
Handle,
|
|
bufferPtr,
|
|
(int) BytesToSend,
|
|
(UrgentFlag ? MSG_OOB : 0)
|
|
);
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
BytesToSend -= (unsigned long) returnCode;
|
|
bufferPtr += returnCode;
|
|
*BytesSent += (unsigned long) returnCode;
|
|
}
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitSend(Handle, Buffer, BytesToSend, BytesSent)
|
|
ENDPOINT Handle;
|
|
char *Buffer;
|
|
unsigned long BytesToSend;
|
|
unsigned long *BytesSent;
|
|
{
|
|
return(PitSendData(Handle, Buffer, BytesToSend, BytesSent, 0));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitSendUrgent(Handle, Buffer, BytesToSend, BytesSent)
|
|
ENDPOINT Handle;
|
|
char *Buffer;
|
|
unsigned long BytesToSend;
|
|
unsigned long *BytesSent;
|
|
{
|
|
return(PitSendData(Handle, Buffer, BytesToSend, BytesSent, 1));
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitReceiveData(Handle, Buffer, BufferSize, BytesToReceive, BytesReceived,
|
|
UrgentFlag)
|
|
|
|
ENDPOINT Handle;
|
|
char *Buffer;
|
|
unsigned long BufferSize;
|
|
unsigned long BytesToReceive;
|
|
unsigned long *BytesReceived;
|
|
int UrgentFlag;
|
|
{
|
|
int returnCode;
|
|
char *bufferPtr = Buffer;
|
|
char receiveSpecified = 0;
|
|
|
|
*BytesReceived = 0;
|
|
|
|
if (BytesToReceive) {
|
|
receiveSpecified = 1;
|
|
|
|
if (BufferSize > BytesToReceive) {
|
|
BufferSize = BytesToReceive;
|
|
}
|
|
}
|
|
|
|
while (BufferSize) {
|
|
returnCode = recv(
|
|
Handle,
|
|
bufferPtr,
|
|
(int) BufferSize,
|
|
(UrgentFlag ? MSG_OOB : 0)
|
|
);
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
if (returnCode == 0) {
|
|
return(PIT_REMOTE_DISCONNECT);
|
|
}
|
|
|
|
*BytesReceived += (unsigned long) returnCode;
|
|
|
|
if (!receiveSpecified) {
|
|
break;
|
|
}
|
|
|
|
BufferSize -= (unsigned long) returnCode;
|
|
bufferPtr += returnCode;
|
|
BytesToReceive -= (unsigned long) returnCode;
|
|
|
|
if (!BytesToReceive) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitReceive(Handle, Buffer, BufferSize, BytesToReceive, BytesReceived)
|
|
ENDPOINT Handle;
|
|
char *Buffer;
|
|
unsigned long BufferSize;
|
|
unsigned long BytesToReceive;
|
|
unsigned long *BytesReceived;
|
|
{
|
|
return(
|
|
PitReceiveData(
|
|
Handle,
|
|
Buffer,
|
|
BufferSize,
|
|
BytesToReceive,
|
|
BytesReceived,
|
|
0
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitReceiveUrgent(Handle, Buffer, BufferSize, BytesToReceive, BytesReceived)
|
|
ENDPOINT Handle;
|
|
char *Buffer;
|
|
unsigned long BufferSize;
|
|
unsigned long BytesToReceive;
|
|
unsigned long *BytesReceived;
|
|
{
|
|
return(
|
|
PitReceiveData(
|
|
Handle,
|
|
Buffer,
|
|
BufferSize,
|
|
BytesToReceive,
|
|
BytesReceived,
|
|
1
|
|
)
|
|
);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitSendDatagram(Handle, Address, Port, Buffer, BytesToSend, BytesSent)
|
|
ENDPOINT Handle;
|
|
IPADDR Address;
|
|
PORT Port;
|
|
char *Buffer;
|
|
unsigned long BytesToSend;
|
|
unsigned long *BytesSent;
|
|
{
|
|
int returnCode;
|
|
struct sockaddr saddr;
|
|
struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
|
|
|
|
|
|
PitZeroMemory(&saddr, sizeof(saddr));
|
|
|
|
sin->sin_family = AF_INET;
|
|
sin->sin_port = htons(Port);
|
|
sin->sin_addr.s_addr = htonl(Address);
|
|
|
|
returnCode = sendto(Handle, Buffer, BytesToSend, 0, &saddr, sizeof(saddr));
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
*BytesSent = (unsigned long) returnCode;
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitReceiveDatagram(Handle, Address, Port, Buffer, BufferSize, BytesReceived)
|
|
ENDPOINT Handle;
|
|
IPADDR *Address;
|
|
PORT *Port;
|
|
char *Buffer;
|
|
unsigned long BufferSize;
|
|
unsigned long *BytesReceived;
|
|
{
|
|
int returnCode;
|
|
struct sockaddr saddr;
|
|
struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
|
|
int saddrLength = sizeof(struct sockaddr);
|
|
|
|
|
|
PitZeroMemory(&saddr, sizeof(saddr));
|
|
|
|
returnCode = recvfrom(Handle, Buffer, BufferSize, 0, &saddr, &saddrLength);
|
|
|
|
if (returnCode == SOCKET_ERROR) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
*Port = ntohs(sin->sin_port);
|
|
*Address = ntohl(sin->sin_addr.s_addr);
|
|
*BytesReceived = (unsigned long) returnCode;
|
|
|
|
return(PIT_SUCCESS);
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitJoinMulticastGroup(Handle, MulticastAddress, InterfaceAddress)
|
|
ENDPOINT Handle;
|
|
IPADDR MulticastAddress;
|
|
IPADDR InterfaceAddress;
|
|
{
|
|
#ifndef MCAST
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#else /* MCAST */
|
|
|
|
struct ip_mreq mreq;
|
|
int returnValue;
|
|
|
|
|
|
mreq.imr_multiaddr.s_addr = htonl(MulticastAddress);
|
|
mreq.imr_interface.s_addr = htonl(InterfaceAddress);
|
|
|
|
returnValue = setsockopt(
|
|
Handle,
|
|
IPPROTO_IP,
|
|
IP_ADD_MEMBERSHIP,
|
|
(char *) &mreq,
|
|
sizeof(struct ip_mreq)
|
|
);
|
|
|
|
if (returnValue == -1) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
printf("Joined multicast group.\n");
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#endif /* MCAST */
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitLeaveMulticastGroup(Handle, MulticastAddress, InterfaceAddress)
|
|
ENDPOINT Handle;
|
|
IPADDR MulticastAddress;
|
|
IPADDR InterfaceAddress;
|
|
{
|
|
#ifndef MCAST
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#else /* MCAST */
|
|
|
|
struct ip_mreq mreq;
|
|
int returnValue;
|
|
|
|
|
|
mreq.imr_multiaddr.s_addr = htonl(MulticastAddress);
|
|
mreq.imr_interface.s_addr = htonl(InterfaceAddress);
|
|
|
|
returnValue = setsockopt(
|
|
Handle,
|
|
IPPROTO_IP,
|
|
IP_DROP_MEMBERSHIP,
|
|
(char *) &mreq,
|
|
sizeof(struct ip_mreq)
|
|
);
|
|
|
|
if (returnValue == -1) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
printf("Dropped multicast group.\n");
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#endif /* MCAST */
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitSetMulticastInterface(Handle, InterfaceAddress)
|
|
ENDPOINT Handle;
|
|
IPADDR InterfaceAddress;
|
|
{
|
|
#ifndef MCAST
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#else /* MCAST */
|
|
|
|
struct in_addr inAddress;
|
|
int returnValue;
|
|
|
|
|
|
inAddress.S_un.S_addr = htonl(InterfaceAddress);
|
|
|
|
returnValue = setsockopt(
|
|
Handle,
|
|
IPPROTO_IP,
|
|
IP_MULTICAST_IF,
|
|
(char *) &inAddress,
|
|
sizeof(struct in_addr)
|
|
);
|
|
|
|
if (returnValue == -1) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
printf("Set default multicast interface.\n");
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#endif /* MCAST */
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitEnableMulticastLoopback(Handle)
|
|
ENDPOINT Handle;
|
|
{
|
|
#ifndef MCAST
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#else /* MCAST */
|
|
|
|
int returnValue;
|
|
int one = 1;
|
|
|
|
|
|
|
|
returnValue = setsockopt(
|
|
Handle,
|
|
IPPROTO_IP,
|
|
IP_MULTICAST_LOOP,
|
|
(char *) &one,
|
|
sizeof(int)
|
|
);
|
|
|
|
if (returnValue == -1) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
printf("Enabled multicast packet loopback.\n");
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#endif /* MCAST */
|
|
}
|
|
|
|
|
|
PIT_STATUS
|
|
PitDisableMulticastLoopback(Handle)
|
|
ENDPOINT Handle;
|
|
{
|
|
#ifndef MCAST
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#else /* MCAST */
|
|
|
|
int returnValue;
|
|
int zero = 0;
|
|
|
|
|
|
|
|
returnValue = setsockopt(
|
|
Handle,
|
|
IPPROTO_IP,
|
|
IP_MULTICAST_LOOP,
|
|
(char *) &zero,
|
|
sizeof(int)
|
|
);
|
|
|
|
if (returnValue == -1) {
|
|
return(PitGetLastErrorCode());
|
|
}
|
|
|
|
printf("Disabled multicast packet loopback.\n");
|
|
|
|
return(PIT_SUCCESS);
|
|
|
|
#endif /* MCAST */
|
|
}
|
|
|
|
#endif /* SOCKETS */
|
|
|