Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

udp broadcast (again, code included)



Hi,

One more time, sorry for the dropped attachment: the code is now included at the end of my mail.

I'm broadcasting packets over upd using the socket API. The minimum options set is SO_DONTROUTE and SO_BROADCAST (setup makes use of setsockopt).
My problem is that the sender station never reads packets broadcasted by itself, although 'tcpdump ip broadcast' shows that these packets are locally visible. Apart this 'local' problem, everything works correctly for other stations. The same code is running as expected on linux. Is there anything special to do on darwin?
The corresponding code is below. To compile on OSX, define the MACOSX macro (gcc -DMACOSX broadcast.c -lpthread -o broadcast)
My system version is Darwin Kernel Version 6.2 (MacOSX 10.2.2)

Thanks for any idea, even suggestions for any alternate place or mailing list where I could find a solution are welcome.

Dominique Fober


/*
a minimum application to show the broadcast problem on MacOSX
D. Fober <email@hidden>
*/

#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <pthread.h>

#ifdef MACOSX
#include <netinet/in.h>
#include <sys/time.h>
#endif

#define kPortNum 15101
#if __BIG_ENDIAN__
#define kBroacastMask 0x000000ff
#else
#define kBroacastMask 0xff000000
#endif

int gSock = 0;
int gDone = 0;
struct sockaddr_in gDest;

//____________________________________________________________
static void fatalerror (char *msg)
{
perror(msg);
exit (1);
}

//____________________________________________________________
void addrsetup ()
{
char host[256];
struct in_addr ipa;
struct hostent * info;

gDest.sin_family = AF_INET;
gDest.sin_port = htons(kPortNum);

if (gethostname(host, 255) == -1) fatalerror ("gethostname failed");

if (( gDest.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
info = gethostbyname(host);
if (!info) fatalerror ("gethostbyname failed");
gDest.sin_addr.s_addr = *(long *)info->h_addr;
}
gDest.sin_addr.s_addr |= kBroacastMask;
}

//____________________________________________________________
static void soksetup (int sok)
{
int ret;
#ifdef MACOSX
struct timeval t;
t.tv_sec = 0;
t.tv_usec= 50000;
ret = setsockopt (sok, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t));
if (ret == -1) fatalerror("setsockopt SO_RCVTIMEO failed");
#endif

ret = 1;
ret = setsockopt (sok, SOL_SOCKET, SO_DONTROUTE, &ret, sizeof(int));
if (ret == -1) fatalerror("setsockopt SO_DONTROUTE failed");
ret = 1;
ret = setsockopt (sok, SOL_SOCKET, SO_BROADCAST, &ret, sizeof(int));
if (ret == -1) fatalerror("setsockopt SO_BROADCAST failed");
addrsetup ();
}

//____________________________________________________________
static int create_socket ()
{
int sok, ret;
struct sockaddr_in in = { 0 };

sok = socket (AF_INET, SOCK_DGRAM, 0);
if (sok == -1) fatalerror ("socket failed");

in.sin_family = AF_INET; /* host byte order */
in.sin_port = htons(kPortNum); /* short, network byte order */
in.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
bzero(&(in.sin_zero), 8); /* zero the rest of the struct */
if (bind (sok, (struct sockaddr *)&in, sizeof(in)) == -1)
fatalerror ("bind failed");
soksetup (sok);
return sok;
}

//____________________________________________________________
static void rcvmsg (int n, long msg, long ipnum)
{
struct in_addr ipa;
ipa.s_addr = ipnum;
fprintf (stdout, "\nmessage %ld received from %s", msg, inet_ntoa (ipa));
}

//____________________________________________________________
static void * sok_listen (void * ptr)
{
struct sockaddr_in from;
long msg;
int n, addr_len;

while (!gDone) {
addr_len = sizeof(from);
n = recvfrom (gSock, &msg, sizeof(msg), 0, (struct sockaddr *)&from, &addr_len);
if (n == -1) {
if (errno != EAGAIN) fatalerror ("recvfrom failed");
}
else rcvmsg (n, htonl(msg), from.sin_addr.s_addr);
}
return 0;
}

//____________________________________________________________
static void * sok_send (void * ptr)
{
int n;
long msg = htonl(54321);

while (!gDone) {
n = sendto(gSock, &msg, sizeof(msg), 0, (struct sockaddr *)&gDest, sizeof(gDest));
if (n == -1) fatalerror ("sendto failed");
usleep (500000);
}
return 0;
}

//____________________________________________________________
main (int argc, char *argv[])
{
pthread_t threadWrite, threadRead;

fprintf (stdout, "Broadcast test\n");
gSock = create_socket ();

if (pthread_create(&threadWrite, NULL, sok_listen, 0)) fatalerror ("pthread_create failed");
if (pthread_create(&threadRead, NULL, sok_send, 0)) fatalerror ("pthread_create failed");
printf ("press return to quit");
getc(stdin);
gDone = 1;
sleep (1);
if (gSock) close(gSock);
fprintf (stdout, "\ndone\n");
return 0;
}
_______________________________________________
darwin-development mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-development
Do not post admin requests to the list. They will be ignored.



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.