#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <getopt.h>
#define MAXBUF 260
void usage()
{
printf( "Usage: sap_detect [-h] [-p port] [-s server_ip] [-w wait] [-g group]\n");
printf(" -h\t--help\t\tDisplay this help file\n"
" -p\t--port\t\tMulticast port to listen to\n"
" -s\t--server\tOnly announces from the specified ip adress\n"
" -w\t--wait\t\tNumber of sap announces to wait before quit\n"
" -g\t--group\t\tMulticast adress of the SAP group\n" );
exit(0);
};
int main(int argc, char *argv[])
{
int i,j;
int s, n, r;
struct sockaddr_in srv, cli;
struct ip_mreq mreq;
char buf[MAXBUF];
char sap_name[256]; int wait = 10000;
int port = 9875;
unsigned char isset_server = 0;
char groupe[16] = "224.2.127.254"; char ipaddr[16];
int option;
const char* const shortopts = "hpswg:";
struct option longopts[] = {
{ "help", 0, NULL, 'h'},
{ "port", 1, NULL, 'p'},
{ "server", 1, NULL, 's'},
{ "wait", 1, NULL, 'w'},
{ "group", 1, NULL, 'g'},
{ NULL, 0, NULL, 0 } };
do
{
option = getopt_long( argc, argv, shortopts, longopts, NULL);
switch (option)
{
case 'h': usage(); break;
case 'p': port = atoi(optarg); break;
case 's':
isset_server = 1;
strcpy(ipaddr, optarg);
break;
case 'g': strcpy(groupe, optarg); break;
case 'w': wait = atoi(optarg); break;
case -1: break;
};
} while (option =! -1); bzero(&srv, sizeof(srv));
srv.sin_family = AF_INET;
srv.sin_port = htons(port);
if (inet_aton(groupe, &srv.sin_addr) < 0) {
perror("inet_aton");
return 1;
}
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket error\n");
return 1;
}
if (bind(s, (struct sockaddr *)&srv, sizeof(srv)) < 0) {
perror("bind error\n");
return 1;
}
if (inet_aton(groupe, &mreq.imr_multiaddr) < 0) {
perror("inet_aton error\n");
return 1;
}
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq))
< 0) {
perror("setsockopt error\n");
return 1;
}
n = sizeof(cli);
while (isset_server == 0 || wait != 0)
{
if ((r = recvfrom(s, buf, MAXBUF, 0, (struct sockaddr *)
&cli, &n)) < 0) {
perror("recvfrom");
} else {
buf[r] = 0;
i = 0; while( buf[i] != 's' || buf[i+1] != '=') i++;
i+=2;
j = 0; while(buf[i] != 10 ) sap_name[j++] = buf[i++];
sap_name[j] = 0;
if(isset_server == 1)
{
if( strcmp( inet_ntoa(cli.sin_addr) ,ipaddr) == 0)
{
printf("%s\t%s\n", ipaddr, sap_name);
exit(0);
}
else wait--;
}
else
fprintf(stdout, "%s\t%s\n", inet_ntoa(cli.sin_addr), sap_name);
}
}
printf("No SAP annonce from %s\n", ipaddr);
return 0;
}