I also make the first experiment on Ubuntu Linux. The result is the same as on Windows Vista. I just share this information.
Printable View
I also make the first experiment on Ubuntu Linux. The result is the same as on Windows Vista. I just share this information.
Are you willing to share the source code so I can try it myself on gentoo?Quote:
Originally Posted by Cooker
Well, it's only security issue if you do TCP bind to ANY address. If you bind to a specific address, no other TCP server can "steal" that specific address+port.
Quote:
Originally Posted by MikeAThon
I don't think I agree. The entire purpose of the SO_EXCLUSIVEADDR option is to prevent a malicious program from "stealing" the addr+port. Without SO_EXCLUSIVEADDR, it's my understanding that a malicious program can do exactly that:Quote:
Originally Posted by j0nas
.Quote:
Originally Posted by http://msdn2.microsoft.com/en-us/library/ms740618.aspx
Still waiting on that source code. I'm either doing something wrong or my OS has some security mechanism such as SO_EXCLUSIVEADDR at kernel level or something.
At first, You can run the following source code on Windows OS.Quote:
Originally Posted by ludakot
- UDP Receiver
Code:#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h> // for Winsock
#pragma comment(lib,"Ws2_32.lib") // for Winsock
void ErrExit(SOCKET fd, const char *format, ...);
int main(int argc, char *argv[])
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
int err = 0;
SOCKET sockfd = 0;
struct sockaddr_in local, remote;
int localport = 0;
int nrecvbytes = 0, fromlen = 0;
char recvbuf[128];
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
if (argc != 3) {
printf("Usage:\n");
printf(" program local_addr local_port\n");
printf("Description:\n");
printf(" Receive UDP packets from local_addr:local_port\n");
return -1;
}
localport = strtol(argv[2], NULL, 10);
// Initiate use of the Winsock DLL
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
// Could not find a usable WinSock DLL
printf("Couldn't find a usable WinSock DLL.\n");
return -1;
}
// Confirm that the WinSock DLL supports 2.2.
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2)
ErrExit(0, "Bad winsock version.\n");
// Create a socket that is bound to a specific transport service provider
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == INVALID_SOCKET)
ErrExit(0, "Can't open a socket with error code %d\n", WSAGetLastError());
// Contain information about local IP address and port
local.sin_family = AF_INET;
local.sin_port = htons(localport);
local.sin_addr.s_addr = inet_addr(argv[1]);
memset(local.sin_zero, '\0', sizeof local.sin_zero);
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen) == SOCKET_ERROR) {
printf("Can't set SO_REUSEADDR option.\n");
}
// Associate a local address with a socket
err = bind(sockfd, (struct sockaddr *)&local, sizeof local);
if (err == SOCKET_ERROR)
ErrExit(sockfd, "Can't bind to a local address and port with error code %d\n", WSAGetLastError());
memset(&remote, 0, sizeof remote);
memset(recvbuf, 0, sizeof recvbuf);
for (;;)
{
fromlen = sizeof remote;
nrecvbytes = recvfrom(sockfd, recvbuf, sizeof recvbuf, 0, (struct sockaddr *)&remote, &fromlen);
if (nrecvbytes == SOCKET_ERROR)
ErrExit(sockfd, "Can't receive messages with error code %d\n", WSAGetLastError());
recvbuf[nrecvbytes] = '\0';
printf("Message [%s] from %s:%d\n", recvbuf, inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
}
return 0;
}
void ErrExit(SOCKET fd, const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
if (fd != NULL)
closesocket(fd);
WSACleanup();
exit(1);
}
- UDP sender
Code:#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <winsock2.h> // for Winsock
#pragma comment(lib,"Ws2_32.lib") // for Winsock
void ErrExit(SOCKET fd, const char *format, ...);
void wait(int seconds);
int main(int argc, char *argv[])
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
int err = 0;
SOCKET sockfd = 0;
struct sockaddr_in local, remote;
int localport = 0, remoteport = 0, cycle = 0;
int nsentbytes = 0;
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
if (argc != 7) {
printf("Usage:\n");
printf(" program local_addr local_port cycle message remote_addr remote_port\n");
printf("Description:\n");
printf(" Send a UDP packet to remote_addr:remote_port from local_addr:local_port every cycle seconds\n");
return -1;
}
localport = strtol(argv[2], NULL, 10);
remoteport = strtol(argv[6], NULL, 10);
cycle = strtol(argv[3], NULL, 10);
// Initiate use of the Winsock DLL
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
// Could not find a usable WinSock DLL
printf("Couldn't find a usable WinSock DLL.\n");
return -1;
}
// Confirm that the WinSock DLL supports 2.2.
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2)
ErrExit(0, "Bad winsock version.\n");
// Create a socket that is bound to a specific transport service provider
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == INVALID_SOCKET)
ErrExit(0, "Can't open a socket with error code %d\n", WSAGetLastError());
// Contain information about local IP address and port
local.sin_family = AF_INET;
local.sin_port = htons(localport);
local.sin_addr.s_addr = inet_addr(argv[1]);
memset(local.sin_zero, '\0', sizeof local.sin_zero);
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen) == SOCKET_ERROR) {
printf("Can't set SO_REUSEADDR option.\n");
}
// Associate a local address with a socket
err = bind(sockfd, (struct sockaddr *)&local, sizeof local);
if (err == SOCKET_ERROR)
ErrExit(sockfd, "Can't bind to a local address and port with error code %d\n", WSAGetLastError());
// Contain information about remote IP address and port
remote.sin_family = AF_INET;
remote.sin_port = htons(remoteport);
remote.sin_addr.s_addr = inet_addr(argv[5]);
memset(remote.sin_zero, '\0', sizeof remote.sin_zero);
printf("==> Press any key to quit the program. <==\n");
for (;;)
{
if (kbhit())
break;
nsentbytes = sendto(sockfd, argv[4], strlen(argv[4]), 0, (struct sockaddr *)&remote, sizeof remote);
if (nsentbytes == SOCKET_ERROR)
ErrExit(sockfd, "Can't send meesages to remote address with error code%d\n", WSAGetLastError());
wait(cycle);
}
system("pause");
return 0;
}
void ErrExit(SOCKET fd, const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
if (fd != NULL)
closesocket(fd);
WSACleanup();
system("pause");
exit(1);
}
void wait(int seconds)
{
clock_t endwait;
endwait = clock () + seconds * CLK_TCK ;
while (clock() < endwait) {}
}
The source code which runs on Ubuntu Linux isn't in my current PC. I will post later.
This SO_EXCLUSIVEADDR option is available on Microsoft Windows. On a Linux, all the socket information is in the man page for socket in section 7. You can type "man 7 socket" to get all these goodies and find if there exists SO_EXCLUSIVEADDRUSE option. That's my way.Quote:
Originally Posted by ludakot
Linux version.Quote:
Originally Posted by ludakot
The source code of UDP sender
I use 'tcpdump' to check UDP message at remote PC side.Code:#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define CLK_TCK CLOCKS_PER_SEC
void ErrExit(int fd, const char *format, ...);
void wait(int seconds);
int main(int argc, char *argv[])
{
int err = 0;
int sockfd = 0;
struct sockaddr_in local, remote;
int localport = 0, remoteport = 0, cycle = 0;
int nsentbytes = 0;
int optval;
if (argc != 7) {
printf("Usage:\n");
printf(" program local_addr local_port cycle message remote_addr remote_port\n");
printf("Description:\n");
printf(" Send a UDP packet to remote_addr:remote_port from local_addr:local_port every cycle seconds\n");
return -1;
}
localport = strtol(argv[2], NULL, 10);
remoteport = strtol(argv[6], NULL, 10);
cycle = strtol(argv[3], NULL, 10);
// Create a socket that is bound to a specific transport service provider
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == INVALID_SOCKET)
ErrExit(0, "Can't open a socket with error %s\n", strerror(errno));
// Contain information about local IP address and port
local.sin_family = AF_INET;
local.sin_port = htons(localport);
local.sin_addr.s_addr = inet_addr(argv[1]);
memset(local.sin_zero, '\0', sizeof local.sin_zero);
optval = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof optval) == SOCKET_ERROR) {
printf("Can't set SO_REUSEADDR option.\n");
}
// Associate a local address with a socket
err = bind(sockfd, (struct sockaddr *)&local, sizeof local);
if (err == SOCKET_ERROR)
ErrExit(sockfd, "Can't bind to a local address and port with error %s\n", strerror(errno));
// Contain information about remote IP address and port
remote.sin_family = AF_INET;
remote.sin_port = htons(remoteport);
remote.sin_addr.s_addr = inet_addr(argv[5]);
memset(remote.sin_zero, '\0', sizeof remote.sin_zero);
for (;;)
{
nsentbytes = sendto(sockfd, argv[4], strlen(argv[4]), 0, (struct sockaddr *)&remote, sizeof remote);
if (nsentbytes == SOCKET_ERROR)
ErrExit(sockfd, "Can't send meesages to remote address with error %s\n", strerror(errno));
wait(cycle);
}
return 0;
}
void ErrExit(int fd, const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
if (fd != NULL)
close(fd);
exit(1);
}
void wait(int seconds)
{
clock_t endwait;
endwait = clock () + seconds * CLK_TCK ;
while (clock() < endwait) {}
}