X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/record-dvb/blobdiff_plain/ed3679acee1dbd17f59ca487941d0bf35f9eab2a..9ccc842a205f6216f91e5f4bf2916bf987fbf8e4:/sap.c diff --git a/sap.c b/sap.c index d8b0284..6a8ef79 100644 --- a/sap.c +++ b/sap.c @@ -31,7 +31,7 @@ struct sdp_info { struct sdp_info *parse_sdp(char *sdp, int len) { - char *pos; + char *pos, *line; static struct sdp_info sdpinfo; /* RFC 2327 @@ -47,7 +47,7 @@ struct sdp_info *parse_sdp(char *sdp, int len) bzero(&sdpinfo, sizeof(struct sdp_info)); - pos = sdp; + pos = line = sdp; while(*pos != 0 && (pos-sdp) < len) { if (*pos == 0x0d) *pos = 0; @@ -55,55 +55,55 @@ struct sdp_info *parse_sdp(char *sdp, int len) 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=
*/ 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= */ 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++; @@ -118,6 +118,7 @@ char *get_url_from_sap(char *service) struct timeval start, curr; struct ip_mreq mreq; unsigned char buffer[BUFFSIZE]; + struct in_addr sapinaddr; char *url = NULL; int fd; @@ -133,7 +134,7 @@ char *get_url_from_sap(char *service) 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; @@ -147,7 +148,7 @@ char *get_url_from_sap(char *service) if ((retval = select(fd+1, &rfds, NULL, NULL, &tv)) == -1) { perror("select"); - return NULL; + break; } if (!retval) { @@ -158,7 +159,7 @@ char *get_url_from_sap(char *service) bzero(buffer, BUFFSIZE); if ((recvd = recv(fd, buffer, BUFFSIZE, 0)) < 1) { perror("recv"); - return NULL; + break; } gettimeofday(&curr, NULL); @@ -170,7 +171,7 @@ char *get_url_from_sap(char *service) 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 @@ -181,13 +182,10 @@ char *get_url_from_sap(char *service) 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 */ @@ -199,11 +197,27 @@ char *get_url_from_sap(char *service) 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.in6_u.u6_addr8, 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 @@ -219,7 +233,7 @@ char *get_url_from_sap(char *service) if (!(url = malloc(len))) { perror("malloc"); - return NULL; + break; } snprintf(url, len, "%s://%s:%s", sdpinfo->proto, sdpinfo->host, sdpinfo->port); @@ -230,7 +244,11 @@ char *get_url_from_sap(char *service) } while(curr.tv_sec < start.tv_sec+SAP_TIMEOUT); - mreq.imr_multiaddr.s_addr = inet_addr(SAP_ADDR); + if (!(inet_aton(SAP_ADDR, &sapinaddr))) { + perror("inet_aton"); + } + + 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));