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

📄 _udp.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/if.h>

#include <arpa/nameser.h>
#include <arpa/tftp.h>
#include <rpc/rpc.h>

#include "interfac.h"
#include "a2name.h"
#include "appletal.h"
#include "nfs.h"
#include "smb.h"
#include "bootp.h"
#include "afsops.h"
#include "rxkops.h"
#include "ip.h"
#include "ip6.h"
#include "udp.h"

struct rtcphdr {
       u_short rh_flags;      /* T:2 P:1 CNT:5 PT:8 */
       u_short rh_len;        /* length of message (in bytes) */
       u_int   rh_ssrc;       /* synchronization src id */
     };

typedef struct {
        u_long upper;         /* more significant 32 bits */
        u_long lower;         /* less significant 32 bits */
      } ntp64;

/* 
 * Sender report.
 */
struct rtcp_sr {
       ntp64     sr_ntp;      /* 64-bit ntp timestamp */
       u_int32_t sr_ts;       /* reference media timestamp */
       u_int32_t sr_np;       /* no. packets sent */
       u_int32_t sr_nb;       /* no. bytes sent */
     };

/* 
 * Receiver report.
 * Time stamps are middle 32-bits of ntp timestamp.
 */
struct rtcp_rr {
       u_int32_t rr_srcid;    /* sender being reported */
       u_int32_t rr_nl;       /* no. packets lost */
       u_int32_t rr_ls;       /* extended last seq number received */
       u_int32_t rr_dv;       /* jitter (delay variance) */
       u_int32_t rr_lsr;      /* orig. ts from last rr from this src  */
       u_int32_t rr_dlsr;     /* time from recpt of last rr to xmit time */
     };

/* XXX */
#define RTCP_PT_SR        200
#define RTCP_PT_RR        201
#define RTCP_PT_SDES      202
#define   RTCP_SDES_CNAME 1
#define   RTCP_SDES_NAME  2
#define   RTCP_SDES_EMAIL 3
#define   RTCP_SDES_PHONE 4
#define   RTCP_SDES_LOC   5
#define   RTCP_SDES_TOOL  6
#define   RTCP_SDES_TXT   7
#define RTCP_PT_BYE       203
#define RTCP_PT_APP       204

/* 
 * Announce-listen control packets are sent to the odd port,
 * Reply/repair/data packets are sent to the even port. 
 */
static void wc_print (const u_char *wp, u_int len, const struct udphdr *up)
{
  u_short dport = ntohs (up->uh_dport);

  if (!(dport % 2))
  {
    srm2_print (wp, len);
    return;
  }

#if 0
  {
    char  str[100];
    u_int slen = min (snapend - (u_char*)wp+1, sizeof(str));

    snprintf (str, slen, " %s", wp);
    PRINTF ("%s", str);
  }
#endif
}


static void vat_print (const void *hdr, u_int len, const struct udphdr *up)
{
  /* vat/vt audio */
  u_int ts = *(u_short*)hdr;

  if ((ts & 0xf060) != 0)
  {
    /* probably vt */
    PRINTF (" udp/vt %u %d / %d",
            (u_int) (ntohs (up->uh_ulen) - sizeof(*up)),
            ts & 0x3ff, ts >> 10);
  }
  else
  {
    /* probably vat */
    u_int i0 = ntohl (((u_int*)hdr)[0]);
    u_int i1 = ntohl (((u_int*)hdr)[1]);

    PRINTF (" udp/vat %u c%d %u%s",
            (u_int) (ntohs (up->uh_ulen) - sizeof(*up) - 8),
            i0 & 0xffff,
            i1, i0 & 0x800000 ? "*" : "");
    /* audio format */
    if (i0 & 0x1f0000)
       PRINTF (" f%d", (i0 >> 16) & 0x1f);
    if (i0 & 0x3f000000)
       PRINTF (" s%d", (i0 >> 24) & 0x3f);
  }
}

static void rtp_print (const void *hdr, u_int len, const struct udphdr *up)
{
  /* rtp v1 or v2 */
  u_int hasopt, hasext, contype, hasmarker;
  u_int *ip  = (u_int*)hdr;
  u_int i0   = ntohl (((u_int*)hdr)[0]);
  u_int i1   = ntohl (((u_int*)hdr)[1]);
  u_int dlen = ntohs (up->uh_ulen) - sizeof(*up) - 8;
  const char *ptype;

  ip   += 2;
  len >>= 2;
  len  -= 2;
  hasopt = 0;
  hasext = 0;
  if ((i0 >> 30) == 1)
  {
    /* rtp v1 */
    hasopt = i0 & 0x800000;
    contype = (i0 >> 16) & 0x3f;
    hasmarker = i0 & 0x400000;
    ptype = "rtpv1";
  }
  else
  {                                /*XXX */
    /* rtp v2 */
    hasext = i0 & 0x10000000;
    contype = (i0 >> 16) & 0x7f;
    hasmarker = i0 & 0x800000;
    dlen -= 4;
    ptype = "rtp";
    ip += 1;
    len -= 1;
  }
  PRINTF (" udp/%s %d c%d %s%s %d",
          ptype, dlen, contype,
          (hasopt || hasext) ? "+" : "",
          hasmarker          ? "*" : "",
          i0 & 0xffff);
  if (vflag)
  {
    PRINTF (" %u", i1);
    if (hasopt)
    {
      u_int i2, optlen;

      do
      {
        i2 = ip[0];
        optlen = (i2 >> 16) & 0xff;
        if (optlen == 0 || optlen > len)
        {
          PUTS (" !opt");
          return;
        }
        ip  += optlen;
        len -= optlen;
      }
      while ((int) i2 >= 0);
    }
    if (hasext)
    {
      u_int i2, extlen;

      i2 = ip[0];
      extlen = (i2 & 0xffff) + 1;
      if (extlen > len)
      {
        PUTS (" !ext");
        return;
      }
      ip += extlen;
    }
    if (contype == 0x1f)                /* H.261 */
       PRINTF (" 0x%04x", ip[0] >> 16);
  }
}

static const u_char *rtcp_print (const u_char * hdr, u_char *ep)
{
  /* rtp v2 control (rtcp) */
  struct  rtcp_rr *rr = 0;
  struct  rtcp_sr *sr;
  struct  rtcphdr *rh = (struct rtcphdr*)hdr;
  int     cnt, len;
  u_short flags;
  double  ts, dts;

  if ((u_char*)(rh+1) > ep)
  {
    PUTS (" [|rtcp]");
    return (ep);
  }
  len   = (ntohs (rh->rh_len)+1) * 4;
  flags = ntohs (rh->rh_flags);
  cnt   = (flags >> 8) & 0x1f;

  switch (flags & 0xff)
  {
    case RTCP_PT_SR:
         sr = (struct rtcp_sr*)(rh+1);
         PUTS (" sr");
         if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh))
            PRINTF (" [%d]", len);
         if (vflag)
            PRINTF (" %lu", ntohl (rh->rh_ssrc));
         if ((u_char*)(sr+1) > ep)
         {
           PUTS (" [|rtcp]");
           return (ep);
         }
         ts = (double) ((u_int32_t) ntohl (sr->sr_ntp.upper)) +
             ((double) ((u_int32_t) ntohl (sr->sr_ntp.lower)) / 4294967296.0);
         PRINTF (" @%.2f %lu %lup %lub", ts,
                 ntohl (sr->sr_ts), ntohl(sr->sr_np), ntohl(sr->sr_nb));
         rr = (struct rtcp_rr*)(sr+1);
         break;

    case RTCP_PT_RR:
         PUTS (" rr");
         if (len != cnt * sizeof(*rr) + sizeof(*rh))
            PRINTF (" [%d]", len);
         rr = (struct rtcp_rr*)(rh+1);
         if (vflag)
            PRINTF (" %lu", ntohl(rh->rh_ssrc));
         break;

    case RTCP_PT_SDES:
         PRINTF (" sdes %d", len);
         if (vflag)
            PRINTF (" %lu", ntohl (rh->rh_ssrc));
         cnt = 0;
         break;

    case RTCP_PT_BYE:
         PRINTF (" bye %d", len);
         if (vflag)
            PRINTF (" %lu", ntohl (rh->rh_ssrc));
         cnt = 0;
         break;

    default:
         PRINTF (" type-0x%x %d", flags & 0xff, len);
         cnt = 0;
         break;
  }
  if (cnt > 1)
     PRINTF (" c%d", cnt);

  while (--cnt >= 0)
  {
    if ((u_char*)(rr+1) > ep)
    {
      PUTS (" [|rtcp]");
      return (ep);
    }
    if (vflag)
       PRINTF (" %lu", ntohl(rr->rr_srcid));
    ts  = (double) ((u_int32_t) ntohl (rr->rr_lsr)) / 65536.;
    dts = (double) ((u_int32_t) ntohl (rr->rr_dlsr)) / 65536.;
    PRINTF (" %lul %lus %luj @%.2f+%.2f",
            ntohl (rr->rr_nl) & 0x00ffffff,
            ntohl (rr->rr_ls),
            ntohl (rr->rr_dv), ts, dts);
  }
  return (hdr + len);
}

static int udp_cksum (const struct ip *ip, const struct udphdr *up, int len)
{
  int i, tlen;
  union phu {
    struct phdr {
           u_int32_t src;
           u_int32_t dst;
           u_char    mbz;
           u_char    proto;
           u_int16_t len;
         } ph;
    u_int16_t pa[6];
  } phu;
  const u_int16_t *sp;
  u_int32_t        sum;

  tlen = ntohs (ip->ip_len) - ((const char *) up - (const char *) ip);

  /* pseudo-header.. */
  phu.ph.len = htons (tlen);
  phu.ph.mbz = 0;
  phu.ph.proto = IPPROTO_UDP;
  memcpy (&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
  memcpy (&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));

  sp = &phu.pa[0];
  sum = sp[0] + sp[1] + sp[2] + sp[3] + sp[4] + sp[5];

  sp = (const u_int16_t*) up;

  for (i = 0; i < (tlen & ~1); i += 2)
    sum += *sp++;

  if (tlen & 1)
     sum += htons ((*(const u_int8_t*)sp) << 8);

  while (sum > 0xffff)
    sum = (sum & 0xffff) + (sum >> 16);
  sum = ~sum & 0xffff;

  return (sum);
}

#ifdef USE_INET6
static int udp6_cksum (const struct ip6_hdr *ip6, const struct udphdr *up, int len)
{
  int i, tlen;
  const u_int16_t *sp;
  u_int32_t sum;
  union {
    struct {
      struct in6_addr ph_src;
      struct in6_addr ph_dst;
      u_int32_t       ph_len;
      u_int8_t        ph_zero[3];
      u_int8_t        ph_nxt;
    } ph;
    u_int16_t pa[20];
  } phu;

  tlen = ntohs (ip6->ip6_plen) + sizeof(struct ip6_hdr) -
         ((const char *) up - (const char *) ip6);

  /* pseudo-header */
  memset (&phu, 0, sizeof(phu));
  phu.ph.ph_src = ip6->ip6_src;
  phu.ph.ph_dst = ip6->ip6_dst;
  phu.ph.ph_len = htonl (tlen);

⌨️ 快捷键说明

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