]>
git.zerfleddert.de Git - record-dvb/blob - sap.c
8dfa6944eb0e4aefad2383de7db3cd3bcf58ff21
4 #include <sys/socket.h>
5 #include <netinet/in.h>
15 #define SAP_ADDR "224.2.127.254"
17 #define SAP_MAX_SIZE 1024
21 #define BUFFSIZE SAP_MAX_SIZE
23 char *get_url_from_sap(char *service
)
25 struct timeval start
, curr
;
27 unsigned char buffer
[BUFFSIZE
];
31 snprintf(buffer
,BUFFSIZE
,"udp://%s:%u", SAP_ADDR
, SAP_PORT
);
33 fd
= open_mcast(buffer
);
35 gettimeofday(&start
, NULL
);
39 int sap_version
, sap_addrtype
, sap_messagetype
, sap_encrypted
, sap_compressed
;
40 in_addr_t sender_address
;
41 unsigned char auth_len
;
43 unsigned char *payload
, *pos
, *host
= NULL
, *proto
= NULL
, *port
= NULL
, *sname
= NULL
;
45 if ((recvd
= recv(fd
, buffer
, BUFFSIZE
, 0)) < 1) {
50 gettimeofday(&curr
, NULL
);
52 sap_version
= (buffer
[0] >> 5) & 0x7;
53 sap_addrtype
= (buffer
[0] >> 4) & 0x1;
54 sap_messagetype
= (buffer
[0] >> 2) & 0x1;
55 sap_encrypted
= (buffer
[0] >> 1) & 0x1;
56 sap_compressed
= buffer
[0] & 0x1;
58 msgid
= buffer
[2] << 8 | buffer
[3];
59 memcpy(&sender_address
, buffer
+4, (sap_addrtype
?16:4));
60 payload
= buffer
+ 4 /* (sap_*, auth_len, msgid) */ + (sap_addrtype
?16:4) + auth_len
;
64 printf("SAP-Version: %d\n", sap_version
);
65 printf("Adresstyp: %s\n", (sap_addrtype
?"IPv6":"IPv4"));
66 printf("Messagetype: %s\n", (sap_messagetype
?"Announcement":"Deletion"));
67 printf("Encrypted: %d\n", sap_encrypted
);
68 printf("Compressed: %d\n", sap_compressed
);
69 printf("Authentication Length: %d\n", auth_len
);
70 printf("Sender: %u\n", sender_address
);
71 printf("Message Identifier Hash: %u\n", msgid
);
75 continue; /* We don't support IPv6 for now */
77 #if 0 /* Getstream gets this wrong, see rfc2974 */
79 continue; /* We are not interested in deletions */
82 if (sap_encrypted
|| sap_compressed
)
86 * o=- 6dca 1 IN IP4 192.168.100.17:2000
89 * c=IN IP4 192.168.100.17/1
90 * m=video 2000 http 33
96 while(*pos
!= 0 && (pos
-buffer
) < BUFFSIZE
) {
104 if (!strncasecmp("s=", payload
, 2)) {
106 } else if (!strncasecmp("c=", payload
, 2)) {
110 while (*payload
!= 0) {
111 if (poscnt
== 2 && *payload
== '/') {
116 if (*payload
== ' ') {
120 /* c=<network type> <address type> <connection address> */
131 } else if (!strncasecmp("m=", payload
, 2)) {
135 while (*payload
!= 0) {
136 if (*payload
== ' ') {
140 /* m=<media> <port> <transport> <fmt list> */
163 if (sname
&& proto
&& port
) {
165 struct in_addr inaddr
;
167 inaddr
.s_addr
= sender_address
;
168 host
= inet_ntoa(inaddr
);
172 printf("%s -> %s://%s:%s\n", sname
, proto
, host
, port
);
175 if (strlen(service
) < strlen(sname
)) {
176 sname
+= strlen(sname
) - strlen(service
);
179 if (!strncasecmp(service
, sname
, strlen(service
))) {
180 int len
= strlen(host
)+strlen(proto
)+strlen(port
)+5;
182 if (!(url
= malloc(len
))) {
187 snprintf(url
, len
, "%s://%s:%s", proto
, host
, port
);
193 } while(curr
.tv_sec
< start
.tv_sec
+SAP_TIMEOUT
);
195 mreq
.imr_multiaddr
.s_addr
= inet_addr(SAP_ADDR
);
196 mreq
.imr_interface
.s_addr
= INADDR_ANY
;
197 setsockopt (fd
, IPPROTO_IP
, IP_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
));