00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include <errno.h>
00029 #include "rtcp.h"
00030
00037 static int rtcp_hdr_val_chk(rtcp_pkt * pkt, int len)
00038 {
00039 rtcp_pkt *end;
00040
00041 if (len < (int) sizeof(rtcp_common_t)) {
00042 nms_printf(NMSML_ERR, "RTCP packet too small!!! (%d)\n", len);
00043 return 1;
00044 }
00045
00046 if (len / 4 > (ntohs((pkt->common).len) + 1)) {
00047
00048 nms_printf(NMSML_DBG2,
00049 "RTCP Compound packet arrived (total len=%d)\n",
00050 len);
00051 if ((*(uint16_t *) pkt & RTCP_VALID_MASK) != RTCP_VALID_VALUE) {
00052 nms_printf(NMSML_WARN,
00053 "RTCP Header not valid: first pkt of Compound is not a SR (or RR)!\n"
00054 BLANK_LINE);
00055 return 1;
00056 }
00057 end = (rtcp_pkt *) ((uint32_t *) pkt + len / 4);
00058 do
00059 pkt =
00060 (rtcp_pkt *) ((uint32_t *) pkt +
00061 ntohs((pkt->common).len) + 1);
00062 while ((pkt < end) && ((pkt->common).ver == 2));
00063
00064 if (pkt != end) {
00065 nms_printf(NMSML_WARN,
00066 "RTCP Header not valid: mismatching lenght (%d)!\n"
00067 BLANK_LINE, len);
00068 return 1;
00069 }
00070 } else {
00071 nms_printf(NMSML_DBG2, "RTCP packet arrived (total len=%d)\n",
00072 len);
00073 if ((pkt->common).ver != RTP_VERSION) {
00074 nms_printf(NMSML_WARN,
00075 "RTCP Header not valid: mismatching RTP version number!\n"
00076 BLANK_LINE);
00077 return 1;
00078 }
00079 if (!(((pkt->common).pt >= 200) && ((pkt->common).pt <= 204))) {
00080 nms_printf(NMSML_WARN,
00081 "RTCP Header not valid: mismatching payload type!\n"
00082 BLANK_LINE);
00083 return 1;
00084 }
00085 if (((pkt->common).pad)
00086 && (*(((uint8_t *) pkt) + len - 1) > (pkt->common).len * 4)) {
00087 nms_printf(NMSML_WARN,
00088 "RTCP Header not valid: mismatching lenght!\n"
00089 BLANK_LINE);
00090 return 1;
00091 }
00092 }
00093
00094 return 0;
00095 }
00096
00102 int rtcp_recv(rtp_session * rtp_sess)
00103 {
00104 uint8_t buffer[1024];
00105 rtp_ssrc *stm_src;
00106
00107 struct sockaddr_storage serveraddr;
00108 nms_sockaddr server =
00109 { (struct sockaddr *) &serveraddr, sizeof(serveraddr) };
00110
00111 rtcp_pkt *pkt;
00112 int ret, n;
00113
00114 memset(buffer, 0, 1024);
00115
00116 if ((n =
00117 recvfrom(rtp_sess->transport.RTCP.sock.fd, buffer, 1024, 0, server.addr,
00118 &server.addr_len)) == -1) {
00119 switch (errno) {
00120 case EBADF:
00121 nms_printf(NMSML_ERR,
00122 "RTCP recvfrom: invalid descriptor\n");
00123 break;
00124 #ifndef WIN32
00125 case ENOTSOCK:
00126 nms_printf(NMSML_ERR, "RTCP recvfrom: not a socket\n");
00127 break;
00128 #endif
00129 case EINTR:
00130 nms_printf(NMSML_ERR,
00131 "RTCP recvfrom: The receive was interrupted by delivery of a signal\n");
00132 break;
00133 case EFAULT:
00134 nms_printf(NMSML_ERR,
00135 "RTCP recvfrom: The buffer points outside userspace\n");
00136 break;
00137 case EINVAL:
00138 nms_printf(NMSML_ERR,
00139 "RTCP recvfrom: Invalid argument passed.\n");
00140 break;
00141 default:
00142 nms_printf(NMSML_ERR, "in RTCP recvfrom\n");
00143 break;
00144 }
00145 return 1;
00146 }
00147
00148 pkt = (rtcp_pkt *) buffer;
00149
00150 if (rtcp_hdr_val_chk(pkt, n)) {
00151 nms_printf(NMSML_WARN,
00152 "RTCP Header Validity Check failed!" BLANK_LINE);
00153 return 1;
00154 }
00155
00156 switch (rtp_ssrc_check
00157 (rtp_sess, ntohl((pkt->r).sr.ssrc), &stm_src, &server, RTCP)) {
00158 case SSRC_NEW:
00159 if (pkt->common.pt == RTCP_SR)
00160 rtp_sess->sess_stats.senders++;
00161 rtp_sess->sess_stats.members++;
00162 case SSRC_RTCPNEW:
00163 break;
00164 case -1:
00165 return 1;
00166 break;
00167 default:
00168 break;
00169 }
00170
00171 if ((ret = rtcp_parse_pkt(stm_src, pkt, n)) != 0)
00172 return ret;
00173 else
00174 rtp_sess->sess_stats.avg_rtcp_size =
00175 n / 16. + rtp_sess->sess_stats.avg_rtcp_size * 15. / 16.;
00176
00177 return 0;
00178 }
00179
00187 int rtcp_parse_pkt(rtp_ssrc * stm_src, rtcp_pkt * pkt, int len)
00188 {
00189 rtcp_pkt *end;
00190 end = (rtcp_pkt *) ((uint32_t *) pkt + len / 4);
00191
00192 while (pkt < end) {
00193 switch ((pkt->common).pt) {
00194 case RTCP_SR:
00195 rtcp_parse_sr(stm_src, pkt);
00196 break;
00197 case RTCP_SDES:
00198 if (rtcp_parse_sdes(stm_src, pkt))
00199 return -1;
00200 break;
00201 case RTCP_RR:
00202 rtcp_parse_rr(pkt);
00203 break;
00204 case RTCP_BYE:
00205 rtcp_parse_bye(stm_src, pkt);
00206 break;
00207 case RTCP_APP:
00208 rtcp_parse_app(pkt);
00209 break;
00210 default:
00211 nms_printf(NMSML_WARN, "Received unknown RTCP pkt\n");
00212 return 1;
00213 }
00214 pkt =
00215 (rtcp_pkt *) ((uint32_t *) pkt + ntohs((pkt->common).len) +
00216 1);
00217 }
00218 return 0;
00219 }