struct sdp_info *parse_sdp(char *sdp, int len)
{
- char *pos;
+ char *pos, *line;
static struct sdp_info sdpinfo;
/* RFC 2327
bzero(&sdpinfo, sizeof(struct sdp_info));
- pos = sdp;
+ pos = line = sdp;
while(*pos != 0 && (pos-sdp) < len) {
if (*pos == 0x0d)
*pos = 0;
if (*pos == 0x0a) {
*pos = 0;
- if (!strncasecmp("s=", sdp, 2)) {
- sdpinfo.service = sdp + 2;
- } else if (!strncasecmp("c=", sdp, 2)) {
+ if (!strncasecmp("s=", line, 2)) {
+ sdpinfo.service = line + 2;
+ } else if (!strncasecmp("c=", line, 2)) {
int poscnt = 0;
- sdp += 2;
- while (*sdp != 0) {
- if (poscnt == 2 && *sdp == '/') {
- *sdp = 0;
+ line += 2;
+ while (*line != 0) {
+ if (poscnt == 2 && *line == '/') {
+ *line = 0;
break;
}
- if (*sdp == ' ') {
- *sdp = 0;
+ if (*line == ' ') {
+ *line = 0;
poscnt++;
/* c=<network type> <address type> <connection address> */
if (poscnt == 2)
- sdpinfo.host = sdp + 1;
+ sdpinfo.host = line + 1;
if (poscnt > 2)
break;
}
- sdp++;
+ line++;
}
- } else if (!strncasecmp("m=", sdp, 2)) {
+ } else if (!strncasecmp("m=", line, 2)) {
int poscnt = 0;
- sdp += 2;
- while (*sdp != 0) {
- if (*sdp == ' ') {
- *sdp = 0;
+ line += 2;
+ while (*line != 0) {
+ if (*line == ' ') {
+ *line = 0;
poscnt++;
/* m=<media> <port> <transport> <fmt list> */
if (poscnt == 1)
- sdpinfo.port = sdp + 1;
+ sdpinfo.port = line + 1;
if (poscnt == 2)
- sdpinfo.proto = sdp + 1;
+ sdpinfo.proto = line + 1;
if (poscnt > 2)
break;
}
- sdp++;
+ line++;
}
}
- sdp = ++pos;
+ line = ++pos;
continue;
}
pos++;
struct timeval start, curr;
struct ip_mreq mreq;
unsigned char buffer[BUFFSIZE];
+ struct in_addr sapinaddr;
char *url = NULL;
int fd;
struct timeval tv;
int retval;
int sap_version, sap_addrtype, sap_messagetype, sap_encrypted, sap_compressed;
- in_addr_t sender_address;
+ uint8_t sender_address[16]; /* This might be IPv6! */
unsigned char auth_len;
unsigned short msgid;
unsigned char *sdp;
if ((retval = select(fd+1, &rfds, NULL, NULL, &tv)) == -1) {
perror("select");
- return NULL;
+ break;
}
if (!retval) {
bzero(buffer, BUFFSIZE);
if ((recvd = recv(fd, buffer, BUFFSIZE, 0)) < 1) {
perror("recv");
- return NULL;
+ break;
}
gettimeofday(&curr, NULL);
sap_compressed = buffer[0] & 0x1;
auth_len = buffer[1];
msgid = buffer[2] << 8 | buffer[3];
- memcpy(&sender_address, buffer+4, (sap_addrtype?16:4));
+ memcpy(sender_address, buffer+4, (sap_addrtype?16:4));
sdp = buffer + 4 /* (sap_*, auth_len, msgid) */ + (sap_addrtype?16:4) + auth_len;
#ifdef DEBUG
printf("Encrypted: %d\n", sap_encrypted);
printf("Compressed: %d\n", sap_compressed);
printf("Authentication Length: %d\n", auth_len);
- printf("Sender: %u\n", sender_address);
+ printf("Sender: %u\n", *((in_addr_t*)sender_address));
printf("Message Identifier Hash: %u\n", msgid);
#endif
- if (sap_addrtype)
- continue; /* We don't support IPv6 for now */
-
#if 0 /* Getstream gets this wrong, see rfc2974 */
if (sap_messagetype)
continue; /* We are not interested in deletions */
sdpinfo = parse_sdp(sdp, recvd-(sdp-buffer));
if (sdpinfo->service && sdpinfo->proto && sdpinfo->port) {
+ char hostbuf[INET6_ADDRSTRLEN];
+
if (!sdpinfo->host) {
- struct in_addr inaddr;
- inaddr.s_addr = sender_address;
- sdpinfo->host = inet_ntoa(inaddr);
+ if (sap_addrtype) {
+ struct in6_addr in6addr;
+
+ memcpy(in6addr.s6_addr, sender_address, 16);
+ if (!(sdpinfo->host = (char*)inet_ntop(AF_INET6, &in6addr, hostbuf, INET6_ADDRSTRLEN))) {
+ perror("inet_ntop");
+ continue;
+ }
+ } else {
+ struct in_addr inaddr;
+
+ inaddr.s_addr = *((in_addr_t*)sender_address);
+ if (!(sdpinfo->host = (char*)inet_ntop(AF_INET, &inaddr, hostbuf, INET6_ADDRSTRLEN))) {
+ perror("inet_ntop");
+ continue;
+ }
+ }
}
#ifdef DEBUG
if (!(url = malloc(len))) {
perror("malloc");
- return NULL;
+ break;
}
snprintf(url, len, "%s://%s:%s", sdpinfo->proto, sdpinfo->host, sdpinfo->port);
}
}
- } while(curr.tv_sec < start.tv_sec+SAP_TIMEOUT);
+ } while(curr.tv_sec < start.tv_sec+SAP_TIMEOUT ||
+ ((curr.tv_sec == start.tv_sec+SAP_TIMEOUT) && (curr.tv_usec < start.tv_usec)));
+
+ if (!(inet_aton(SAP_ADDR, &sapinaddr))) {
+ perror("inet_aton");
+ }
- mreq.imr_multiaddr.s_addr = inet_addr(SAP_ADDR);
+ mreq.imr_multiaddr.s_addr = sapinaddr.s_addr;
mreq.imr_interface.s_addr = INADDR_ANY;
setsockopt (fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));