[prev in list] [next in list] [prev in thread] [next in thread] 

List:       hpux-devtools
Subject:    HPUX-DEVTOOLS: HPUXX-DEV: unable to read broadcast UDP messages on HP-UX 11.00
From:       "didier billard" <didier_billard () hotmail ! com>
Date:       2002-11-26 17:41:00
[Download RAW message or body]

Hello,

we are currently trying to migrate end-user software application from HP-UX 
10.20 OS to HP-UX 11.00 OS.

yesterday we got the following problem when migrating our application:

- when sending UDP messages in broadcast mode from an HP-UX 10.20 station to 
another HP-UX 10.20 station, UDP messages are correctly received by the 
second station

- when sending UDP message in broadcast mode from an HP-UX 11.00 station to 
another HP-UX 11.00 station, UDP messages are correclty received by the 
HP-UX 10.20 station

- when sending UDP messages at a given destination IP address from an HP-UX 
11.00 station to destination HP-UX 10.20 station, UDP messages are correctly 
received by HP-UX 10.20 station.

- when sending UDP message in braodcast mode from an HP-UX 10.20 station to 
an HP-UX 11.00 station, UDP messages are NOT RECEIVED by the HP-UX 11.00 
station

HP hotline told us to install PHNE_27886 and subsequent patches on ou HP-UX 
11.00 station but it still does not work.

Does anyone know wethee this problem is due to HP-UX 11.00 configuration or 
to a problem corrected by some patch or anythnig else ?

thank you for your help.

Didier BILLARD

Nota;
You may find hereunder source code for readBroadcast.cpp and 
writeBroadcast.cpp programs we used to test our platform on HP-UX 10.20 and 
HP-UX 11.00 stations:

readBroadcast.cpp:
// 
****************************************************************************

#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <errno.h>

#include <stdlib.h>
#include <stdio.h>

#define DEFAULT_PORT_NUM 10100
#define DEFAULT_TIMEOUT_SEC 10
#define max(a,b) (((a)>(b))?(a):(b))

typedef unsigned long IpAddress;
#define C_NullIpAddress 0L

IpAddress StringToIpAddress(
			      const char *buf
			      )

    {
      // scan the 4 integers numbers and rebuild a new IpAddress.
      IpAddress result = C_NullIpAddress;
      unsigned int a,b,c,d;
      int nb = sscanf(buf, "%d.%d.%d.%d", &a, &b, &c, &d);

      if (nb == 4)
	{
	  // Compute each new value...
	  a = (a << 24) & 0xff000000;
	  b = (b << 16) & 0x00ff0000;
	  c = (c << 8) & 0x0000ff00;
	  d = d & 0x000000ff;
	  result = a | b | c | d;
	}

      return result;

    }

