rtp.c

Go to the documentation of this file.
00001 /* $Id: rtp.c,v 1.16 2005/11/22 22:15:39 robert Exp $ */
00002 
00003 #ifdef HAVE_CONFIG_H
00004 # include <config.h>
00005 /* std int types already defined in config.h */
00006 # define _STDINT_H
00007 #endif
00008 
00009 #ifndef __GNUC__
00010 # if HAVE_ALLOCA_H
00011 #  include <alloca.h>
00012 # else
00013 #  ifdef _AIX
00014 #pragma alloca
00015 #  else
00016 #   ifndef alloca       /* predefined by HP cc +Olibcalls */
00017 char   *alloca();
00018 #   endif
00019 #  endif
00020 # endif
00021 #endif
00022 
00023 #include <stdio.h>
00024 #include <stdarg.h>
00025 
00026 #ifdef STDC_HEADERS
00027 # include <stdlib.h>
00028 # include <string.h>
00029 #else
00030 # ifndef HAVE_STRCHR
00031 #  define strchr index
00032 #  define strrchr rindex
00033 # endif
00034 char   *strchr(), *strrchr();
00035 # ifndef HAVE_MEMCPY
00036 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
00037 #  define memmove(d, s, n) bcopy ((s), (d), (n))
00038 # endif
00039 #endif
00040 
00041 #ifdef HAVE_UNISTD_H
00042 # include <unistd.h>
00043 #endif
00044 
00045 #include <sys/types.h>
00046 #include <sys/socket.h>
00047 #include <netinet/in.h>
00048 #include <arpa/inet.h>
00049 
00050 #include "console.h"
00051 
00052 #ifdef WITH_DMALLOC
00053 #include <dmalloc.h>
00054 #endif
00055 
00056 struct rtpbits {
00057     int     sequence:16;     /* sequence number: random */
00058     int     pt:7;            /* payload type: 14 for MPEG audio */
00059     int     m:1;             /* marker: 0 */
00060     int     cc:4;            /* number of CSRC identifiers: 0 */
00061     int     x:1;             /* number of extension headers: 0 */
00062     int     p:1;             /* is there padding appended: 0 */
00063     int     v:2;             /* version: 2 */
00064 };
00065 
00066 struct rtpheader {           /* in network byte order */
00067     struct rtpbits b;
00068     int     timestamp;       /* start: random */
00069     int     ssrc;            /* random */
00070     int     iAudioHeader;    /* =0?! */
00071 };
00072 
00073 void
00074 initrtp(struct rtpheader *foo)
00075 {
00076     foo->b.v = 2;
00077     foo->b.p = 0;
00078     foo->b.x = 0;
00079     foo->b.cc = 0;
00080     foo->b.m = 0;
00081     foo->b.pt = 14;     /* MPEG Audio */
00082 #ifdef FEFE
00083     foo->b.sequence = 42;
00084     foo->timestamp = 0;
00085 #else
00086     foo->b.sequence = rand() & 65535;
00087     foo->timestamp = rand();
00088 #endif
00089     foo->ssrc = rand();
00090     foo->iAudioHeader = 0;
00091 }
00092 
00093 int
00094 sendrtp(int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo, const void *data, int len)
00095 {
00096     char   *buf = alloca(len + sizeof(struct rtpheader));
00097     int    *cast = (int *) foo;
00098     int    *outcast = (int *) buf;
00099     outcast[0] = htonl(cast[0]);
00100     outcast[1] = htonl(cast[1]);
00101     outcast[2] = htonl(cast[2]);
00102     outcast[3] = htonl(cast[3]);
00103     memmove(buf + sizeof(struct rtpheader), data, len);
00104     return sendto(fd, buf, len + sizeof(*foo), 0,
00105                   (struct sockaddr *) sSockAddr, sizeof(*sSockAddr));
00106 /*  return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
00107 }
00108 
00109 /* create a sender socket. */
00110 int
00111 makesocket(char *szAddr, unsigned short port, unsigned char TTL, struct sockaddr_in *sSockAddr)
00112 {
00113     int     iRet, iLoop = 1;
00114     struct sockaddr_in sin;
00115     unsigned char cTtl = TTL;
00116     char    cLoop = 0;
00117     unsigned int tempaddr;
00118 
00119     int     iSocket = socket(AF_INET, SOCK_DGRAM, 0);
00120     if (iSocket < 0) {
00121         error_printf("socket() failed.\n");
00122         exit(1);
00123     }
00124 
00125     tempaddr = inet_addr(szAddr);
00126     sSockAddr->sin_family = sin.sin_family = AF_INET;
00127     sSockAddr->sin_port = sin.sin_port = htons(port);
00128     sSockAddr->sin_addr.s_addr = tempaddr;
00129 
00130     iRet = setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, &iLoop, sizeof(int));
00131     if (iRet < 0) {
00132         error_printf("setsockopt SO_REUSEADDR failed\n");
00133         exit(1);
00134     }
00135 
00136     if ((ntohl(tempaddr) >> 28) == 0xe) {
00137         /* only set multicast parameters for multicast destination IPs */
00138         iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_TTL, &cTtl, sizeof(char));
00139         if (iRet < 0) {
00140             error_printf("setsockopt IP_MULTICAST_TTL failed.  multicast in kernel?\n");
00141             exit(1);
00142         }
00143 
00144         cLoop = 1;      /* !? */
00145         iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &cLoop, sizeof(char));
00146         if (iRet < 0) {
00147             error_printf("setsockopt IP_MULTICAST_LOOP failed.  multicast in kernel?\n");
00148             exit(1);
00149         }
00150     }
00151 
00152     return iSocket;
00153 }
00154 
00155 
00156 
00157 
00158 #if 0
00159 /* */
00160 /* code contributed by Anonymous source.  Supposed to be much better */
00161 /* then original code, but only seems to run on windows with MSVC.   */
00162 /* and I cannot test it */
00163 /* */
00164 #include <stdlib.h>
00165 #include <string.h>
00166 #include <netinet/in.h>
00167 #include <unistd.h>
00168 #include <stdio.h>
00169 #include <sys/types.h>
00170 #include <sys/socket.h>
00171 #include <arpa/inet.h>
00172 
00173 struct rtpbits {
00174     int     sequence:16;     /* sequence number: random */
00175     int     pt:7;            /* payload type: 14 for MPEG audio */
00176     int     m:1;             /* marker: 0 */
00177     int     cc:4;            /* number of CSRC identifiers: 0 */
00178     int     x:1;             /* number of extension headers: 0 */
00179     int     p:1;             /* is there padding appended: 0 */
00180     int     v:2;             /* version: 2 */
00181 };
00182 
00183 struct rtpheader {           /* in network byte order */
00184     struct rtpbits b;
00185     int     timestamp;       /* start: random */
00186     int     ssrc;            /* random */
00187     int     iAudioHeader;    /* =0?! */
00188 };
00189 
00190 void
00191 rtp_initialization(struct rtpheader *foo)
00192 {
00193     foo->b.v = 2;
00194     foo->b.p = 0;
00195     foo->b.x = 0;
00196     foo->b.cc = 0;
00197     foo->b.m = 0;
00198     foo->b.pt = 14;     /* MPEG Audio */
00199 #ifdef FEFE
00200     foo->b.sequence = 42;
00201     foo->timestamp = 0;
00202 #else
00203     foo->b.sequence = rand() & 65535;
00204     foo->timestamp = rand();
00205 #endif
00206     foo->ssrc = rand();
00207     foo->iAudioHeader = 0;
00208 }
00209 
00210 int
00211 rtp_send(SOCKET s, struct rtpheader *foo, void *data, int len)
00212 {
00213     char   *buffer = malloc(len + sizeof(struct rtpheader));
00214     int    *cast = (int *) foo;
00215     int    *outcast = (int *) buffer;
00216     int     count, size;
00217 
00218     outcast[0] = htonl(cast[0]);
00219     outcast[1] = htonl(cast[1]);
00220     outcast[2] = htonl(cast[2]);
00221     outcast[3] = htonl(cast[3]);
00222     memmove(buffer + sizeof(struct rtpheader), data, len);
00223 /*    return sendto (fd,buf,len+sizeof(*foo),0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr)); */
00224 /*  return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
00225     size = len + sizeof(*foo);
00226     count = send(s, buffer, size, 0);
00227     free(buffer);
00228 
00229     return count != size;
00230 }
00231 
00232 /* create a sender socket. */
00233 int
00234 rtp_socket(SOCKET * ps, char *address, unsigned short port, int TTL)
00235 {
00236 /*    int iRet ; */
00237     int     iLoop = 1;
00238 /*    struct  sockaddr_in sin ; */
00239     char    cTTL = (char) TTL;
00240     char    cLoop = 0;
00241 /*    unsigned int tempaddr ; */
00242     BOOL    True = TRUE;
00243     INT     error;
00244     char   *c = "";
00245     UINT    ip;
00246     PHOSTENT host;
00247     SOCKET  s;
00248     SOCKADDR_IN source, dest;
00249 #if 0
00250     int     s = socket(AF_INET, SOCK_DGRAM, 0);
00251     if (s < 0) {
00252         error_printf("socket() failed.\n");
00253         exit(1);
00254     }
00255 
00256     tempaddr = inet_addr(address);
00257     sSockAddr->sin_family = sin.sin_family = AF_INET;
00258     sSockAddr->sin_port = sin.sin_port = htons(port);
00259     sSockAddr->sin_addr.s_addr = tempaddr;
00260 
00261     iRet = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &iLoop, sizeof(int));
00262     if (iRet < 0) {
00263         error_printf("setsockopt SO_REUSEADDR failed\n");
00264         exit(1);
00265     }
00266 
00267     if ((ntohl(tempaddr) >> 28) == 0xe) {
00268         /* only set multicast parameters for multicast destination IPs */
00269         iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &cTTL, sizeof(char));
00270         if (iRet < 0) {
00271             error_printf("setsockopt IP_MULTICAST_TTL failed.    multicast in kernel?\n");
00272             exit(1);
00273         }
00274 
00275         cLoop = 1;      /* !? */
00276         iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &cLoop, sizeof(char));
00277         if (iRet < 0) {
00278             error_printf("setsockopt IP_MULTICAST_LOOP failed.    multicast in kernel?\n");
00279             exit(1);
00280         }
00281     }
00282 #endif
00283     source.sin_family = AF_INET;
00284     source.sin_addr.s_addr = htonl(INADDR_ANY);
00285     source.sin_port = htons(0);
00286 
00287     dest.sin_family = AF_INET;
00288     dest.sin_addr.s_addr = inet_addr(address);
00289 
00290     if (!strcmp(address, "255.255.255.255")) {
00291     }
00292     else if (dest.sin_addr.s_addr == INADDR_NONE) {
00293         host = gethostbyname(address);
00294 
00295         if (host) {
00296             dest.sin_addr = *(PIN_ADDR) host->h_addr;
00297         }
00298         else {
00299             printf("Unknown host %s\r\n", address);
00300             return 1;
00301         }
00302     }
00303 
00304     dest.sin_port = htons((u_short) port);
00305 
00306     ip = ntohl(dest.sin_addr.s_addr);
00307 
00308     if (IN_CLASSA(ip))
00309         c = "class A";
00310     if (IN_CLASSB(ip))
00311         c = "class B";
00312     if (IN_CLASSC(ip))
00313         c = "class C";
00314     if (IN_CLASSD(ip))
00315         c = "class D";
00316     if (ip == INADDR_LOOPBACK)
00317         c = "loopback";
00318     if (ip == INADDR_BROADCAST)
00319         c = "broadcast";
00320 
00321     s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
00322 
00323     if (s == INVALID_SOCKET) {
00324         error = WSAGetLastError();
00325         printf("socket () error %d\r\n", error);
00326         return error;
00327     }
00328 
00329     error = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &True, sizeof(BOOL));
00330 
00331     error = bind(s, (struct sockaddr *) &source, sizeof(source));
00332 
00333     if (error == SOCKET_ERROR) {
00334         error = WSAGetLastError();
00335         printf("bind () error %d\r\n", error);
00336         closesocket(s);
00337         return error;
00338     }
00339 
00340     if (ip == INADDR_BROADCAST) {
00341         printf("broadcast %s:%u %s\r\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), c);
00342 
00343         error = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char *)
00344                            &True, sizeof(BOOL));
00345 
00346         if (error == SOCKET_ERROR) {
00347             error = WSAGetLastError();
00348             printf("setsockopt (%u, SOL_SOCKET, SO_BROADCAST, ...) error %d\r\n", s, error);
00349             closesocket(s);
00350             return error;
00351         }
00352     }
00353 
00354     if (IN_CLASSD(ip)) {
00355         printf("multicast %s:%u %s\r\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), c);
00356 
00357 /*        error = setsockopt (s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &TTL, sizeof (int)) ; */
00358         error = setsockopt(s, IPPROTO_IP, 3, (const char *) &TTL, sizeof(int));
00359 
00360         if (error == SOCKET_ERROR) {
00361             error = WSAGetLastError();
00362             printf("setsockopt (%u, IPPROTO_IP, IP_MULTICAST_TTL, ...) error %d\r\n", s, error);
00363             closesocket(s);
00364             return error;
00365         }
00366     }
00367 
00368     error = connect(s, (PSOCKADDR) & dest, sizeof(SOCKADDR_IN));
00369 
00370     if (error == SOCKET_ERROR) {
00371         printf("connect: error %d\n", WSAGetLastError());
00372         closesocket(s);
00373         return error;
00374     }
00375 
00376     *ps = s;
00377 
00378     return 0;
00379 }
00380 
00381 
00382 
00383 #endif

Generated on Sun Dec 2 11:34:18 2007 for LAME by  doxygen 1.5.2