📄 packet.hh
字号:
// -*- c-basic-offset: 2; related-file-name: "../../lib/packet.cc" -*-#ifndef CLICK_PACKET_HH#define CLICK_PACKET_HH#include <click/ipaddress.hh>#include <click/glue.hh>#include <click/timestamp.hh>#ifdef CLICK_LINUXMODULE# include <click/skbmgr.hh>#endifstruct click_ether;struct click_ip;struct click_icmp;struct click_ip6;struct click_tcp;struct click_udp;#ifdef CLICK_NS# include <click/simclick.h>#endifCLICK_DECLSclass IP6Address;class WritablePacket;class Packet { public: // PACKET CREATION enum { DEFAULT_HEADROOM = 28, MIN_BUFFER_LENGTH = 64 }; static WritablePacket *make(uint32_t); static WritablePacket *make(const char *, uint32_t); static WritablePacket *make(const unsigned char *, uint32_t); static WritablePacket *make(uint32_t, const unsigned char *, uint32_t, uint32_t); #ifdef CLICK_LINUXMODULE // Packet::make(sk_buff *) wraps a Packet around an existing sk_buff. // Packet now owns the sk_buff (ie we don't increment skb->users). static Packet *make(struct sk_buff *); struct sk_buff *skb() { return (struct sk_buff *)this; } const struct sk_buff *skb() const { return (const struct sk_buff*)this; } void kill();#elif CLICK_BSDMODULE // Packet::make(mbuf *) wraps a Packet around an existing mbuf. // Packet now owns the mbuf. static Packet *make(struct mbuf *); struct mbuf *m() { return _m; } const struct mbuf *m() const { return (const struct mbuf *)_m; } struct mbuf *steal_m(); void kill() { if (--_use_count <= 0) delete this; }#else /* User-space */ static WritablePacket *make(unsigned char *, uint32_t, void (*destructor)(unsigned char *, size_t)); void kill() { if (--_use_count <= 0) delete this; }#endif bool shared() const; Packet *clone(); WritablePacket *uniqueify(); #ifdef CLICK_LINUXMODULE /* Linux kernel module */ const unsigned char *data() const { return skb()->data; } const unsigned char *end_data() const { return skb()->tail; } uint32_t length() const { return skb()->len; } uint32_t headroom() const { return skb()->data - skb()->head; } uint32_t tailroom() const { return skb()->end - skb()->tail; } const unsigned char *buffer_data() const { return skb()->head; } uint32_t buffer_length() const { return skb()->end - skb()->head; }#else /* User-level driver and BSD kernel module */ const unsigned char *data() const { return _data; } const unsigned char *end_data() const { return _tail; } uint32_t length() const { return _tail - _data; } uint32_t headroom() const { return _data - _head; } uint32_t tailroom() const { return _end - _tail; } const unsigned char *buffer_data() const { return _head; } uint32_t buffer_length() const { return _end - _head; }#endif WritablePacket *push(uint32_t nb); // Add more space before packet. WritablePacket *push_mac_header(uint32_t nb); Packet *nonunique_push(uint32_t nb); void pull(uint32_t nb); // Get rid of initial bytes. WritablePacket *put(uint32_t nb); // Add bytes to end of pkt. Packet *nonunique_put(uint32_t nb); void take(uint32_t nb); // Delete bytes from end of pkt. Packet *shift_data(int offset, bool free_on_failure = true);#ifdef CLICK_USERLEVEL inline void shrink_data(const unsigned char *, uint32_t length); inline void change_headroom_and_length(uint32_t headroom, uint32_t length);#endif // HEADER ANNOTATIONS#ifdef CLICK_LINUXMODULE /* Linux kernel module */ const unsigned char *mac_header() const { return skb()->mac.raw; } const click_ether *ether_header() const { return (click_ether *)skb()->mac.raw; } const unsigned char *network_header() const { return skb()->nh.raw; } const click_ip *ip_header() const { return (click_ip *)skb()->nh.iph; } const click_ip6 *ip6_header() const { return (click_ip6 *)skb()->nh.ipv6h; } const unsigned char *transport_header() const { return skb()->h.raw; } const click_icmp *icmp_header() const { return (click_icmp*)skb()->h.icmph; } const click_tcp *tcp_header() const { return (click_tcp *)skb()->h.th; } const click_udp *udp_header() const { return (click_udp *)skb()->h.uh; }#else /* User space and BSD kernel module */ const unsigned char *mac_header() const { return _mac.raw; } const click_ether *ether_header() const { return _mac.ethernet; } const unsigned char *network_header() const { return _nh.raw; } const click_ip *ip_header() const { return _nh.iph; } const click_ip6 *ip6_header() const { return _nh.ip6h; } const unsigned char *transport_header() const { return _h.raw; } const click_icmp *icmp_header() const { return _h.icmph; } const click_tcp *tcp_header() const { return _h.th; } const click_udp *udp_header() const { return _h.uh; }#endif void set_mac_header(const unsigned char *); void set_mac_header(const unsigned char *, uint32_t); void set_ether_header(const click_ether *); void set_network_header(const unsigned char *, uint32_t); void set_network_header_length(uint32_t); void set_ip_header(const click_ip *, uint32_t); void set_ip6_header(const click_ip6 *); void set_ip6_header(const click_ip6 *, uint32_t); int mac_header_offset() const; uint32_t mac_header_length() const; int network_header_offset() const; uint32_t network_header_length() const; int ip_header_offset() const; uint32_t ip_header_length() const; int ip6_header_offset() const; uint32_t ip6_header_length() const; int transport_header_offset() const;#ifdef CLICK_LINUXMODULE /* Linux kernel module */ int mac_length() const { return skb()->tail - skb()->mac.raw;} int network_length() const { return skb()->tail - skb()->nh.raw; } int transport_length() const { return skb()->tail - skb()->h.raw; }#else /* User space and BSD kernel module */ int mac_length() const { return _tail - _mac.raw; } int network_length() const { return _tail - _nh.raw; } int transport_length() const { return _tail - _h.raw; }#endif // LINKS#ifdef CLICK_LINUXMODULE /* Linux kernel module */ Packet *next() const { return (Packet *)(skb()->next); } Packet *&next() { return (Packet *&)(skb()->next); } void set_next(Packet *p) { skb()->next = p->skb(); }#else /* User space and BSD kernel module */ Packet *next() const { return _next; } Packet *&next() { return _next; } void set_next(Packet *p) { _next = p; }#endif // ANNOTATIONS private: struct Anno;#ifdef CLICK_LINUXMODULE /* Linux kernel module */ const Anno *anno() const { return (const Anno *)skb()->cb; } Anno *anno() { return (Anno *)skb()->cb; }#else /* User-space and BSD kernel module */ const Anno *anno() const { return (const Anno *)_cb; } Anno *anno() { return (Anno *)_cb; }#endif public: enum PacketType { // must agree with if_packet.h HOST = 0, BROADCAST = 1, MULTICAST = 2, OTHERHOST = 3, OUTGOING = 4, LOOPBACK = 5, FASTROUTE = 6 }; enum { ADDR_ANNO_SIZE = 16 }; uint8_t *addr_anno() { return anno()->addr.c; } const uint8_t *addr_anno() const { return anno()->addr.c; } IPAddress dst_ip_anno() const; void set_dst_ip_anno(IPAddress); const IP6Address &dst_ip6_anno() const; void set_dst_ip6_anno(const IP6Address &);#ifdef CLICK_LINUXMODULE const Timestamp ×tamp_anno() const { return *(const Timestamp*) &skb()->stamp; } Timestamp ×tamp_anno() { return *(Timestamp*) &skb()->stamp; } void set_timestamp_anno(const Timestamp &tv) { memcpy(&skb()->stamp, &tv, 8); } net_device *device_anno() const { return skb()->dev; } void set_device_anno(net_device *dev) { skb()->dev = dev; } PacketType packet_type_anno() const { return (PacketType)(skb()->pkt_type & PACKET_TYPE_MASK); } void set_packet_type_anno(PacketType p) { skb()->pkt_type = (skb()->pkt_type & PACKET_CLEAN) | p; }# ifdef HAVE_INT64_TYPES uint64_t perfctr_anno() const { return anno()->perfctr; } void set_perfctr_anno(uint64_t pc) { anno()->perfctr = pc; }# endif#else /* User-space and BSD kernel module */ const Timestamp ×tamp_anno() const { return _timestamp; } Timestamp ×tamp_anno() { return _timestamp; } void set_timestamp_anno(const Timestamp &tv) { _timestamp = tv; }#ifdef CLICK_NS class SimPacketinfoWrapper { public: simclick_simpacketinfo _pinfo; SimPacketinfoWrapper() { // The uninitialized value for the simulator packet data can't be // all zeros (0 is a valid packet id) or random junk out of memory // since the simulator will look at this info to see if the packet // was originally generated by it. Accidental collisions with other // packet IDs or bogus packet IDs can cause weird things to happen. So we // set it to all -1 here to keep the simulator from getting confused. memset(&_pinfo,-1,sizeof(_pinfo)); } }; simclick_simpacketinfo* get_sim_packetinfo() { return &(_sim_packetinfo._pinfo); } void set_sim_packetinfo(simclick_simpacketinfo* pinfo) { _sim_packetinfo._pinfo = *pinfo; }#endif# ifdef CLICK_BSDMODULE /* BSD kernel module */ net_device *device_anno() const { if (m()) return m()->m_pkthdr.rcvif; else return NULL; } void set_device_anno(net_device *dev) { if (m()) m()->m_pkthdr.rcvif = dev; }# else net_device *device_anno() const { return 0; } void set_device_anno(net_device *) { }# endif PacketType packet_type_anno() const { return _pkt_type; } void set_packet_type_anno(PacketType p) { _pkt_type = p; }#endif enum { USER_ANNO_SIZE = 24, USER_ANNO_US_SIZE = 12, USER_ANNO_S_SIZE = 12, USER_ANNO_U_SIZE = 6, USER_ANNO_I_SIZE = 6 }; uint8_t user_anno_c(int i) const { return anno()->user.c[i]; } void set_user_anno_c(int i, uint8_t v) { anno()->user.c[i] = v; } uint16_t user_anno_us(int i) const { return anno()->user.us[i]; } void set_user_anno_us(int i, uint16_t v) { anno()->user.us[i] = v; } int16_t user_anno_s(int i) const { return anno()->user.us[i]; } void set_user_anno_s(int i, int16_t v) { anno()->user.s[i] = v; } uint32_t user_anno_u(int i) const { return anno()->user.u[i]; } void set_user_anno_u(int i, uint32_t v) { anno()->user.u[i] = v; } int32_t user_anno_i(int i) const { return anno()->user.i[i]; } void set_user_anno_i(int i, int32_t v) { anno()->user.i[i] = v; } const uint8_t *all_user_anno() const { return &anno()->user.c[0]; } uint8_t *all_user_anno() { return &anno()->user.c[0]; } const uint32_t *all_user_anno_u() const { return &anno()->user.u[0]; } uint32_t *all_user_anno_u() { return &anno()->user.u[0]; } void clear_annotations(); void copy_annotations(const Packet *); private: // Anno must fit in sk_buff's char cb[48]. struct Anno { union { uint8_t c[ADDR_ANNO_SIZE]; uint32_t ip4; } addr; union { uint8_t c[USER_ANNO_SIZE]; uint16_t us[USER_ANNO_US_SIZE]; int16_t s[USER_ANNO_S_SIZE]; uint32_t u[USER_ANNO_U_SIZE]; int32_t i[USER_ANNO_I_SIZE]; } user; // flag allocations: see packet_anno.hh #if (defined(CLICK_LINUXMODULE) || defined(CLICK_BSDMODULE)) && defined(HAVE_INT64_TYPES) uint64_t perfctr;#endif };#ifndef CLICK_LINUXMODULE /* * User-space and BSD kernel module implementations. */ int _use_count; Packet *_data_packet; /* mimic Linux sk_buff */ unsigned char *_head; /* start of allocated buffer */ unsigned char *_data; /* where the packet starts */ unsigned char *_tail; /* one beyond end of packet */ unsigned char *_end; /* one beyond end of allocated buffer */#ifdef CLICK_USERLEVEL void (*_destructor)(unsigned char *, size_t);#endif unsigned char _cb[48]; union { unsigned char *raw; click_ether *ethernet; } _mac; union { unsigned char *raw; click_ip *iph; click_ip6 *ip6h; } _nh; union { unsigned char *raw; click_tcp *th; click_udp *uh; click_icmp *icmph; } _h; PacketType _pkt_type; Timestamp _timestamp;#ifdef CLICK_BSDMODULE struct mbuf *_m;#endif Packet *_next;#ifdef CLICK_NS SimPacketinfoWrapper _sim_packetinfo;#endif#endif Packet(); Packet(const Packet &); ~Packet(); Packet &operator=(const Packet &);#ifndef CLICK_LINUXMODULE Packet(int, int, int) { } static WritablePacket *make(int, int, int); bool alloc_data(uint32_t, uint32_t, uint32_t);#endif#ifdef CLICK_BSDMODULE static void assimilate_mbuf(Packet *p); void assimilate_mbuf();#endif inline void shift_header_annotations(int32_t shift); WritablePacket *expensive_uniqueify(int32_t extra_headroom, int32_t extra_tailroom, bool free_on_failure); WritablePacket *expensive_push(uint32_t nbytes); WritablePacket *expensive_put(uint32_t nbytes); friend class WritablePacket;};class WritablePacket : public Packet { public: #ifdef CLICK_LINUXMODULE /* Linux kernel module */ unsigned char *data() const { return skb()->data; } unsigned char *end_data() const { return skb()->tail; } unsigned char *buffer_data() const { return skb()->head; } unsigned char *mac_header() const { return skb()->mac.raw; } click_ether *ether_header() const { return (click_ether*)skb()->mac.raw;} unsigned char *network_header() const { return skb()->nh.raw; } click_ip *ip_header() const { return (click_ip *)skb()->nh.iph; } click_ip6 *ip6_header() const { return (click_ip6*)skb()->nh.ipv6h; } unsigned char *transport_header() const { return skb()->h.raw; } click_icmp *icmp_header() const { return (click_icmp*)skb()->h.icmph; } click_tcp *tcp_header() const { return (click_tcp*)skb()->h.th; } click_udp *udp_header() const { return (click_udp*)skb()->h.uh; }#else /* User-space or BSD kernel module */ unsigned char *data() const { return _data; } unsigned char *end_data() const { return _tail; } unsigned char *buffer_data() const { return _head; } unsigned char *mac_header() const { return _mac.raw; } click_ether *ether_header() const { return _mac.ethernet; } unsigned char *network_header() const { return _nh.raw; } click_ip *ip_header() const { return _nh.iph; } click_ip6 *ip6_header() const { return _nh.ip6h; } unsigned char *transport_header() const { return _h.raw; } click_icmp *icmp_header() const { return _h.icmph; } click_tcp *tcp_header() const { return _h.th; } click_udp *udp_header() const { return _h.uh; }#endif private: WritablePacket() { } WritablePacket(const Packet &) { } ~WritablePacket() { } friend class Packet; };inline WritablePacket *Packet::make(uint32_t len){ return make(DEFAULT_HEADROOM, (const unsigned char *)0, len, 0);}inline WritablePacket *Packet::make(const char *s, uint32_t len){ return make(DEFAULT_HEADROOM, (const unsigned char *)s, len, 0);}inline WritablePacket *Packet::make(const unsigned char *s, uint32_t len){ return make(DEFAULT_HEADROOM, (const unsigned char *)s, len, 0);}#ifdef CLICK_LINUXMODULEinline Packet *Packet::make(struct sk_buff *skb){ if (atomic_read(&skb->users) == 1) { skb_orphan(skb); return reinterpret_cast<Packet *>(skb); } else { Packet *p = reinterpret_cast<Packet *>(skb_clone(skb, GFP_ATOMIC)); atomic_dec(&skb->users); return p; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -