I encountered mucho frustration trying to make WS-Discovery work, so I ended up writing one in C, you can compile it with gcc or g++ and it should work on *nix.
This is very simple, it just sends out a probe message and prints out the responses. I made it get the probe message from a file, so you will need to provide your own probe message.
Call the function like this somewhere in your program and watch it go:
send_request_write("239.255.255.250", 3702, "sample-probe-msg.xml");
And here is the code you need to put in your program:
/* You need these headers for networking */
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
/* and these defines */
#define DATA_SIZE 1024
#define RBUF_SIZE 4096
/* Returns 0 for success, otherwise -1. */
int make_socket(struct sockaddr_in *s, char *host, int port) {
s->sin_family = AF_INET;
if (host != NULL) {
struct hostent *he = gethostbyname(host);
if (he == NULL) {
perror("gethostbyname");
return -1;
}
s->sin_addr = *((struct in_addr *)he->h_addr);
} else {
s->sin_addr.s_addr = htonl(INADDR_ANY);
}
s->sin_port = htons(port);
memset(&(s->sin_zero), 0, 8);
return 0;
}
void send_request_write(char *host, int port, char *filename) {
struct timeval tv;
int mysockfd, n, k;
struct sockaddr_in serv_addr, my_addr, client_addr;
unsigned int addr_len, client_add_len;
int filesize, pos = 0;
/* Make sure the file to send exists */
int fd = open(filename, O_RDONLY, 0006);
if (fd == -1) {
perror("open");
exit(1);
}
/* get file length */
filesize = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
/* Bind to random port */
if ((mysockfd=socket(AF_INET,SOCK_DGRAM,0)) == -1) {
perror("socket");
exit(1);
}
make_socket(&my_addr, NULL, 0);
if (bind(mysockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
/* 3 secs timeout */
tv.tv_sec = 3;
tv.tv_usec = 0;
setsockopt(mysockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
/* Announcement */
addr_len = sizeof(struct sockaddr);
if (getsockname(mysockfd, (struct sockaddr *)&my_addr, &addr_len) == -1) {
perror("getsockname");
exit(1);
}
printf("Send/recv on port %d...\n", ntohs( my_addr.sin_port ));
/* Make send_to socket */
make_socket(&serv_addr, host, port);
/* Send the request */
printf("Sending data to %s:%i, totaling %i bytes.\n", host, port, filesize);
while (pos < filesize) {
char dataBuf[DATA_SIZE] = {0};
n = read(fd, &dataBuf, DATA_SIZE);
if (n == -1) {
perror("read");
exit(1);
}
pos += n;
/* send what we got from the file */
addr_len = sizeof(struct sockaddr);
k = sendto(mysockfd, dataBuf, n, 0, (struct sockaddr *)&serv_addr, addr_len);
if (k < 0) {
exit(1); /* abbbboooooort! */
}
}
close(fd);
k = 0;
/* Wait for the response(s) */
while (1) {
char rcvBuf[RBUF_SIZE] = {0};
client_add_len = sizeof(struct sockaddr);
k = recvfrom(mysockfd, rcvBuf, RBUF_SIZE, 0, (struct sockaddr *)&client_addr, &client_add_len);
if (k < 0) {
break;
} else {
printf("Got packet from %s:%d, %i bytes.\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), k
);
printf("%s\n______________________________\n\n", rcvBuf);
}
}
close(mysockfd);
}