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

📄 fakepcap.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
// -*- mode: c++; c-basic-offset: 4 -*-/* * fakepcap.{cc,hh} -- a faked-up pcap-like interface * Eddie Kohler * * Copyright (c) 2001 International Computer Science Institute * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include "fakepcap.hh"#include <clicknet/ip.h>#include <clicknet/ip6.h>#include <clicknet/ether.h>#include <clicknet/fddi.h>#include <clicknet/rfc1483.h>#include <clicknet/wifi.h>#include <clicknet/llc.h>#include <clicknet/ppp.h>#include <click/confparse.hh>CLICK_DECLSstatic const struct dlt_name {    const char* name;    int dlt;} dlt_names[] = {    { "NULL", FAKE_DLT_NULL },    { "IP", FAKE_DLT_RAW },    { "ETHER", FAKE_DLT_EN10MB },    { "FDDI", FAKE_DLT_FDDI },    { "ATM", FAKE_DLT_ATM_RFC1483 },    { "RFC1483", FAKE_DLT_ATM_RFC1483 },    { "ATM_RFC1483", FAKE_DLT_ATM_RFC1483 },    { "802_11", FAKE_DLT_IEEE802_11 },    { "802.11", FAKE_DLT_IEEE802_11 },    { "SLL", FAKE_DLT_LINUX_SLL },    { "AIRONET", FAKE_DLT_AIRONET_HEADER },    { "HDLC", FAKE_DLT_C_HDLC },    { "PPP_HDLC", FAKE_DLT_PPP_HDLC },    { "PPP", FAKE_DLT_PPP },    { "SUNATM", FAKE_DLT_SUNATM },    { "PRISM", FAKE_DLT_PRISM_HEADER }};intfake_pcap_parse_dlt(const String &str){    for (const dlt_name* d = dlt_names; d < dlt_names + (sizeof(dlt_names) / sizeof(dlt_names[0])); d++)	if (str == d->name)	    return d->dlt;    uint32_t dlt;    if (str.length() >= 2 && str[0] == '#' && cp_unsigned(str.substring(1), &dlt) && dlt < 0x7FFFFFFF)	return dlt;    else	return -1;}Stringfake_pcap_unparse_dlt(int dlt){    for (const dlt_name* d = dlt_names; d < dlt_names + (sizeof(dlt_names) / sizeof(dlt_names[0])); d++)	if (dlt == d->dlt)	    return String::stable_string(d->name);    if (dlt < 0)	return String::stable_string("<none>");    return "#" + String(dlt);}// Handling FORCE_IP.boolfake_pcap_dlt_force_ipable(int dlt){    return (dlt == FAKE_DLT_RAW || dlt == FAKE_DLT_HOST_RAW	    || dlt == FAKE_DLT_EN10MB || dlt == FAKE_DLT_SUNATM	    || dlt == FAKE_DLT_FDDI || dlt == FAKE_DLT_ATM_RFC1483	    || dlt == FAKE_DLT_LINUX_SLL || dlt == FAKE_DLT_C_HDLC	    || dlt == FAKE_DLT_IEEE802_11 || dlt == FAKE_DLT_PRISM_HEADER	    || dlt == FAKE_DLT_PPP_HDLC || dlt == FAKE_DLT_PPP	    || dlt == FAKE_DLT_NULL);}intfake_pcap_canonical_dlt(int dlt, bool){    if (dlt == FAKE_DLT_HOST_RAW)	return FAKE_DLT_RAW;    else	return dlt;}#if HAVE_INDIFFERENT_ALIGNMENT#define unaligned_net_short(v) (ntohs(*reinterpret_cast<const uint16_t*>(v)))#define UNALIGNED_NET_SHORT_EQ(x, y) ((x) == htons((y)))#elsestatic inline uint16_tunaligned_net_short(const void *v){    const uint8_t *d = reinterpret_cast<const uint8_t *>(v);    return (d[0] << 8) | d[1];}#define UNALIGNED_NET_SHORT_EQ(x, y) (unaligned_net_short(&(x)) == (y))#endif#define IP_ETHERTYPE(et)	(UNALIGNED_NET_SHORT_EQ((et), ETHERTYPE_IP) || UNALIGNED_NET_SHORT_EQ((et), ETHERTYPE_IP6))// NB: May change 'p', but will never free it.boolfake_pcap_force_ip(Packet *&p, int dlt){    const click_ip* iph = 0;    const uint8_t* data = p->data();    const uint8_t* end_data = p->end_data();        switch (dlt) {      case FAKE_DLT_RAW:      case FAKE_DLT_HOST_RAW: {	  iph = reinterpret_cast<const click_ip*>(data);	  break;      }      ethernet:      case FAKE_DLT_EN10MB: {	  const click_ether* ethh = reinterpret_cast<const click_ether*>(data);	  if (data + sizeof(click_ether) <= end_data) {	      if (IP_ETHERTYPE(ethh->ether_type))		  iph = reinterpret_cast<const click_ip*>(ethh + 1);	      else if (UNALIGNED_NET_SHORT_EQ(ethh->ether_type, ETHERTYPE_8021Q)		       && data + sizeof(click_ether_vlan) <= end_data) {		  // XXX don't handle 802.1Q-in-802.1Q		  const click_ether_vlan* ethvh = reinterpret_cast<const click_ether_vlan*>(ethh);		  if (IP_ETHERTYPE(ethvh->ether_vlan_encap_proto))		      iph = reinterpret_cast<const click_ip*>(ethvh + 1);	      }	  }	  break;      }      fddi:      case FAKE_DLT_FDDI: {	  const click_fddi* fh = reinterpret_cast<const click_fddi*>(data);	  if (data + sizeof(click_fddi_snap) > end_data	      || (fh->fc & FDDI_FC_LLCMASK) != FDDI_FC_LLC_ASYNC)	      break;	  data = reinterpret_cast<const uint8_t*>(fh + 1);	  goto rfc1483;      }      case FAKE_DLT_SUNATM:	data += 4;	goto rfc1483;	      rfc1483:      case FAKE_DLT_ATM_RFC1483: {	  const click_rfc1483* rh = reinterpret_cast<const click_rfc1483*>(data);	  if (data + sizeof(click_rfc1483) <= end_data	      && memcmp(&rh->dsap, RFC1483_SNAP_IP_EXPECTED, RFC1483_SNAP_IP_EXPECTED_LEN) == 0	      && IP_ETHERTYPE(rh->ether_type))	      iph = reinterpret_cast<const click_ip*>(rh + 1);	  else if (data + 4 <= end_data		   && rh->dsap == LLC_IP_LSAP && rh->ssap == LLC_IP_LSAP)	      iph = reinterpret_cast<const click_ip*>(data + 4);	  else if (data + sizeof(click_rfc1483) <= end_data		   && rh->dsap == LLC_SNAP_LSAP && rh->ssap == LLC_SNAP_LSAP) {#define	OUI_ENCAP_ETHER	0x000000	/* encapsulated Ethernet */#define	OUI_CISCO_90	0x0000f8	/* Cisco bridging */#define OUI_RFC2684	0x0080c2	/* RFC 2684 bridged Ethernet */#define PID_RFC2684_ETH_FCS	0x0001	/* Ethernet, with FCS */#define PID_RFC2684_ETH_NOFCS	0x0007	/* Ethernet, without FCS */#define PID_RFC2684_FDDI_FCS	0x0004	/* FDDI, with FCS */#define PID_RFC2684_FDDI_NOFCS	0x000a	/* FDDI, without FCS */	      uint32_t orgcode = rh->orgcode[0]<<16 + rh->orgcode[1]<<8 + rh->orgcode[2];	      if (orgcode == OUI_ENCAP_ETHER || orgcode == OUI_CISCO_90) {		  data = reinterpret_cast<const uint8_t*>(&rh->ether_type) - 12;		  goto ethernet;	      } else if (orgcode == OUI_RFC2684) {		  uint32_t ethertype = unaligned_net_short(&rh->ether_type);		  if (ethertype == PID_RFC2684_ETH_FCS || ethertype == PID_RFC2684_ETH_NOFCS) {		      data = reinterpret_cast<const uint8_t*>(rh + 1);		      goto ethernet;		  } else if (ethertype == PID_RFC2684_FDDI_FCS || ethertype == PID_RFC2684_FDDI_NOFCS) {		      data = reinterpret_cast<const uint8_t*>(rh + 1) + 1;		      goto fddi;		  }	      }	  }	  break;      }      case FAKE_DLT_LINUX_SLL: {	  CLICK_SIZE_PACKED_STRUCTURE(	  struct click_linux_sll {,	      uint16_t sll_pkttype;	      uint16_t sll_hatype;	      uint16_t sll_halen;	      uint8_t sll_addr[8];	      uint16_t sll_protocol;	  });	  const click_linux_sll* sllh = reinterpret_cast<const click_linux_sll*>(data);	  if (data + sizeof(click_linux_sll) <= end_data &&	      IP_ETHERTYPE(sllh->sll_protocol))	      iph = reinterpret_cast<const click_ip*>(sllh + 1);	  break;      }      c_hdlc:      case FAKE_DLT_C_HDLC: {	  struct click_pcap_hdlc {	      uint16_t hdlc_address;	      uint16_t hdlc_protocol;	  };	  const click_pcap_hdlc* hdlch = reinterpret_cast<const click_pcap_hdlc*>(data);	  if (data + sizeof(click_pcap_hdlc) <= end_data	      && IP_ETHERTYPE(hdlch->hdlc_protocol))	      iph = reinterpret_cast<const click_ip*>(hdlch + 1);	  break;      }      case FAKE_DLT_PPP_HDLC: {	  if (data + 4 > end_data)	      /* nada */;	  else if (data[0] == PPP_ADDRESS) {	      if (data[2] == 0 && (data[3] == PPP_IP || data[3] == PPP_IPV6))		  iph = reinterpret_cast<const click_ip*>(data + 4);	  } else if (data[0] == 0x0F /* CHDLC_UNICAST */		     || data[0] == 0x8F /* CHDLC_BCAST */)	      goto c_hdlc;	  break;      }      case FAKE_DLT_PPP: {	  if (data + 2 <= end_data && data[0] == PPP_ADDRESS && data[1] == PPP_CONTROL)	      data += 2;	  if (data + 2 > end_data)	      /* nada */;	  else if (data[0] == PPP_IP || data[0] == PPP_IPV6)	      iph = reinterpret_cast<const click_ip*>(data + 1);	  else if (data[0] == 0 && (data[1] == PPP_IP || data[1] == PPP_IPV6))	      iph = reinterpret_cast<const click_ip*>(data + 2);	  break;      }      case FAKE_DLT_PRISM_HEADER:	data += 144;	goto ieee802_11;      ieee802_11:      case FAKE_DLT_IEEE802_11:	if (data + 24 <= end_data	    && (data[0] & WIFI_FC0_TYPE_MASK) == WIFI_FC0_TYPE_DATA) {	    data += ((data[1] & 0x03) == 0x03 ? 30 : 24);	    goto rfc1483;	}	break;      case FAKE_DLT_NULL: {	  if (data + 4 > end_data)	      break;	  int family = data[0] | (data[1] << 8);	  if (family == 0)	      family = (data[2] << 8) | data[3];	  if (family == 2 /* BSD_AF_INET */	      || family == 24 /* BSD_AF_INET6_BSD */	      || family == 28 /* BSD_AF_INET6_FREEBSD */	      || family == 30 /* BSD_AF_INET6_DARWIN */)	      iph = reinterpret_cast<const click_ip*>(data + 4);	  break;      }      default:	break;    }    if (!iph)	return false;#if !HAVE_INDIFFERENT_ALIGNMENT    // Machine may crash if we try to access 'iph'. Align it on a word    // boundary.    uintptr_t header_ptr = reinterpret_cast<uintptr_t>(iph);    if (header_ptr & 3) {	int header_off = header_ptr - reinterpret_cast<uintptr_t>(p->data());	if (Packet *q = p->shift_data(-(header_ptr & 3), false)) {	    p = q;	    iph = reinterpret_cast<const click_ip *>(q->data() + header_off);	} else			// cannot align; return it as a non-IP packet	    return false;    }#endif        if (iph->ip_v == 4) {	if (iph->ip_hl >= 5	    && reinterpret_cast<const uint8_t*>(iph) + (iph->ip_hl << 2) <= end_data) {	    p->set_ip_header(iph, iph->ip_hl << 2);	    p->set_dst_ip_anno(iph->ip_dst);	    return true;	}    } else if (iph->ip_v == 6) {	if (reinterpret_cast<const uint8_t*>(iph) + sizeof(click_ip6) <= end_data) {	    p->set_ip6_header(reinterpret_cast<const click_ip6*>(iph));	    return true;	}    }    return false;}CLICK_ENDDECLSELEMENT_REQUIRES(userlevel|ns)ELEMENT_PROVIDES(FakePcap)

⌨️ 快捷键说明

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