00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include "rtcp.h"
00029 #include "version.h"
00030
00031 #ifndef WIN32
00032 # include <pwd.h>
00033 #endif
00034
00042 static int rtcp_set_ssrc_sdes(rtp_ssrc * stm_src, rtcp_sdes_item_t * item)
00043 {
00044 char *str = ((char **) (&(stm_src->ssrc_sdes)))[item->type];
00045
00046 if (str != NULL) {
00047 if (memcmp(str, item->data, item->len) != 0) {
00048 free(str);
00049 if ((str =
00050 (((char **) (&(stm_src->ssrc_sdes)))[item->
00051 type]) =
00052 (char *) malloc(item->len + 1)) == NULL)
00053 return nms_printf(NMSML_FATAL,
00054 "Cannot allocate memory!\n");
00055
00056 memcpy(str, item->data, item->len);
00057 str[item->len] = 0;
00058 }
00059
00060 } else {
00061 if ((str = ((char **) (&(stm_src->ssrc_sdes)))[item->type] =
00062 (char *) malloc(item->len + 1)) == NULL)
00063 return nms_printf(NMSML_FATAL,
00064 "Cannot allocate memory!\n");
00065
00066 memcpy(str, item->data, item->len);
00067 str[item->len] = 0;
00068 }
00069 return 0;
00070 }
00071
00078 int rtcp_parse_sdes(rtp_ssrc * stm_src, rtcp_pkt * pkt)
00079 {
00080 int8_t count = pkt->common.count;
00081 rtcp_sdes_t *sdes = &(pkt->r.sdes);
00082 rtcp_sdes_item_t *rsp, *rspn;
00083 rtcp_sdes_item_t *end =
00084 (rtcp_sdes_item_t *) ((uint32_t *) pkt + pkt->common.len + 1);
00085
00086 nms_printf(NMSML_DBG3, "Received SDES from SSRC: %u\n",
00087 pkt->r.sdes.src);
00088 while (--count >= 0) {
00089 rsp = &(sdes->item[0]);
00090 if (rsp >= end)
00091 break;
00092 for (; rsp->type; rsp = rspn) {
00093 rspn =
00094 (rtcp_sdes_item_t *) ((uint8_t *) rsp + rsp->len +
00095 2);
00096 if (rspn >= end) {
00097 rsp = rspn;
00098 break;
00099 }
00100 if (rtcp_set_ssrc_sdes(stm_src, rsp))
00101 return 1;
00102 }
00103 sdes =
00104 (rtcp_sdes_t *) ((uint32_t *) sdes +
00105 (((uint8_t *) rsp - (uint8_t *) sdes) >> 2) +
00106 1);
00107 }
00108 if (count >= 0)
00109 nms_printf(NMSML_WARN, "Invalid RTCP SDES pkt format!\n");
00110 else if (stm_src->ssrc_stats.probation)
00111 stm_src->ssrc_stats.probation = 1;
00112 return 0;
00113 }
00114
00115
00123 int rtcp_build_sdes(rtp_session * rtp_sess, rtcp_pkt * pkt, int left)
00124 {
00125 #ifndef WIN32
00126 struct passwd *pwitem = getpwuid(getuid());
00127 char * user = pwitem->pw_name;
00128 char * real_name = pwitem->pw_gecos;
00129 #else
00130 char * user = "guest";
00131 char * real_name = "";
00132 #endif
00133
00134 rtcp_sdes_item_t *item;
00135 char str[MAX_SDES_LEN] = "";
00136 int len, pad;
00137 char addr[128];
00138
00139 memset(str, 0, MAX_SDES_LEN);
00140
00141
00142
00143 if (nms_addr_ntop(&rtp_sess->transport.RTP.u.udp.dstaddr, addr, sizeof(addr))) {
00144 strcpy(str, user);
00145 strcat(str, "@");
00146 strcat(str, addr);
00147 }
00148 if (((strlen(str) + sizeof(rtcp_sdes_item_t) - 1 +
00149 sizeof(rtcp_common_t) + 1) >> 2) > (unsigned int) left)
00150
00151 return 0;
00152
00153 len =
00154 (strlen(str) + sizeof(rtcp_sdes_item_t) - 1 +
00155 sizeof(rtcp_common_t)) >> 2;
00156 pkt->common.ver = RTP_VERSION;
00157 pkt->common.pad = 0;
00158 pkt->common.count = 1;
00159 pkt->common.pt = RTCP_SDES;
00160 pkt->r.sdes.src = htonl(rtp_sess->local_ssrc);
00161
00162 item = pkt->r.sdes.item;
00163
00164 item->type = RTCP_SDES_CNAME;
00165 item->len = strlen(str);
00166 strcpy((char *) item->data, str);
00167
00168 item = (rtcp_sdes_item_t *) ((char *) item + strlen((char *) item));
00169
00170
00171 if (strlen(strcpy(str, real_name))) {
00172 if (((strlen(str) + sizeof(rtcp_sdes_item_t) - 1 +
00173 sizeof(rtcp_common_t) + 1) >> 2) > (unsigned int) left) {
00174
00175 pad = 4 - len % 4;
00176 len += pad / 4;
00177 while (pad--)
00178 *((char *) item++) = 0;
00179 pkt->common.len = htons(len);
00180 return len;
00181 }
00182
00183 len +=
00184 (strlen(str) + sizeof(rtcp_sdes_item_t) - 1 +
00185 sizeof(rtcp_common_t) + 1) >> 2;
00186
00187 item->type = RTCP_SDES_NAME;
00188 item->len = strlen(str);
00189 strcpy((char *) item->data, str);
00190
00191 item =
00192 (rtcp_sdes_item_t *) ((char *) item +
00193 strlen((char *) item));
00194 }
00195
00196
00197 sprintf(str, "%s - %s", PROG_NAME, PROG_DESCR);
00198 if (((strlen(str) + sizeof(rtcp_sdes_item_t) - 1 +
00199 sizeof(rtcp_common_t)) >> 2) > (unsigned int) left) {
00200
00201 pad = 4 - len % 4;
00202 len += pad / 4;
00203 while (pad--)
00204
00205 *((char *) item++) = 0;
00206 pkt->common.len = htons(len);
00207 return len;
00208 }
00209
00210 len +=
00211 (strlen(str) + sizeof(rtcp_sdes_item_t) - 1 +
00212 sizeof(rtcp_common_t) + 1) >> 2;
00213
00214 item->type = RTCP_SDES_TOOL;
00215 item->len = strlen(str);
00216 strcpy((char *) item->data, str);
00217
00218 item = (rtcp_sdes_item_t *) ((char *) item + strlen((char *) item));
00219
00220 pad = 4 - len % 4;
00221 len += pad / 4;
00222 while (pad--)
00223
00224 *((char *) item++) = 0;
00225 pkt->common.len = htons(len);
00226
00227 return len;
00228 }