int main(const int argc, char** argv)
{
  unsigned int portNum = DEFAULT_PORT_NUM;
  IpAddress ipAddress = 0L;
  unsigned int timeInt = DEFAULT_TIMEOUT_SEC;

  // printf("argc = %d\n", argc);

  int curArg = 1;
  int reuseAddrFlag = 0;

  for (curArg = 1; curArg < argc; curArg++) {
    switch (argv[curArg][0]) {
      case '-':
        // printf("argument[%d] = %s\n", curArg, &argv[curArg][1]);
	switch(argv[curArg][1]) {
	  case 'p':
	    portNum = atoi(&argv[curArg][2]);
	    // printf("Port number is %d\n", portNum);
	    break;
	  case 'a':
	    ipAddress = StringToIpAddress(&argv[curArg][2]);
	    // printf("IP Address is 0x%x\n", ipAddress);
	    break;
	  case 't':
	    timeInt = atoi(&argv[curArg][2]);
	    break;
	  case 'r':
	    reuseAddrFlag = 1;
	    break;
	case 'h':
	    printf("%s usage:\n", argv[0]);
	    printf("   -p: specify port number (ex: -p10300)\n");
	    printf("   -a: speficy local IP address to bind (ex.: 
-a155.133.1.11)\n");
	    printf("   -t: specify select time-out interval in seconds (ex.: 
-t5)\n");
	    printf("   -r: set SO_REUSEADDR socket option\n");
	    printf("   -h: this stuff !!!\n");
            exit(0);
            break;
	default:
           printf("invalid argument is %s\n", argv[curArg]);
	   printf("%s: usage is %s -p<Port Number> -a<Address> -t<time interval> 
[-r]\n", argv[0], argv[0]);
	  exit(1);
	}
        break;
    default:
        printf("invalid argument is %s\n", argv[curArg]);
	printf("%s: usage is %s -p<Port Number> -a<Address> -t<time interval> 
[-r]\n", argv[0], argv[0]);
	exit(1);
    }
  }

  printf("Starting read UDP socket at address 0x%x with port %d and time-out 
%d seconds\n", ipAddress, portNum, timeInt);

  // Create UDP Socket
  int _fd = 0;
  if ((_fd = ::socket(AF_INET, SOCK_DGRAM, 0))==-1) {
    printf("Unable to create UDP socket errno = %d\n", errno);
    exit (2);
  }

  // set socket options
  if (reuseAddrFlag != 0) {
    const int on = 1;
    if (setsockopt(_fd,SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
      printf("Unable to set socket option to SO_REUSEADDR errno = %d(%s)\n", 
portNum, errno, strerror(errno));
      exit(1);
    } else {
      printf("Socket option to SO_REUSEADDR\n");
    }
  }
  // bind UPD socket to port
  struct sockaddr_in peerAddr;
  bzero(&peerAddr, sizeof(peerAddr));
  peerAddr.sin_family      = AF_INET;
  peerAddr.sin_addr.s_addr = htonl(ipAddress);
  peerAddr.sin_port        = htons((unsigned short)portNum);
  if(::bind(_fd, (const sockaddr *)&peerAddr, sizeof(peerAddr))== -1) {
    printf("Unable to bind UDP socket to %d port errno = %d(%s)\n", portNum, 
  errno,strerror(errno));
    exit(1);
  }

  // select loop
  fd_set          readSet, errorSet;
  unsigned int             availBytes = 0;
  int maxfd = -1;
  struct timeval timeOut_val, *ptTimeOut = NULL;
  int            res = -1;
  do {
    FD_ZERO(&readSet);
    FD_SET(_fd, &readSet);
    errorSet = readSet;
    // Update max file descriptor for select()
    maxfd = max(maxfd, _fd) + 1;

    // timeout
    timeOut_val.tv_sec = timeInt;
    timeOut_val.tv_usec = 0;
    ptTimeOut = &timeOut_val;

    if (timeInt > 0) {
      res = select(
		   maxfd,
		   &readSet, NULL,&errorSet, // fd masks
		   ptTimeOut);
    } else {
      res = select(
		   maxfd,
		   &readSet, NULL,&errorSet, // fd masks
		   NULL);
    }
    if (res < 0) {
      printf("Error res = %d when selecting socket errno = %d\n", res, 
errno);
      exit(3);
    } else if (res > 0) {
      if(FD_ISSET(_fd,&readSet)) {
	printf("Ok readable\n");
      } else {
	printf("Pas readable res = %d\n",res);
      }
      if(FD_ISSET(_fd, &errorSet)) {
	printf("Ok error\n");
      } else {
	printf("Pas error res = %d\n",res);
      }

      if (ioctl(_fd, FIONREAD, &availBytes) == -1) {
	printf("Error when reading available byte number from socket errno = 
%d(%s)\n", errno, strerror(errno));
	exit(4);
      }
      else {
	printf("Available byte number = %d (res = %d)\n", availBytes, res);
	// read available data
	struct sockaddr_in readAddress;
	struct msghdr      readData;
        struct iovec       readVector[1];

	memset(&readData, 0, sizeof(readData));
	memset(&readAddress, 0, sizeof(readAddress));
	readData.msg_name    = (caddr_t)&readAddress;
	readData.msg_namelen = sizeof(readAddress);
	readData.msg_iov     = readVector;
	readData.msg_iovlen  = 0;

	char *readBuf = new char [availBytes +1];
	memset(readBuf, 0, availBytes +1);
	readVector[0].iov_base = readBuf;
	readVector[0].iov_len = availBytes;
	readData.msg_iovlen++;

	int resRead = 0;
	if ((resRead = recvmsg(_fd, &readData, 0)) == -1) {
	  printf("Error while reading data from socket errno = %d(%s)\n", errno, 
strerror(errno));
	  exit(5);
	}
	else {
	   printf("buffer read = %s\n", readBuf);
	   delete [] readBuf;
	}


      }
    }
    else { // res = 0
      printf("Select timeout errno = %d\n", errno);
    }
  }
  while ((res != -1) || (errno == EINTR));

  exit(0);
}


writeBroadcast.cpp:
// 
****************************************************************************

#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <errno.h>

#include <stdlib.h>
#include <stdio.h>

#define DEFAULT_PORT_NUM 10100
#define DEFAULT_TIMEOUT_SEC 10
#define DEFAULT_SEND_SIZE   10
#define DEFAULT_NETMASK 0xffffff00
#define max(a,b) (((a)>(b))?(a):(b))

typedef unsigned long IpAddress;
#define C_NullIpAddress 0L

IpAddress StringToIpAddress(
			      const char *buf
			      )

    {
      // scan the 4 integers numbers and rebuild a new IpAddress.
      IpAddress result = C_NullIpAddress;
      unsigned int a,b,c,d;
      int nb = sscanf(buf, "%d.%d.%d.%d", &a, &b, &c, &d);

      if (nb == 4)
	{
	  // Compute each new value...
	  a = (a << 24) & 0xff000000;
	  b = (b << 16) & 0x00ff0000;
	  c = (c << 8) & 0x0000ff00;
	  d = d & 0x000000ff;
	  result = a | b | c | d;
	}

      return result;

    }

int main(const int argc, char** argv)
{
  unsigned int portNum = DEFAULT_PORT_NUM;
  IpAddress ipLocalAddress = 0L;
  IpAddress ipDistAddress = 0L;
  IpAddress netMask = DEFAULT_NETMASK;
  unsigned int timeInt = DEFAULT_TIMEOUT_SEC;


  // printf("argc = %d\n", argc);

  int curArg = 1;
  int broadcastFlag = 0;
  int reuseAddrFlag = 0;

  for (curArg = 1; curArg < argc; curArg++) {
    switch (argv[curArg][0]) {
      case '-':
	switch(argv[curArg][1]) {
	  case 'p':
	    portNum = atoi(&argv[curArg][2]);
	    break;
	  case 'a':
	    ipLocalAddress = StringToIpAddress(&argv[curArg][2]);
	    break;
	  case 'd':
	    ipDistAddress = StringToIpAddress(&argv[curArg][2]);
	    break;
	  case 't':
	    timeInt = atoi(&argv[curArg][2]);
	    break;
	  case 'b':
	    broadcastFlag = 1;
	    break;
	  case 'n':
	    netMask =  StringToIpAddress(&argv[curArg][2]);
	    break;
	   case 'r':
	     reuseAddrFlag = 1;
            break;
	case 'h':
	    printf("%s usage:\n", argv[0]);
	    printf("   -p: specify port number (ex: -p10300)\n");
	    printf("   -a: speficy local IP address to bind (ex.: 
-a155.133.1.11)\n");
	    printf("   -d: specify destination IP address   (ex.: 
-d155.133.1.13)\n");
	    printf("   -n: net mask used with broadcast mode, default is 
255.255.255.0 (ex.: -n255.255.0.0)\n");
	    printf("   -b: use broadcast mode acording to net mask (broadcast 
address is <local address | ~net mask>)\n");
	    printf("   -t: specify select time-out interval in seconds (ex.: 
-t5)\n");
	    printf("   -r: set SO_REUSEADDR socket option\n");
	    printf("   -h: this stuff !!!\n");
            exit(0);
            break;
	default:
           printf("invalid argument is %s\n", argv[curArg]);
	   printf("%s: usage is %s -b [-n<netmask address>] -p<Port Number> 
-a<Local Address> -t<time interval> [-r]\n", argv[0], argv[0]);
	   printf("%s: usage is %s -p<Port Number> -a<Local Address> -t<time 
interval> -d<Distant Address> [-r]\n", argv[0], argv[0]);
	  exit(1);
	}
        break;
    default:
        printf("invalid argument is %s\n", argv[curArg]);
	printf("%s: usage is %s -b  [-n<netmask address>] -p<Port Number> -a<Local 
Address> -t<time interval> [-r]\n", argv[0], argv[0]);
	printf("%s: usage is %s -p<Port Number> -a<Local Address> -t<time interval> 
-d<Distant Address> [-r]\n", argv[0], argv[0]);
	exit(1);
    }
  }

  if ((broadcastFlag == 0) && (ipDistAddress == 0L)) {
    printf("invalid arguments: distant IP Address must be specified when 
broadcast mode is OFF\n");
	printf("%s: usage is %s -b [-n<netmask address>] -p<Port Number> -a<Local 
Address> -t<time interval> [-r]\n", argv[0], argv[0]);
	printf("%s: usage is %s -p<Port Number> -a<Local Address> -t<time interval> 
-d<Distant Address> [-r]\n", argv[0], argv[0]);
  }

  timeInt = max(1,timeInt);
  printf("Starting write UDP socket at address 0x%x with port %d and 
time-out %d seconds\n", ipLocalAddress, portNum, timeInt);
  if (broadcastFlag != 0) {
    printf("Broadcast mode is ON\n");
  }

  // Create UDP Socket
  int _fd = 0;
  if ((_fd = ::socket(AF_INET, SOCK_DGRAM, 0))==-1) {
    printf("Unable to create UDP socket errno = %d\n", errno);
    exit (2);
  }

  // set socket options
  if (broadcastFlag != 0) {
    const int on = 1;
    if (setsockopt(_fd,SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) {
      printf("Unable to set socket option to SO_BROADCAST errno = %d(%s)\n", 
portNum, errno, strerror(errno));
      exit(1);
    } else {
      printf("Socket option to SO_BROADCAST\n");
    }
  }
  if (reuseAddrFlag != 0) {
    const int on = 1;
    if (setsockopt(_fd,SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
      printf("Unable to set socket option to SO_REUSEADDR errno = %d(%s)\n", 
portNum, errno, strerror(errno));
      exit(1);
    } else {
      printf("Socket option to SO_REUSEADDR\n");
    }
  }

  // bind UPD socket to port
  struct sockaddr_in peerAddr;
  bzero(&peerAddr, sizeof(peerAddr));
  peerAddr.sin_family      = AF_INET;
  peerAddr.sin_addr.s_addr = htonl(ipLocalAddress);
  peerAddr.sin_port        = htons((unsigned short)portNum);
  if(::bind(_fd, (const sockaddr *)&peerAddr, sizeof(peerAddr))== -1) {
    printf("Unable to bind UDP socket to %d port errno = %d(%s)\n", portNum, 
  errno,strerror(errno));
    exit(1);
  }

  // select loop
  int res = 0;
  do {
	// write available data
	struct sockaddr_in sendAddress;
	struct msghdr      sendData;
        struct iovec       sendVector[1];

	memset(&sendData, 0, sizeof(sendData));
	memset(&sendAddress, 0, sizeof(sendAddress));
	sendAddress.sin_family      = AF_INET;
	if (broadcastFlag != 0) {
	  sendAddress.sin_addr.s_addr = htonl(ipLocalAddress | ~netMask);
	} else {
	  sendAddress.sin_addr.s_addr = htonl(ipDistAddress);
	}
	sendAddress.sin_port        = htons((unsigned short)portNum);
	sendData.msg_name    = (caddr_t)&sendAddress;
	sendData.msg_namelen = sizeof(sendAddress);
	sendData.msg_iov     = sendVector;
	sendData.msg_iovlen  = 0;

	unsigned int sendSize = max(strlen("test data") + 1,DEFAULT_SEND_SIZE);
	char *sendBuf = new char [sendSize];
	memset(sendBuf, 0, sendSize);
	strcpy(sendBuf, "test data");
	sendVector[0].iov_base = sendBuf;
	sendVector[0].iov_len = sendSize;
	sendData.msg_iovlen++;

	if ((res = sendmsg(_fd, &sendData, 0)) == -1) {
	  printf("Error while sending data from socket addr 0x%x and port %d errno 
= %d(%s)\n",sendAddress.sin_addr.s_addr , sendAddress.sin_port, errno, 
strerror(errno));
	  exit(5);
	}
	else {
	   printf("buffer send = %s at address 0x%x and port %d\n", sendBuf, 
sendAddress.sin_addr.s_addr,sendAddress.sin_port );
	   delete [] sendBuf;
	}

        sleep(timeInt);

  }
  while ((res != -1) || (errno == EINTR));

  exit(0);
}

_________________________________________________________________
MSN Messenger : discutez en direct avec vos amis ! 
http://www.msn.fr/msger/default.asp
 _________________________________________________________________
 To leave this mailing list, send mail to majordomo@cxx.cup.hp.com
    with the message UNSUBSCRIBE hpux-devtools
 _________________________________________________________________
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic