SSDP プロトコルを実装しようとしていますが、それがどのように機能するのか正確にはわかりません。SSDP は udp 経由でデータを送信します。これは明らかです。コントローラがネットワークに接続すると、マルチキャスト アドレス 239.255.255.250:1900 に送信できる MSEARCH メッセージでデバイスを検索できます。すべてのデバイスは、このアドレスをリッスンして応答する必要があります。しかし、彼らがどのように反応するかはわかりません。彼らがユニキャストで応答することをwiresharkで見ていますが、応答を受信するポートを特定する方法がわかりません。
編集 - - - - - - - -
スパイク ファジング フレームワークを使用して ssdp ファザーを作成しようとしています。私が言ったように、正しいデータを送信できますが、応答を受信できません。簡単な説明とともに、いくつかのスパイク コードを貼り付けてみます。送信するデータを表す Spike 構造体があります (実際のデータ、サイズ、プロトコル情報を格納します...)。より明確にするために、いくつかの変数を削除しました。
struct spike {
/*total size of all data*/
unsigned long datasize;
unsigned char *databuf;
unsigned char *endbuf;
int fd; /*for holding socket or file information*/
int proto; /*1 for tcp, 2 for udp*/
struct sockaddr_in *destsockaddr;
};
今、私はudp経由でデータを送信しており、次の関数でいくつかの応答を受け取りたいです
spike_connect_udp(target,port);
spike_send();
s_read_packet();
関数の実装:
int
spike_connect_udp(char * host, int port)
{
int fd;
/*ahh, having udpstuff.c makes this stuff easy*/
fd=udpconnect(host,port);
if (fd==-1)
{
fprintf(stderr,"Couldn't udp connect to target\n");
return (0);
}
current_spike->fd=fd;
current_spike->proto=2; /*UDP*/
return 1;
}
int
udpconnect(const char * host, const unsigned short port )
{
int sfd = -1;
struct sockaddr_in addr;
/* Translate hostname from DNS or IP-address form */
memset(&addr, 0, sizeof(addr));
if (!getHostAddress(host, &addr))
{
hdebug("can't resolve host or address.\n");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = ntohs(port);
if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
hdebug("Could not create socket!\n");
return -1;
}
/* Now connect! */
if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
close(sfd);
return -1;
}
return sfd;
}
int
spike_send()
{
int retval;
switch (current_spike->proto)
{
case 1: /*TCP*/
//deleted, doesnt matter, i am sending via udp
case 2: /*UDP*/
//udp_write_data is function from framework
retval=udp_write_data(current_spike->fd, current_spike->destsockaddr, s_get_size(), s_get_databuf());
break;
}
fflush(0);
return retval;
}
これは正常に機能し、udp 経由でデータを送信します。ここで、開いているソケット current_spike->fd を介していくつかの応答を受け取りたいと考えています。関数 s_read_packet void
s_read_packet()
{
unsigned char buffer[5000];
int i;
int size;
s_fd_wait();
printf("Reading packet\n");
memset(buffer,0x00,sizeof(buffer));
/what alarm and fcntl does?
alarm(1);
fcntl(current_spike->fd, F_SETFL, O_NONBLOCK);
//this read return error -1 and sets errno to 11 service temporarily unavailable
size=read(current_spike->fd,buffer,1500);
fcntl(current_spike->fd, F_SETFL, 0);
alarm(0);
for (i=0; i<size; i++)
{
if (isprint(buffer[i]))
printf("%c",buffer[i]);
else
printf("[%2.2x]",buffer[i]);
}
printf("\nDone with read\n");
}
int
s_fd_wait()
{
/*this function does a select to wait for
input on the fd, and if there
is, returns 1, else 0 */
int fd;
fd_set rfds;
struct timeval tv;
int retval;
fd=current_spike->fd;
/* Watch server_fd (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
/* Wait up to zero seconds . will this wait forever? not on linux.*/
/* from man page: timeout is an upper bound on the amount of time
elapsed before select returns. It may be zero, causing select
to return immediately. If timeout is NULL (no timeout), select
can block indefinitely. */
/*wait 2 seconds only*/
tv.tv_sec = TIMEINSECONDS;
tv.tv_usec = TIMEINUSECONDS;
//printf("Before select %d:%d\n",TIMEINSECONDS,TIMEINUSECONDS);
retval = select(fd+1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
//printf("After select retval=%d.\n",retval);
switch (retval)
{
case 0:
/*Timeout - no packet or keypress*/
return(0);
break;
case -1:
/* ignore interrupted system calls */
if (errno != EINTR)
{
/*some kind of weird select error. Die. */
exit(-1);
}
/*otherwise we got interrupted, so just return false*/
return (0);
break;
default:
{
if (FD_ISSET(fd,&rfds))
return (1);
else
return (0);
}
}
}
しかし、関数 s_read_packet はデータを生成しません...