IP Source routing in TCP client



Hi,

I try to create a TCP client that supports loose source routing. Please
find my test code below.

I never succeed in seeing the loose source data set in the setsockopt
call on the network. I use Ethereal to check the network traffic. The
SYN telegram transmitted when connect() is called does not contain my
desired IP header options.

I know that the problem is not related to Ethereal since it displays
the loose source routing bytes in the IP header if I test with the
ping/tracert -j option.

I have tested this on both Windows NT4.0 and Windows XP SP2. The result
is the same in both cases.

I have set the DisableIPSourceRouting registry parameter equal to 0
(HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters).

Any ideas?

Thanks in advance.

Geir Guldstein



#include <winsock2.h>
#include <ws2tcpip.h>


#define MYREMOTEIPADDRESS "193.155.23.37"
#define MYPORTNUMBER 80
#define MYROUTERIPADDRESS "200.201.202.1"


void TestSourceRouting(void)
{
SOCKET sockRaw;
struct sockaddr_in localAddr, remoteAddr;
WSADATA wsaData;

/* ------------------ */
/* Init params */
remoteAddr.sin_family = AF_INET;
remoteAddr.sin_addr.S_un.S_addr = inet_addr(MYREMOTEIPADDRESS);
remoteAddr.sin_port = htons(MYPORTNUMBER);

/* ----------------- */
/* Create the socket */
if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0){
fprintf(stderr,"WSAStartup failed: %d\n",GetLastError());
}
sockRaw = socket(AF_INET, SOCK_STREAM, 0);
if (sockRaw == INVALID_SOCKET)
{
fprintf(stderr,"socket() failed: %d\n",WSAGetLastError());
}

/* -------------- */
/* Set IP Options */
char optionlist[12];
optionlist[0] = (char)0x83; // Loose source routing
optionlist[1] = (char)0x0b; // size of the option
optionlist[2] = (char)0x04; // pointer to the next IP destination
long a = inet_addr(MYROUTERIPADDRESS); // router, first in the source
routing list
memcpy( &optionlist[3], &a, 4);
memcpy( &optionlist[7], &(remoteAddr.sin_addr.S_un.S_addr), 4); //
remote address (destination), must be last in the source routing list
optionlist[11] = 0x00; // End of Options + Padding
if(setsockopt( sockRaw, IPPROTO_IP, IP_OPTIONS, optionlist,
sizeof(optionlist)) == SOCKET_ERROR){
fprintf(stderr,"failed to set IP_OPTIONS: %d\n",WSAGetLastError());
}

/* --------------- */
/* bind the socket */
memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockRaw, (struct sockaddr *)&localAddr, sizeof(localAddr)) ==
SOCKET_ERROR)
{
fprintf(stderr,"bind() failed: %d\n",WSAGetLastError());
}

/* --------------- */
/* connect */
if(connect(sockRaw, (struct sockaddr*)&remoteAddr, sizeof(remoteAddr))
== SOCKET_ERROR)
{
fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
}
}

.