]>
cvs.zerfleddert.de Git - record-dvb/blob - sap.c
654e8ac086afdd30588ade4e750912b34025b136
   4 #include <sys/socket.h> 
   5 #include <netinet/in.h>          
  12 #include <sys/select.h> 
  17 #define SAP_ADDR        "224.2.127.254" 
  19 #define SAP_MAX_SIZE    1024 
  23 #define BUFFSIZE        SAP_MAX_SIZE 
  32 struct sdp_info 
*parse_sdp(char *sdp
, int len
) 
  35         static struct sdp_info sdpinfo
; 
  39          * o=- 6dca 1 IN IP4 192.168.100.17:2000 
  42          * c=IN IP4 192.168.100.17/1 
  43          * m=video 2000 http 33 
  48         bzero(&sdpinfo
, sizeof(struct sdp_info
)); 
  51         while(*pos 
!= 0 && (pos
-sdp
) < len
) { 
  58                         if (!strncasecmp("s=", line
, 2)) { 
  59                                 sdpinfo
.service 
= line 
+ 2; 
  60                         } else if (!strncasecmp("c=", line
, 2)) { 
  65                                         if (poscnt 
== 2 && *line 
== '/') { 
  74                                                 /* c=<network type> <address type> <connection address> */ 
  76                                                         sdpinfo
.host 
= line 
+ 1; 
  83                         } else if (!strncasecmp("m=", line
, 2)) { 
  92                                                 /* m=<media> <port> <transport> <fmt list> */ 
  94                                                         sdpinfo
.port 
= line 
+ 1; 
  97                                                         sdpinfo
.proto 
= line 
+ 1; 
 116 char *get_url_from_sap(char *service
) 
 118         struct timeval start
, curr
; 
 120         unsigned char buffer
[BUFFSIZE
]; 
 121         struct in_addr sapinaddr
; 
 125         snprintf(buffer
,BUFFSIZE
,"udp://%s:%u", SAP_ADDR
, SAP_PORT
); 
 127         fd 
= open_mcast(buffer
); 
 129         gettimeofday(&start
, NULL
); 
 136                 int sap_version
, sap_addrtype
, sap_messagetype
, sap_encrypted
, sap_compressed
; 
 137                 uint8_t sender_address
[16]; /* This might be IPv6! */ 
 138                 unsigned char auth_len
; 
 139                 unsigned short msgid
; 
 141                 struct sdp_info 
*sdpinfo
; 
 149                 if ((retval 
= select(fd
+1, &rfds
, NULL
, NULL
, &tv
)) == -1) { 
 155                         gettimeofday(&curr
, NULL
); 
 159                 bzero(buffer
, BUFFSIZE
); 
 160                 if ((recvd 
= recv(fd
, buffer
, BUFFSIZE
, 0)) < 1) { 
 165                 gettimeofday(&curr
, NULL
); 
 167                 sap_version 
= (buffer
[0] >> 5) & 0x7; 
 168                 sap_addrtype 
= (buffer
[0] >> 4) & 0x1; 
 169                 sap_messagetype 
= (buffer
[0] >> 2) & 0x1; 
 170                 sap_encrypted 
= (buffer
[0] >> 1) & 0x1; 
 171                 sap_compressed 
= buffer
[0] & 0x1; 
 172                 auth_len 
= buffer
[1]; 
 173                 msgid 
= buffer
[2] << 8 | buffer
[3]; 
 174                 memcpy(sender_address
, buffer
+4, (sap_addrtype
?16:4)); 
 175                 sdp 
= buffer 
+ 4 /* (sap_*, auth_len, msgid) */ + (sap_addrtype
?16:4) + auth_len
; 
 179                 printf("SAP-Version: %d\n", sap_version
); 
 180                 printf("Adresstyp: %s\n", (sap_addrtype
?"IPv6":"IPv4")); 
 181                 printf("Messagetype: %s\n", (sap_messagetype
?"Announcement":"Deletion")); 
 182                 printf("Encrypted: %d\n", sap_encrypted
); 
 183                 printf("Compressed: %d\n", sap_compressed
); 
 184                 printf("Authentication Length: %d\n", auth_len
); 
 185                 printf("Sender: %u\n", *((in_addr_t
*)sender_address
)); 
 186                 printf("Message Identifier Hash: %u\n", msgid
); 
 189 #if 0 /* Getstream gets this wrong, see rfc2974 */ 
 191                         continue; /* We are not interested in deletions */ 
 194                 if (sap_encrypted 
|| sap_compressed
) 
 197                 sdpinfo 
= parse_sdp(sdp
, recvd
-(sdp
-buffer
)); 
 199                 if (sdpinfo
->service 
&& sdpinfo
->proto 
&& sdpinfo
->port
) { 
 200                         char hostbuf
[INET6_ADDRSTRLEN
]; 
 202                         if (!sdpinfo
->host
) { 
 205                                          struct in6_addr in6addr
; 
 207                                          memcpy(in6addr
.in6_u
.u6_addr8
, sender_address
, 16); 
 208                                          if (!(sdpinfo
->host 
= (char*)inet_ntop(AF_INET6
, &in6addr
, hostbuf
, INET6_ADDRSTRLEN
))) { 
 213                                          struct in_addr inaddr
; 
 215                                          inaddr
.s_addr 
= *((in_addr_t
*)sender_address
); 
 216                                          if (!(sdpinfo
->host 
= (char*)inet_ntop(AF_INET
, &inaddr
, hostbuf
, INET6_ADDRSTRLEN
))) { 
 224                         printf("%s -> %s://%s:%s\n", sdpinfo
->service
, sdpinfo
->proto
, sdpinfo
->host
, sdpinfo
->port
); 
 227                         if (strlen(service
) < strlen(sdpinfo
->service
)) { 
 228                                 sdpinfo
->service 
+= strlen(sdpinfo
->service
) - strlen(service
); 
 231                         if (!strncasecmp(service
, sdpinfo
->service
, strlen(service
))) { 
 232                                 int len 
= strlen(sdpinfo
->host
)+strlen(sdpinfo
->proto
)+strlen(sdpinfo
->port
)+5; 
 234                                 if (!(url 
= malloc(len
))) { 
 239                                 snprintf(url
, len
, "%s://%s:%s", sdpinfo
->proto
, sdpinfo
->host
, sdpinfo
->port
); 
 245         } while(curr
.tv_sec 
< start
.tv_sec
+SAP_TIMEOUT 
|| 
 246                 ((curr
.tv_sec 
== start
.tv_sec
+SAP_TIMEOUT
) && (curr
.tv_usec 
< start
.tv_usec
))); 
 248         if (!(inet_aton(SAP_ADDR
, &sapinaddr
))) { 
 252         mreq
.imr_multiaddr
.s_addr 
= sapinaddr
.s_addr
; 
 253         mreq
.imr_interface
.s_addr 
= INADDR_ANY
; 
 254         setsockopt (fd
, IPPROTO_IP
, IP_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
));