Home | History | Annotate | Download | only in test
      1 /*
      2  * rtp.c
      3  *
      4  * library functions for the real-time transport protocol
      5  *
      6  * David A. McGrew
      7  * Cisco Systems, Inc.
      8  */
      9 /*
     10  *
     11  * Copyright (c) 2001-2006, Cisco Systems, Inc.
     12  * All rights reserved.
     13  *
     14  * Redistribution and use in source and binary forms, with or without
     15  * modification, are permitted provided that the following conditions
     16  * are met:
     17  *
     18  *   Redistributions of source code must retain the above copyright
     19  *   notice, this list of conditions and the following disclaimer.
     20  *
     21  *   Redistributions in binary form must reproduce the above
     22  *   copyright notice, this list of conditions and the following
     23  *   disclaimer in the documentation and/or other materials provided
     24  *   with the distribution.
     25  *
     26  *   Neither the name of the Cisco Systems, Inc. nor the names of its
     27  *   contributors may be used to endorse or promote products derived
     28  *   from this software without specific prior written permission.
     29  *
     30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     33  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     34  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     35  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     36  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     37  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     40  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     41  * OF THE POSSIBILITY OF SUCH DAMAGE.
     42  *
     43  */
     44 
     45 
     46 #include "rtp_priv.h"
     47 
     48 #include <stdio.h>
     49 #include <string.h>
     50 
     51 #include <sys/types.h>
     52 #ifdef HAVE_SYS_SOCKET_H
     53 # include <sys/socket.h>
     54 #endif
     55 
     56 #define PRINT_DEBUG    0    /* set to 1 to print out debugging data */
     57 #define VERBOSE_DEBUG  0    /* set to 1 to print out more data      */
     58 
     59 int
     60 rtp_sendto(rtp_sender_t sender, const void* msg, int len) {
     61   int octets_sent;
     62   err_status_t stat;
     63   int pkt_len = len + RTP_HEADER_LEN;
     64 
     65   /* marshal data */
     66   strncpy(sender->message.body, msg, len);
     67 
     68   /* update header */
     69   sender->message.header.seq = ntohs(sender->message.header.seq) + 1;
     70   sender->message.header.seq = htons(sender->message.header.seq);
     71   sender->message.header.ts = ntohl(sender->message.header.ts) + 1;
     72   sender->message.header.ts = htonl(sender->message.header.ts);
     73 
     74   /* apply srtp */
     75   stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len);
     76   if (stat) {
     77 #if PRINT_DEBUG
     78     fprintf(stderr, "error: srtp protection failed with code %d\n", stat);
     79 #endif
     80     return -1;
     81   }
     82 #if VERBOSE_DEBUG
     83   srtp_print_packet(&sender->message.header, pkt_len);
     84 #endif
     85   octets_sent = sendto(sender->socket, (void*)&sender->message,
     86 		       pkt_len, 0, (struct sockaddr *)&sender->addr,
     87 		       sizeof (struct sockaddr_in));
     88 
     89   if (octets_sent != pkt_len) {
     90 #if PRINT_DEBUG
     91     fprintf(stderr, "error: couldn't send message %s", (char *)msg);
     92     perror("");
     93 #endif
     94   }
     95 
     96   return octets_sent;
     97 }
     98 
     99 int
    100 rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) {
    101   int octets_recvd;
    102   err_status_t stat;
    103 
    104   octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message,
    105 			 *len, 0, (struct sockaddr *) NULL, 0);
    106 
    107   if (octets_recvd == -1) {
    108     *len = 0;
    109     return -1;
    110   }
    111 
    112   /* verify rtp header */
    113   if (receiver->message.header.version != 2) {
    114     *len = 0;
    115     return -1;
    116   }
    117 
    118 #if PRINT_DEBUG
    119   fprintf(stderr, "%d octets received from SSRC %u\n",
    120 	  octets_recvd, receiver->message.header.ssrc);
    121 #endif
    122 #if VERBOSE_DEBUG
    123   srtp_print_packet(&receiver->message.header, octets_recvd);
    124 #endif
    125 
    126   /* apply srtp */
    127   stat = srtp_unprotect(receiver->srtp_ctx,
    128 			&receiver->message.header, &octets_recvd);
    129   if (stat) {
    130     fprintf(stderr,
    131 	    "error: srtp unprotection failed with code %d%s\n", stat,
    132 	    stat == err_status_replay_fail ? " (replay check failed)" :
    133 	    stat == err_status_auth_fail ? " (auth check failed)" : "");
    134     return -1;
    135   }
    136   strncpy(msg, receiver->message.body, octets_recvd);
    137 
    138   return octets_recvd;
    139 }
    140 
    141 int
    142 rtp_sender_init(rtp_sender_t sender,
    143 		int sock,
    144 		struct sockaddr_in addr,
    145 		unsigned int ssrc) {
    146 
    147   /* set header values */
    148   sender->message.header.ssrc    = htonl(ssrc);
    149   sender->message.header.ts      = 0;
    150   sender->message.header.seq     = (uint16_t) rand();
    151   sender->message.header.m       = 0;
    152   sender->message.header.pt      = 0x1;
    153   sender->message.header.version = 2;
    154   sender->message.header.p       = 0;
    155   sender->message.header.x       = 0;
    156   sender->message.header.cc      = 0;
    157 
    158   /* set other stuff */
    159   sender->socket = sock;
    160   sender->addr = addr;
    161 
    162   return 0;
    163 }
    164 
    165 int
    166 rtp_receiver_init(rtp_receiver_t rcvr,
    167 		  int sock,
    168 		  struct sockaddr_in addr,
    169 		  unsigned int ssrc) {
    170 
    171   /* set header values */
    172   rcvr->message.header.ssrc    = htonl(ssrc);
    173   rcvr->message.header.ts      = 0;
    174   rcvr->message.header.seq     = 0;
    175   rcvr->message.header.m       = 0;
    176   rcvr->message.header.pt      = 0x1;
    177   rcvr->message.header.version = 2;
    178   rcvr->message.header.p       = 0;
    179   rcvr->message.header.x       = 0;
    180   rcvr->message.header.cc      = 0;
    181 
    182   /* set other stuff */
    183   rcvr->socket = sock;
    184   rcvr->addr = addr;
    185 
    186   return 0;
    187 }
    188 
    189 int
    190 rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy) {
    191   return srtp_create(&sender->srtp_ctx, policy);
    192 }
    193 
    194 int
    195 rtp_sender_deinit_srtp(rtp_sender_t sender) {
    196   return srtp_dealloc(sender->srtp_ctx);
    197 }
    198 
    199 int
    200 rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy) {
    201   return srtp_create(&sender->srtp_ctx, policy);
    202 }
    203 
    204 int
    205 rtp_receiver_deinit_srtp(rtp_receiver_t sender) {
    206   return srtp_dealloc(sender->srtp_ctx);
    207 }
    208 
    209 rtp_sender_t
    210 rtp_sender_alloc(void) {
    211   return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
    212 }
    213 
    214 void
    215 rtp_sender_dealloc(rtp_sender_t rtp_ctx) {
    216   free(rtp_ctx);
    217 }
    218 
    219 rtp_receiver_t
    220 rtp_receiver_alloc(void) {
    221   return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
    222 }
    223 
    224 void
    225 rtp_receiver_dealloc(rtp_receiver_t rtp_ctx) {
    226   return free(rtp_ctx);
    227 }
    228