EMANE  1.2.1
netutils.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013,2016 - Adjacent Link LLC, Bridgewater, New Jersey
3  * Copyright (c) 2008-2010 - DRS CenGen, LLC, Columbia, Maryland
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of DRS CenGen, LLC nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef EMANEUTILSNETUTILS_HEADER_
35 #define EMANEUTILSNETUTILS_HEADER_
36 
37 #include <sstream>
38 #include <vector>
39 #include <cstdint>
40 #include <cstring>
41 #include <arpa/inet.h>
42 
43 namespace EMANE
44 {
45  namespace Utils
46  {
54  struct UdpHeader
55  {
56  std::uint16_t u16Udpsrc;
57  std::uint16_t u16Udpdst;
58  std::uint16_t u16Udplen;
59  std::uint16_t u16Udpcheck;
60  } __attribute__((packed));
61 
62 
68  const std::uint8_t IP_PROTO_UDP = 0x11;
69 
75  const std::uint16_t UDP_HEADER_LEN = 8;
76 
77 
84  inline std::uint8_t
85  get_ip_version(std::uint8_t vhl)
86  {
87  return ((vhl >> 4) & 0x0F);
88  }
89 
96  inline std::uint8_t
97  get_ip_hdrlen(std::uint8_t vhl)
98  {
99  return ((vhl & 0x0F) << 2);
100  }
101 
102 
110  inline std::uint8_t
111  get_ip_dscp(std::uint8_t tos)
112  {
113  return (tos >> 2);
114  }
115 
125  inline std::uint8_t
126  get_ip_dscp(std::uint8_t ver, std::uint8_t clas)
127  {
128  return (((ver & 0x0F) << 2) | (clas >> 6));
129  }
139  struct Ip4Header
140  {
141  std::uint8_t u8Ipv4vhl;
142  std::uint8_t u8Ipv4tos;
143  std::uint16_t u16Ipv4len;
144  std::uint16_t u16Ipv4id;
145  std::uint16_t u16Ipv4frag;
146  std::uint8_t u8Ipv4hops;
147  std::uint8_t u8Ipv4proto;
148  std::uint16_t u16Ipv4check;
149  std::uint32_t u32Ipv4src;
150  std::uint32_t u32Ipv4dst;
151  } __attribute__((packed));
152 
158  const std::uint16_t IPV4_HEADER_LEN = 20;
159 
160 
166  const std::uint16_t IPV4_ADDR_LEN = 4;
167 
168 
174  const std::uint16_t IPV6_ADDR_LEN = 16;
175 
181  const std::uint8_t IPV6_P_ICMP = 0x3A;
182 
190  inline std::uint8_t
192  {
193  return get_ip_version(ip->u8Ipv4vhl);
194  }
195 
196 
204  inline std::uint8_t
206  {
207  return get_ip_hdrlen(ip->u8Ipv4vhl);
208  }
209 
210 
218  inline std::uint16_t
219  get_len(const Ip4Header *ip)
220  {
221  return ntohs(ip->u16Ipv4len);
222  }
223 
224 
232  inline std::uint8_t
233  get_dscp(const Ip4Header *ip)
234  {
235  return get_ip_dscp(ip->u8Ipv4tos);
236  }
237 
247  inline void
248  addr_to_string(const std::uint8_t * addr, size_t addrlen, const char *delim, char *buf, size_t buflen)
249  {
250  size_t pos = 0;
252  for(size_t i = 0; i < addrlen; ++i)
253  {
254  if(i < (addrlen - 1))
255  {
256  pos += snprintf(buf + pos, buflen - pos, "%02X%s", addr[i] & 0xFF, delim);
257  }
258  else
259  {
260  pos += snprintf(buf + pos, buflen - pos, "%02X", addr[i] & 0xFF);
261  }
262  }
263  }
264 
265 
273  struct Ip6Header
274  {
275  struct {
276  std::uint8_t u8Ipv6Ver;
277  std::uint8_t u8Ipv6Class;
278  std::uint16_t u16Ipv6Flow;
279  } vcf;
280 
281  std::uint16_t u16Ipv6len;
282  std::uint8_t u8Ipv6next;
283  std::uint8_t u8Ipv6hops;
284  std::uint8_t Ipv6src[IPV6_ADDR_LEN];
285  std::uint8_t Ipv6dst[IPV6_ADDR_LEN];
286  } __attribute__((packed));
287 
293  const std::uint16_t IPV6_HEADER_LEN = 40;
294 
300  const std::uint16_t IPV6_MAX_BIT_LEN = 128;
301 
302 
303 
304  inline std::uint8_t
306  {
307  return get_ip_version(ip->vcf.u8Ipv6Ver);
308  }
309 
310  inline std::uint8_t
312  {
313  return get_ip_hdrlen(ip->vcf.u8Ipv6Ver);
314  }
315 
316  inline std::uint16_t
317  get_len(const Ip6Header *ip)
318  {
319  return (ntohs(ip->u16Ipv6len) + IPV6_HEADER_LEN);
320  }
321 
322  inline std::uint8_t
323  get_dscp(const Ip6Header *ip)
324  {
325  return get_ip_dscp(ip->vcf.u8Ipv6Ver, ip->vcf.u8Ipv6Class);
326  }
327 
328 
329 
335  const std::uint16_t ETH_ALEN = 6;
336 
337 
343  const std::uint16_t ETH_HEADER_LEN = 14;
344 
345 
351  const std::uint16_t ETHARP_HEADER_LEN = 28;
352 
358  const std::uint16_t IP_MAX_PACKET = 0xFFFF;
359 
360 
366  const std::uint16_t ARPHRD_ETHER = 0x0001;
367 
368 
374  const std::uint16_t ETH_P_IPV4 = 0x0800;
375 
376 
382  const std::uint16_t ETH_P_ARP = 0x0806;
383 
389  const std::uint16_t ETH_P_IPV6 = 0x86DD;
399  std::uint8_t buff[ETH_ALEN];
400  } __attribute__((packed));
401 
410  std::uint16_t word1;
411  std::uint16_t word2;
412  std::uint16_t word3;
413  } __attribute__((packed));
414 
422  union EtherAddr {
425  } __attribute__((packed));
426 
434  struct EtherHeader{
435  union EtherAddr dst;
436  union EtherAddr src;
437  std::uint16_t u16proto;
438  } __attribute__((packed));
439 
440 
448  inline const EtherAddr*
450  {
451  return (&eth->src);
452  }
453 
461  inline const EtherAddr*
463  {
464  return (&eth->dst);
465  }
466 
474  inline std::uint16_t
476  {
477  return ntohs(eth->u16proto);
478  }
479 
480 
481 
489  inline const char *
490  addr_to_string(const EtherAddr * addr)
491  {
492  static char buf[64];
493 
494  addr_to_string((std::uint8_t*) addr, ETH_ALEN, ":", buf, sizeof(buf));
495 
496  return buf;
497  }
498 
499 
507  inline std::string
509  {
510  char buf[64];
512  addr_to_string((std::uint8_t*) addr, ETH_ALEN, ":", buf, sizeof(buf));
514  return buf;
515  }
518 
527  {
528  std::uint16_t u16hwType;
529  std::uint16_t u16protocol;
530  std::uint8_t u8hwAddrLen;
531  std::uint8_t u8protoAddrLen;
532  std::uint16_t u16code;
534  std::uint32_t u32srcProtoAddr;
536  std::uint32_t u32dstProtoAddr;
537  } __attribute__((packed));
538 
546  inline std::uint16_t
548  {
549  return ntohs(arp->u16hwType);
550  }
551 
552 
560  inline std::uint16_t
562  {
563  return ntohs(arp->u16protocol);
564  }
565 
566 
574  inline std::uint8_t
576  {
577  return (arp->u8hwAddrLen);
578  }
579 
580 
588  inline std::uint8_t
590  {
591  return (arp->u8protoAddrLen);
592  }
593 
601  inline std::uint16_t
603  {
604  return ntohs(arp->u16code);
605  }
606 
607 
615  inline const EtherAddr*
617  {
618  return (&arp->srcHwAddr);
619  }
620 
621 
629  inline const EtherAddr*
631  {
632  return (&arp->dstHwAddr);
633  }
634 
642  inline std::uint32_t
644  {
645  return (arp->u32srcProtoAddr);
646  }
647 
648 
656  inline std::uint32_t
658  {
659  return (arp->u32dstProtoAddr);
660  }
661 
662 
668  const std::uint16_t ETH_ARPOP_REQUEST = 0x0001;
669 
670 
676  const std::uint16_t ETH_ARPOP_REPLY = 0x0002;
677 
678 
679 
687  inline std::uint16_t
688  ethaddr4_to_id (const EtherAddr *addr)
689  {
690  // multicast mac
691  static std::uint8_t MulticastMacAddr[3] = {0x01, 0x00, 0x5E};
692 
693  // broadcast mac
694  static std::uint8_t BroadcastMacAddr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
695 
696  // multicast
697  if(memcmp(addr->bytes.buff, MulticastMacAddr, 3) == 0)
698  {
699  return ntohs(0xFFFF);
700  }
701  // broadcast
702  else if(memcmp(addr->bytes.buff, BroadcastMacAddr, 6) == 0)
703  {
704  return ntohs(0xFFFF);
705  }
706  // unicast
707  else
708  {
709  return ntohs(addr->words.word3);
710  }
711  }
712 
713 
721  inline std::uint16_t
722  ethaddr6_to_id (const EtherAddr *addr)
723  {
724  // multicast mac
725  static std::uint8_t MulticastMacAddr[2] = {0x33, 0x33};
726 
727  // broadcast mac
728  static std::uint8_t BroadcastMacAddr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
729 
730  // multicast
731  if(memcmp(addr->bytes.buff, MulticastMacAddr, 2) == 0)
732  {
733  return ntohs(0xFFFF);
734  }
735  // broadcast
736  else if(memcmp(addr->bytes.buff, BroadcastMacAddr, 6) == 0)
737  {
738  return ntohs(0xFFFF);
739  }
740  // unicast
741  else
742  {
743  return ntohs(addr->words.word3);
744  }
745  }
746 
754  inline std::uint8_t
755  get_prefixlen (const in6_addr *prefix)
756  {
757  std::uint8_t len = 0;
758  std::uint8_t *u8ptr = (std::uint8_t *) prefix;
759 
760  while ((*u8ptr == 0xff) && len < IPV6_MAX_BIT_LEN)
761  {
762  len += 8;
763  u8ptr++;
764  }
765 
766  if (len < IPV6_MAX_BIT_LEN)
767  {
768  std::uint8_t byte = *u8ptr;
769  while (byte)
770  {
771  len++;
772  byte <<= 1;
773  }
774  }
775 
776  return len;
777  }
778 
779 
791  inline std::uint16_t
792  inet_cksum (const void * buf, int buflen, std::uint16_t prev = 0)
793  {
794  std::uint32_t sum = 0;
795  std::uint16_t *w = (std::uint16_t *) buf;
797  while (buflen > 1) {
798  sum += *w;
799  buflen -= 2;
800  w++;
801  }
802 
803  if (buflen) {
804  std::uint8_t *byte = (std::uint8_t *) w;
805  sum += *byte;
806  }
807 
808  sum += prev;
809  sum = (sum >> 16) + (sum & 0xFFFF);
810  return (sum + (sum >> 16));
811  }
812 
819  struct IP6ICMPHeader {
820  std::uint8_t u8Type;
821  std::uint8_t u8Code;
822  std::uint16_t u16Checksum;
823  std::uint32_t u32Flags;
824  sockaddr_in6 targetAddr;
825  } __attribute__((packed));
826 
832  const std::uint8_t IP6_ICMP_NEIGH_SOLICIT = 135;
833 
839  const std::uint8_t IP6_ICMP_NEIGH_ADVERT = 136;
840 
849  inline std::string formatFrequency(const std::uint64_t val, const int precision = 6)
850  {
851  std::stringstream ss;
852 
853  ss.precision(precision);
854 
855  const float fFrequency = val;
856 
857  if(fFrequency < 1e+3)
858  {
859  ss << fFrequency << " Hz";
860  }
861  else if (fFrequency < 1e+6)
862  {
863  ss << (fFrequency / 1e+3) << " KHz";
864  }
865  else if (fFrequency < 1e+9)
866  {
867  ss << (fFrequency / 1e+6) << " MHz";
868  }
869  else if (fFrequency < 1e+12)
870  {
871  ss << (fFrequency / 1e+9) << " GHz";
872  }
873  else
874  {
875  ss << (fFrequency / 1e+12) << " THz";
876  }
877 
878  return ss.str();
879  }
880 
881  inline std::vector<std::string> getTokens(const std::string & sInput, const char * pzDelimeter)
882  {
883  char *pzToken = NULL;
884 
885  int iTokenCount = 0;
886 
887  std::string str = sInput;
888 
889  std::vector<std::string> strVector;
890 
891  while ((pzToken = strtok (iTokenCount == 0 ? &str[0] : NULL, pzDelimeter)) != NULL)
892  {
893  ++iTokenCount;
894 
895  strVector.push_back(pzToken);
896  }
897 
898  return strVector;
899  }
900  }
901 }
902 
903 #endif // EMANEUTILSNETUTILS_HEADER_
const std::uint16_t ETH_P_ARP
Ethernet arp protocol.
Definition: netutils.h:382
std::uint8_t Ipv6src[IPV6_ADDR_LEN]
Definition: netutils.h:258
const std::uint16_t ETH_P_IPV6
Ethernet ipv6 protocol.
Definition: netutils.h:389
union EtherAddr src
Definition: netutils.h:436
Definition of the IPv4 header.
Definition: netutils.h:139
std::uint32_t get_dstprotoaddr(const EtherArpHeader *arp)
Definition: netutils.h:657
const std::uint16_t IPV6_MAX_BIT_LEN
ipv6 max addr len
Definition: netutils.h:300
struct EMANE::Utils::Ip6Header::@23 vcf
std::uint8_t u8Ipv6hops
Definition: netutils.h:283
struct EtherAddrWords words
Definition: netutils.h:424
const EtherAddr * get_dsthwaddr(const EtherArpHeader *arp)
Definition: netutils.h:630
std::uint16_t u16Ipv4len
Definition: netutils.h:143
struct @24 vcf
std::vector< std::string > getTokens(const std::string &sInput, const char *pzDelimeter)
Definition: netutils.h:881
std::uint16_t get_len(const Ip4Header *ip)
Definition: netutils.h:219
struct EtherAddrBytes bytes
Definition: netutils.h:423
const std::uint16_t IP_MAX_PACKET
Max ip packet len.
Definition: netutils.h:358
std::uint16_t u16Ipv4frag
Definition: netutils.h:145
Definition of the ethernet frame address as an array of 6 bytes.
Definition: netutils.h:398
std::uint16_t get_code(const EtherArpHeader *arp)
Definition: netutils.h:602
struct EtherAddrWords words
Definition: netutils.h:391
const std::uint16_t UDP_HEADER_LEN
udp header len
Definition: netutils.h:75
std::uint16_t u16proto
Definition: netutils.h:437
union EtherAddr dst
Definition: netutils.h:390
std::uint8_t u8Ipv4tos
Definition: netutils.h:142
std::uint16_t get_protocol(const EtherHeader *eth)
Definition: netutils.h:475
std::uint32_t u32Ipv4dst
Definition: netutils.h:150
std::uint8_t get_ip_dscp(std::uint8_t tos)
Definition: netutils.h:111
Definition of the IPv6 ICMP header.
Definition: netutils.h:819
std::string formatFrequency(const std::uint64_t val, const int precision=6)
returns a sting with the formatted value and suffix
Definition: netutils.h:849
std::uint8_t get_hwaddrlen(const EtherArpHeader *arp)
Definition: netutils.h:575
std::uint8_t buff[ETH_ALEN]
Definition: netutils.h:390
std::uint8_t u8Ipv6Class
Definition: netutils.h:277
std::uint16_t get_hwtype(const EtherArpHeader *arp)
Definition: netutils.h:547
std::uint32_t u32Ipv4src
Definition: netutils.h:149
const std::uint16_t ETHARP_HEADER_LEN
Ethernet Arp header length.
Definition: netutils.h:351
struct EtherAddrBytes bytes
Definition: netutils.h:390
std::uint16_t u16Udplen
Definition: netutils.h:58
std::uint16_t u16Udpcheck
Definition: netutils.h:59
std::uint16_t u16Udpsrc
Definition: netutils.h:56
const std::uint16_t IPV4_ADDR_LEN
ipv4 addr len
Definition: netutils.h:166
Definition of the IPv6 header.
Definition: netutils.h:273
std::uint32_t u32srcProtoAddr
Definition: netutils.h:534
std::uint8_t get_hdrlen(const Ip4Header *ip)
Definition: netutils.h:205
std::uint8_t get_ip_version(std::uint8_t vhl)
Definition: netutils.h:85
const EtherAddr * get_dstaddr(const EtherHeader *eth)
Definition: netutils.h:462
std::uint16_t ethaddr4_to_id(const EtherAddr *addr)
Definition: netutils.h:688
const EtherAddr * get_srcaddr(const EtherHeader *eth)
Definition: netutils.h:449
std::uint16_t u16Ipv4check
Definition: netutils.h:148
std::uint32_t get_srcprotoaddr(const EtherArpHeader *arp)
Definition: netutils.h:643
std::uint16_t u16Ipv4id
Definition: netutils.h:144
Definition of the ethernet arp header.
Definition: netutils.h:526
std::uint16_t inet_cksum(const void *buf, int buflen, std::uint16_t prev=0)
Definition: netutils.h:792
const std::uint16_t ETH_ARPOP_REPLY
Ethernet arp reply.
Definition: netutils.h:676
std::uint16_t u16Udpdst
Definition: netutils.h:57
Definition of the ethernet frame address as an array of 6 bytes or set of 3 words.
Definition: netutils.h:422
std::uint8_t u8protoAddrLen
Definition: netutils.h:531
const EtherAddr * get_srchwaddr(const EtherArpHeader *arp)
Definition: netutils.h:616
const std::uint8_t IP6_ICMP_NEIGH_ADVERT
IPv6 ICMP Neighbor Advertisement.
Definition: netutils.h:839
std::uint8_t u8Ipv6next
Definition: netutils.h:282
std::uint8_t get_ip_hdrlen(std::uint8_t vhl)
Definition: netutils.h:97
const std::uint16_t IPV4_HEADER_LEN
ipv4 header len without options
Definition: netutils.h:158
const std::uint8_t IP_PROTO_UDP
ip udp protocol
Definition: netutils.h:68
std::uint16_t ethaddr6_to_id(const EtherAddr *addr)
Definition: netutils.h:722
const std::uint16_t ETH_ARPOP_REQUEST
Ethernet arp request.
Definition: netutils.h:668
Definition of the UDP header.
Definition: netutils.h:54
std::uint8_t u8Ipv6Ver
Definition: netutils.h:276
const std::uint16_t ETH_ALEN
Ethernet hardware address length.
Definition: netutils.h:335
const std::uint16_t IPV6_ADDR_LEN
ipv6 addr len
Definition: netutils.h:174
Definition of the ethernet frame address as a set of 3 words.
Definition: netutils.h:409
void addr_to_string(const std::uint8_t *addr, size_t addrlen, const char *delim, char *buf, size_t buflen)
Definition: netutils.h:248
const std::uint16_t ARPHRD_ETHER
Ethernet hardware type.
Definition: netutils.h:366
std::string ethaddr_to_string(const EtherAddr *addr)
Definition: netutils.h:508
std::uint16_t u16Ipv6len
Definition: netutils.h:281
const std::uint8_t IPV6_P_ICMP
IPv6 ICMP Protocol.
Definition: netutils.h:181
std::uint8_t get_protoaddrlen(const EtherArpHeader *arp)
Definition: netutils.h:589
struct EMANE::Utils::UdpHeader __attribute__((packed))
std::uint8_t get_dscp(const Ip4Header *ip)
Definition: netutils.h:233
union EtherAddr dst
Definition: netutils.h:435
union EtherAddr src
Definition: netutils.h:391
const std::uint16_t ETH_HEADER_LEN
Ethernet header length.
Definition: netutils.h:343
std::uint16_t u16protocol
Definition: netutils.h:529
std::uint8_t Ipv6dst[IPV6_ADDR_LEN]
Definition: netutils.h:259
Definition of the ethernet frame header.
Definition: netutils.h:434
std::uint32_t u32Flags
Definition: netutils.h:823
std::uint8_t u8Ipv4proto
Definition: netutils.h:147
std::uint8_t buff[ETH_ALEN]
Definition: netutils.h:399
std::uint16_t u16Ipv6Flow
Definition: netutils.h:278
const std::uint8_t IP6_ICMP_NEIGH_SOLICIT
IPv6 ICMP Neighbor Soliciation.
Definition: netutils.h:832
std::uint16_t u16Checksum
Definition: netutils.h:822
Definition: agent.h:43
const std::uint16_t ETH_P_IPV4
Ethernet ipv4 protocol.
Definition: netutils.h:374
std::uint8_t u8Ipv4vhl
Definition: netutils.h:141
std::uint32_t u32dstProtoAddr
Definition: netutils.h:536
std::uint8_t u8Ipv4hops
Definition: netutils.h:146
const std::uint16_t IPV6_HEADER_LEN
ipv6 header len
Definition: netutils.h:293
std::uint8_t get_version(const Ip4Header *ip)
Definition: netutils.h:191
std::uint8_t get_prefixlen(const in6_addr *prefix)
Definition: netutils.h:755