⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtpdump.c

📁 RTP 实现的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    printf("flags=0x%x type=0x%x confid=%u\n",      v->flags, v->type, v->confid);   }  else if (r->common.version == RTP_VERSION) {    printf("\n");    while (len > 0) {      len -= (ntohs(r->common.length) + 1) << 2;      if (len < 0) {        /* something wrong with packet format */        printf("Illegal RTCP packet length %d words.\n",	       ntohs(r->common.length));        return -1;      }      switch (r->common.pt) {      case RTCP_SR:        printf(" (SR ssrc=0x%lx p=%d count=%d len=%d\n",           ntohl(r->r.rr.ssrc), r->common.p, r->common.count,	       ntohs(r->common.length));        printf("ntp=%lu.%lu ts=%lu psent=%lu osent=%lu\n",          ntohl(r->r.sr.ntp_sec),          ntohl(r->r.sr.ntp_frac),          ntohl(r->r.sr.rtp_ts),          ntohl(r->r.sr.psent),        ntohl(r->r.sr.osent));        for (i = 0; i < r->common.count; i++) {          printf("  (ssrc=%0lx fraction=%g lost=%lu last_seq=%lu jit=%lu lsr=%lu dlsr=%lu)\n",           ntohl(r->r.sr.rr[i].ssrc),           r->r.sr.rr[i].fraction / 256.,           ntohl(r->r.sr.rr[i].lost), /* XXX I'm pretty sure this is wrong */           ntohl(r->r.sr.rr[i].last_seq),           ntohl(r->r.sr.rr[i].jitter),           ntohl(r->r.sr.rr[i].lsr),           ntohl(r->r.sr.rr[i].dlsr));        }        printf(" )\n");         break;      case RTCP_RR:        printf(" (RR ssrc=0x%lx p=%d count=%d len=%d\n",           ntohl(r->r.rr.ssrc), r->common.p, r->common.count,	       ntohs(r->common.length));        for (i = 0; i < r->common.count; i++) {          printf("(ssrc=%0lx fraction=%g lost=%lu last_seq=%lu jit=%lu lsr=%lu dlsr=%lu)\n",           ntohl(r->r.rr.rr[i].ssrc),           r->r.rr.rr[i].fraction / 256.,           ntohl(r->r.rr.rr[i].lost),           ntohl(r->r.rr.rr[i].last_seq),           ntohl(r->r.rr.rr[i].jitter),           ntohl(r->r.rr.rr[i].lsr),           ntohl(r->r.rr.rr[i].dlsr));        }        printf(" )\n");         break;      case RTCP_SDES:        printf(" (SDES p=%d count=%d len=%d\n",           r->common.p, r->common.count, ntohs(r->common.length));        buf = (char *)&r->r.sdes;        for (i = 0; i < r->common.count; i++) {          int remaining = (ntohs(r->common.length) << 2) -	    (buf - (char *)&r->r.sdes);          printf("  (src=0x%lx ", ntohl(((struct rtcp_sdes *)buf)->src));          if (remaining > 0) {            buf = rtp_read_sdes(buf,               (ntohs(r->common.length) << 2) - (buf - (char *)&r->r.sdes));            if (!buf) return -1;          }          else {            fprintf(stderr, "Missing at least %d bytes.\n", -remaining);            return -1;          }          printf(")\n");         }        printf(" )\n");         break;      case RTCP_BYE:        printf(" (BYE p=%d count=%d len=%d\n",           r->common.p, r->common.count, ntohs(r->common.length));        for (i = 0; i < r->common.count; i++) {          printf("ssrc[%d]=%0lx ", i, ntohl(r->r.bye.src[i]));        }        if (ntohs(r->common.length) > r->common.count) {          buf = (char *)&r->r.bye.src[r->common.count];          printf("reason=\"%*.*s\"", *buf, *buf, buf+1);         }        printf(")\n");        break;      /* invalid type */      default:        printf("(? pt=%d src=0x%lx)\n", r->common.pt, ntohl(r->r.sdes.src));      break;      }      r = (rtcp_t *)((u_int32 *)r + ntohs(r->common.length) + 1);    }  }  else {    printf("invalid version %d\n", r->common.version);  }  return len;} /* parse_control *//** Process one packet.*/void packet_handler(t_format format, int trunc, double dstart, struct  timeval now, int ctrl, struct sockaddr_in sin, int len, RD_buffer_t  packet){  double dnow = tdbl(&now);  int hlen;   /* header length */  switch(format) {    case F_header:      packet.p.hdr.offset = htonl((dnow - dstart)*1000);      packet.p.hdr.plen   = ctrl ? 0 : len;      /* leave only header */      if (ctrl == 0) len = parse_header(packet.p.data);      packet.p.hdr.length = htons(len + sizeof(packet.p.hdr));      if (fwrite((char *)&packet, len + sizeof(packet.p.hdr), 1, stdout) == 0) {        perror("fwrite");        exit(1);      }      break;    case F_dump:      hlen = ctrl ? len : parse_header(packet.p.data);      packet.p.hdr.offset = htonl((dnow - dstart)*1000);      packet.p.hdr.plen   = ctrl ? 0 : len;      /* truncation of payload */      if (!ctrl && (len - hlen > trunc)) len = hlen + trunc;      packet.p.hdr.length = htons(len + sizeof(packet.p.hdr));      if (fwrite((char *)&packet, len + sizeof(packet.p.hdr), 1, stdout) == 0) {        perror("fwrite");        exit(1);      }      break;    case F_payload:      /* XXX should check header format. */      if (ctrl == 0) {        if (fwrite(&packet.p.data[12], len - 12, 1, stdout) == 0) {          perror("fwrite");          exit(1);        }      }      break;    case F_short:      if (ctrl == 0) parse_short(now, packet.p.data, len);      break;    case F_rtcp:    case F_hex:      case F_ascii:        printf("%8ld.%06ld %s len=%d from=%s:%u ",            now.tv_sec, now.tv_usec, parse_type(ctrl, packet.p.data),            len, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));        if (format == F_hex) {          hex(packet.p.data, trunc < len ? trunc : len);        }        ctrl ? parse_control(packet.p.data, len) :               parse_data(packet.p.data, len);        break;     case F_invalid:        break;  }} /* packet_handler */int main(int argc, char *argv[]){  int c;  static struct {    char *name;    t_format format;  } formats[] = {    {"dump",    F_dump},    {"header",  F_header},    {"hex",     F_hex},    {"rtcp",    F_rtcp},    {"short",   F_short},    {"payload", F_payload},    {"ascii",   F_ascii},    {0,0}   };  t_format format = F_ascii;  struct sockaddr_in sin;  struct timeval start;  struct timeval timeout;   /* timeout to limit recording */  double dstart;            /* time as double */  int duration = 1000000;   /* maximum duration in seconds */  int trunc    = 1000000;   /* bytes to show for F_hex and F_dump */  enum {FromFile, FromNetwork} source;  int sock[2];  FILE *in = stdin;         /* input file to use instead of sockets */  fd_set readfds;  extern char *optarg;  extern int optind;  int i;  int nfds = 0;  extern double tdbl(struct timeval *);  while ((c = getopt(argc, argv, "b:F:f:t:x:")) != EOF) {    switch(c) {    /* output format */    case 'F':      format = F_invalid;      for (i = 0; formats[i].name; i++) {        if (strncasecmp(formats[i].name, optarg, strlen(optarg)) == 0) {          format = formats[i].format;          break;        }      }      if (format == F_invalid) {        usage(argv[1]);        exit(1);      }      break;    /* input file (instead of network connection) */    case 'f':      if (!(in = fopen(optarg, "r"))) {        perror(optarg);        exit(1);      }      break;    /* recording duration in minutes or fractions thereof */    case 't':      duration = atof(optarg) * 60;      break;    /* bytes to show for F_hex or F_dump */    case 'x':      trunc = atoi(optarg);      break;    case '?':    case 'h':      usage(argv[0]);      exit(1);      break;    }  }  /*   * Set up payload type map. We should be able to read this in   * from a file.   */  for (i = 0; i < 256; i++) {    pt_map[i].enc  = "????";    pt_map[i].rate = 0;    pt_map[i].ch   = 0;  }  /* Updated 25 Jul 1997 to reflect IANA assignments: */  /* <ftp://ftp.isi.edu/in-notes/iana/assignments/rtp-av-payload-types> */  /* Marked items are indicated as 'reserved' by the IANA */  pt_map[  0].enc = "PCMU"; pt_map[  0].rate =  8000; pt_map[  0].ch = 1;  pt_map[  1].enc = "1016"; pt_map[  1].rate =  8000; pt_map[  1].ch = 1;  pt_map[  2].enc = "G721"; pt_map[  2].rate =  8000; pt_map[  2].ch = 1;  pt_map[  3].enc = "GSM "; pt_map[  3].rate =  8000; pt_map[  3].ch = 1;  pt_map[  4].enc = "G723"; pt_map[  4].rate =  8000; pt_map[  4].ch = 1;  pt_map[  5].enc = "DVI4"; pt_map[  5].rate =  8000; pt_map[  5].ch = 1;  pt_map[  6].enc = "DVI4"; pt_map[  6].rate = 16000; pt_map[  6].ch = 1;  pt_map[  7].enc = "LPC "; pt_map[  7].rate =  8000; pt_map[  7].ch = 1;  pt_map[  8].enc = "PCMA"; pt_map[  8].rate =  8000; pt_map[  7].ch = 1;  pt_map[  9].enc = "G722"; pt_map[  9].rate =  8000; pt_map[  7].ch = 1;  pt_map[ 10].enc = "L16 "; pt_map[ 10].rate = 44100; pt_map[ 10].ch = 2;  pt_map[ 11].enc = "L16 "; pt_map[ 11].rate = 44100; pt_map[ 11].ch = 1;  pt_map[ 14].enc = "MPA "; pt_map[ 14].rate = 90000; pt_map[ 14].ch = 0;  pt_map[ 15].enc = "G728"; pt_map[ 15].rate =  8000; pt_map[ 15].ch = 1;  pt_map[ 16].enc = "DVI4"; pt_map[ 16].rate = 11025; pt_map[ 16].ch = 1;  pt_map[ 17].enc = "DVI4"; pt_map[ 17].rate = 22050; pt_map[ 17].ch = 1;  pt_map[ 23].enc = "SCR "; pt_map[ 23].rate = 90000; pt_map[ 23].ch = 0; /**/  pt_map[ 24].enc = "MPEG"; pt_map[ 24].rate = 90000; pt_map[ 24].ch = 0; /**/  pt_map[ 25].enc = "CelB"; pt_map[ 25].rate = 90000; pt_map[ 26].ch = 0;  pt_map[ 26].enc = "JPEG"; pt_map[ 26].rate = 90000; pt_map[ 26].ch = 0;  pt_map[ 27].enc = "CUSM"; pt_map[ 27].rate = 90000; pt_map[ 27].ch = 0; /**/  pt_map[ 28].enc = "nv  "; pt_map[ 28].rate = 90000; pt_map[ 28].ch = 0;  pt_map[ 29].enc = "PicW"; pt_map[ 29].rate = 90000; pt_map[ 29].ch = 0; /**/  pt_map[ 30].enc = "CPV "; pt_map[ 30].rate = 90000; pt_map[ 30].ch = 0; /**/  pt_map[ 31].enc = "H261"; pt_map[ 31].rate = 90000; pt_map[ 31].ch = 0;  pt_map[ 32].enc = "MPV "; pt_map[ 32].rate = 90000; pt_map[ 32].ch = 0;  pt_map[ 33].enc = "MP2T"; pt_map[ 33].rate = 90000; pt_map[ 33].ch = 0;  /* set maximum time to gather packets */  timeout.tv_usec = 0;  timeout.tv_sec  = duration;  /* if no optional arguments, we are reading from a file */  if (optind == argc) {    source = FromFile;    sock[0] = fileno(in);  /* stdin */    sock[1] = -1;          /* not used */    RD_header(in, &sin, 0);    dstart = 0.;  }  else {    source = FromNetwork;    nfds = open_network(argv[optind], format != F_rtcp, sock, &sin);    gettimeofday(&start, 0);    dstart = tdbl(&start);  }  /* write header for dump file */  if (format == F_dump || format == F_header)    rtpdump_header(stdout, &sin, &start);  /* signal handler */  signal(SIGINT, done);  /* main loop */  while (1) {    int len;    RD_buffer_t packet;    struct timeval now;    double dnow;    if (source == FromNetwork) {      FD_ZERO(&readfds);      if (sock[0] >= 0) FD_SET(sock[0], &readfds);      if (sock[1] >= 0) FD_SET(sock[1], &readfds);      c = select(nfds+1, &readfds, 0, 0, &timeout);      if (c < 0) {        perror("select");        exit(1);      }      /* end of recording time reached */      else if (c == 0) {        if (verbose)          fprintf(stderr, "Time limit reached.\n");        exit(0);      }      for (i = 0; i < 2; i++) {        if (sock[i] >= 0 && FD_ISSET(sock[i], &readfds)) {          int alen = sizeof(sin);          /* subtract elapsed time from remaining timeout */          gettimeofday(&now, 0);          dnow = tdbl(&now);          timeout.tv_sec = duration - (dnow - dstart);          if (timeout.tv_sec < 0) timeout.tv_sec = 0;          len = recvfrom(sock[i], packet.p.data, sizeof(packet.p.data),             0, (struct sockaddr *)&sin, &alen);          packet_handler(format, trunc, dstart, now, i, sin, len, packet);        }      }    }    else {      len = RD_read(in, &packet);      now.tv_sec = packet.p.hdr.offset / 1000.;      now.tv_usec = (packet.p.hdr.offset % 1000) * 1000;      dnow = tdbl(&now);      /* plen>0: data =0: control */      i = (packet.p.hdr.plen == 0);      /* arbitrary, obviously invalid value */      sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = 0;      packet_handler(format, trunc, dstart, now, i, sin, len, packet);    }  }  return 0;} /* main */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -