]>
cvs.zerfleddert.de Git - record-dvb/blob - sap.c
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
25 char *get_url_from_sap(char *service
)
27 struct timeval start
, curr
;
29 unsigned char buffer
[BUFFSIZE
];
33 snprintf(buffer
,BUFFSIZE
,"udp://%s:%u", SAP_ADDR
, SAP_PORT
);
35 fd
= open_mcast(buffer
);
37 gettimeofday(&start
, NULL
);
41 int sap_version
, sap_addrtype
, sap_messagetype
, sap_encrypted
, sap_compressed
;
42 in_addr_t sender_address
;
43 unsigned char auth_len
;
45 unsigned char *payload
, *pos
, *host
= NULL
, *proto
= NULL
, *port
= NULL
, *sname
= NULL
;
56 if ((retval
= select(fd
+1, &rfds
, NULL
, NULL
, &tv
)) == -1) {
62 gettimeofday(&curr
, NULL
);
66 if ((recvd
= recv(fd
, buffer
, BUFFSIZE
, 0)) < 1) {
71 gettimeofday(&curr
, NULL
);
73 sap_version
= (buffer
[0] >> 5) & 0x7;
74 sap_addrtype
= (buffer
[0] >> 4) & 0x1;
75 sap_messagetype
= (buffer
[0] >> 2) & 0x1;
76 sap_encrypted
= (buffer
[0] >> 1) & 0x1;
77 sap_compressed
= buffer
[0] & 0x1;
79 msgid
= buffer
[2] << 8 | buffer
[3];
80 memcpy(&sender_address
, buffer
+4, (sap_addrtype
?16:4));
81 payload
= buffer
+ 4 /* (sap_*, auth_len, msgid) */ + (sap_addrtype
?16:4) + auth_len
;
85 printf("SAP-Version: %d\n", sap_version
);
86 printf("Adresstyp: %s\n", (sap_addrtype
?"IPv6":"IPv4"));
87 printf("Messagetype: %s\n", (sap_messagetype
?"Announcement":"Deletion"));
88 printf("Encrypted: %d\n", sap_encrypted
);
89 printf("Compressed: %d\n", sap_compressed
);
90 printf("Authentication Length: %d\n", auth_len
);
91 printf("Sender: %u\n", sender_address
);
92 printf("Message Identifier Hash: %u\n", msgid
);
96 continue; /* We don't support IPv6 for now */
98 #if 0 /* Getstream gets this wrong, see rfc2974 */
100 continue; /* We are not interested in deletions */
103 if (sap_encrypted
|| sap_compressed
)
108 * o=- 6dca 1 IN IP4 192.168.100.17:2000
111 * c=IN IP4 192.168.100.17/1
112 * m=video 2000 http 33
118 while(*pos
!= 0 && (pos
-buffer
) < recvd
) {
125 if (!strncasecmp("s=", payload
, 2)) {
127 } else if (!strncasecmp("c=", payload
, 2)) {
131 while (*payload
!= 0) {
132 if (poscnt
== 2 && *payload
== '/') {
137 if (*payload
== ' ') {
141 /* c=<network type> <address type> <connection address> */
150 } else if (!strncasecmp("m=", payload
, 2)) {
154 while (*payload
!= 0) {
155 if (*payload
== ' ') {
159 /* m=<media> <port> <transport> <fmt list> */
179 if (sname
&& proto
&& port
) {
181 struct in_addr inaddr
;
183 inaddr
.s_addr
= sender_address
;
184 host
= inet_ntoa(inaddr
);
188 printf("%s -> %s://%s:%s\n", sname
, proto
, host
, port
);
191 if (strlen(service
) < strlen(sname
)) {
192 sname
+= strlen(sname
) - strlen(service
);
195 if (!strncasecmp(service
, sname
, strlen(service
))) {
196 int len
= strlen(host
)+strlen(proto
)+strlen(port
)+5;
198 if (!(url
= malloc(len
))) {
203 snprintf(url
, len
, "%s://%s:%s", proto
, host
, port
);
209 } while(curr
.tv_sec
< start
.tv_sec
+SAP_TIMEOUT
);
211 mreq
.imr_multiaddr
.s_addr
= inet_addr(SAP_ADDR
);
212 mreq
.imr_interface
.s_addr
= INADDR_ANY
;
213 setsockopt (fd
, IPPROTO_IP
, IP_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
));