]>
git.zerfleddert.de Git - record-dvb/blob - sap.c
d8b028434ead4f7a07dc4b24f52666c2fa680a3e
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=", sdp
, 2)) {
59 sdpinfo
.service
= sdp
+ 2;
60 } else if (!strncasecmp("c=", sdp
, 2)) {
65 if (poscnt
== 2 && *sdp
== '/') {
74 /* c=<network type> <address type> <connection address> */
76 sdpinfo
.host
= sdp
+ 1;
83 } else if (!strncasecmp("m=", sdp
, 2)) {
92 /* m=<media> <port> <transport> <fmt list> */
94 sdpinfo
.port
= sdp
+ 1;
97 sdpinfo
.proto
= sdp
+ 1;
116 char *get_url_from_sap(char *service
)
118 struct timeval start
, curr
;
120 unsigned char buffer
[BUFFSIZE
];
124 snprintf(buffer
,BUFFSIZE
,"udp://%s:%u", SAP_ADDR
, SAP_PORT
);
126 fd
= open_mcast(buffer
);
128 gettimeofday(&start
, NULL
);
135 int sap_version
, sap_addrtype
, sap_messagetype
, sap_encrypted
, sap_compressed
;
136 in_addr_t sender_address
;
137 unsigned char auth_len
;
138 unsigned short msgid
;
140 struct sdp_info
*sdpinfo
;
148 if ((retval
= select(fd
+1, &rfds
, NULL
, NULL
, &tv
)) == -1) {
154 gettimeofday(&curr
, NULL
);
158 bzero(buffer
, BUFFSIZE
);
159 if ((recvd
= recv(fd
, buffer
, BUFFSIZE
, 0)) < 1) {
164 gettimeofday(&curr
, NULL
);
166 sap_version
= (buffer
[0] >> 5) & 0x7;
167 sap_addrtype
= (buffer
[0] >> 4) & 0x1;
168 sap_messagetype
= (buffer
[0] >> 2) & 0x1;
169 sap_encrypted
= (buffer
[0] >> 1) & 0x1;
170 sap_compressed
= buffer
[0] & 0x1;
171 auth_len
= buffer
[1];
172 msgid
= buffer
[2] << 8 | buffer
[3];
173 memcpy(&sender_address
, buffer
+4, (sap_addrtype
?16:4));
174 sdp
= buffer
+ 4 /* (sap_*, auth_len, msgid) */ + (sap_addrtype
?16:4) + auth_len
;
178 printf("SAP-Version: %d\n", sap_version
);
179 printf("Adresstyp: %s\n", (sap_addrtype
?"IPv6":"IPv4"));
180 printf("Messagetype: %s\n", (sap_messagetype
?"Announcement":"Deletion"));
181 printf("Encrypted: %d\n", sap_encrypted
);
182 printf("Compressed: %d\n", sap_compressed
);
183 printf("Authentication Length: %d\n", auth_len
);
184 printf("Sender: %u\n", sender_address
);
185 printf("Message Identifier Hash: %u\n", msgid
);
189 continue; /* We don't support IPv6 for now */
191 #if 0 /* Getstream gets this wrong, see rfc2974 */
193 continue; /* We are not interested in deletions */
196 if (sap_encrypted
|| sap_compressed
)
199 sdpinfo
= parse_sdp(sdp
, recvd
-(sdp
-buffer
));
201 if (sdpinfo
->service
&& sdpinfo
->proto
&& sdpinfo
->port
) {
202 if (!sdpinfo
->host
) {
203 struct in_addr inaddr
;
205 inaddr
.s_addr
= sender_address
;
206 sdpinfo
->host
= inet_ntoa(inaddr
);
210 printf("%s -> %s://%s:%s\n", sdpinfo
->service
, sdpinfo
->proto
, sdpinfo
->host
, sdpinfo
->port
);
213 if (strlen(service
) < strlen(sdpinfo
->service
)) {
214 sdpinfo
->service
+= strlen(sdpinfo
->service
) - strlen(service
);
217 if (!strncasecmp(service
, sdpinfo
->service
, strlen(service
))) {
218 int len
= strlen(sdpinfo
->host
)+strlen(sdpinfo
->proto
)+strlen(sdpinfo
->port
)+5;
220 if (!(url
= malloc(len
))) {
225 snprintf(url
, len
, "%s://%s:%s", sdpinfo
->proto
, sdpinfo
->host
, sdpinfo
->port
);
231 } while(curr
.tv_sec
< start
.tv_sec
+SAP_TIMEOUT
);
233 mreq
.imr_multiaddr
.s_addr
= inet_addr(SAP_ADDR
);
234 mreq
.imr_interface
.s_addr
= INADDR_ANY
;
235 setsockopt (fd
, IPPROTO_IP
, IP_DROP_MEMBERSHIP
, &mreq
, sizeof(mreq
));