gem5  v21.1.0.2
inet.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2002-2005 The Regents of The University of Michigan
15  * Copyright (c) 2010 Advanced Micro Devices, Inc.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #include "base/inet.hh"
43 
44 #include <cstddef>
45 #include <cstdio>
46 #include <sstream>
47 #include <string>
48 
49 #include "base/cprintf.hh"
50 #include "base/logging.hh"
51 #include "base/types.hh"
52 
53 namespace gem5
54 {
55 
56 GEM5_DEPRECATED_NAMESPACE(Net, networking);
57 namespace networking
58 {
59 
61 {
62  std::memset(data, 0, ETH_ADDR_LEN);
63 }
64 
65 EthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN])
66 {
67  for (int i = 0; i < ETH_ADDR_LEN; ++i)
68  data[i] = ea[i];
69 }
70 
71 EthAddr::EthAddr(const eth_addr &ea)
72 {
73  for (int i = 0; i < ETH_ADDR_LEN; ++i)
74  data[i] = ea.data[i];
75 }
76 
77 EthAddr::EthAddr(const std::string &addr)
78 {
79  parse(addr);
80 }
81 
82 const EthAddr &
83 EthAddr::operator=(const eth_addr &ea)
84 {
85  *data = *ea.data;
86  return *this;
87 }
88 
89 const EthAddr &
90 EthAddr::operator=(const std::string &addr)
91 {
92  parse(addr);
93  return *this;
94 }
95 
96 void
97 EthAddr::parse(const std::string &addr)
98 {
99  // the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise
100  // the sscanf function won't work.
101  int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1];
102  if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1],
103  &bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) {
104  std::memset(data, 0xff, ETH_ADDR_LEN);
105  return;
106  }
107 
108  for (int i = 0; i < ETH_ADDR_LEN; ++i) {
109  if (bytes[i] & ~0xff) {
110  std::memset(data, 0xff, ETH_ADDR_LEN);
111  return;
112  }
113 
114  data[i] = bytes[i];
115  }
116 }
117 
118 std::string
120 {
121  std::stringstream stream;
122  stream << *this;
123  return stream.str();
124 }
125 
126 bool
127 operator==(const EthAddr &left, const EthAddr &right)
128 {
129  return !std::memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN);
130 }
131 
132  std::ostream &
133 operator<<(std::ostream &stream, const EthAddr &ea)
134 {
135  const uint8_t *a = ea.addr();
136  ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]);
137  return stream;
138 }
139 
140 std::string
142 {
143  std::stringstream stream;
144  stream << *this;
145  return stream.str();
146 }
147 
148 bool
149 operator==(const IpAddress &left, const IpAddress &right)
150 {
151  return left.ip() == right.ip();
152 }
153 
154 std::ostream &
155 operator<<(std::ostream &stream, const IpAddress &ia)
156 {
157  uint32_t ip = ia.ip();
158  ccprintf(stream, "%x.%x.%x.%x",
159  (uint8_t)(ip >> 24), (uint8_t)(ip >> 16),
160  (uint8_t)(ip >> 8), (uint8_t)(ip >> 0));
161  return stream;
162 }
163 
164 std::string
166 {
167  std::stringstream stream;
168  stream << *this;
169  return stream.str();
170 }
171 
172 bool
173 operator==(const IpNetmask &left, const IpNetmask &right)
174 {
175  return (left.ip() == right.ip()) &&
176  (left.netmask() == right.netmask());
177 }
178 
179 std::ostream &
180 operator<<(std::ostream &stream, const IpNetmask &in)
181 {
182  ccprintf(stream, "%s/%d", (const IpAddress &)in, in.netmask());
183  return stream;
184 }
185 
186 std::string
188 {
189  std::stringstream stream;
190  stream << *this;
191  return stream.str();
192 }
193 
194 bool
195 operator==(const IpWithPort &left, const IpWithPort &right)
196 {
197  return (left.ip() == right.ip()) && (left.port() == right.port());
198 }
199 
200 std::ostream &
201 operator<<(std::ostream &stream, const IpWithPort &iwp)
202 {
203  ccprintf(stream, "%s:%d", (const IpAddress &)iwp, iwp.port());
204  return stream;
205 }
206 
207 uint16_t
208 cksum(const IpPtr &ptr)
209 {
210  int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0);
211  return ip_cksum_carry(sum);
212 }
213 
214 uint16_t
216 {
217  int tcplen = ip->len() - ip->hlen();
218  int sum = ip_cksum_add(ip->payload(), tcplen, 0);
219  sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination
220  sum += htons(ip->ip_p + tcplen);
221  return ip_cksum_carry(sum);
222 }
223 
224 uint16_t
226 {
227  int tcplen = ip6->plen() - ip6->extensionLength();
228  int sum = ip_cksum_add(ip6->payload(), tcplen, 0);
229  sum = ip_cksum_add(ip6->src(), 32, sum);
230  sum += htons(ip6->proto() + tcplen);
231  return ip_cksum_carry(sum);
232 }
233 
234 uint16_t
235 cksum(const TcpPtr &tcp)
236 {
237  if (IpPtr(tcp.packet())) {
238  return __tu_cksum(IpPtr(tcp.packet()));
239  } else if (Ip6Ptr(tcp.packet())) {
240  return __tu_cksum6(Ip6Ptr(tcp.packet()));
241  } else {
242  panic("Unrecognized IP packet format");
243  }
244  // Should never reach here
245  return 0;
246 }
247 
248 uint16_t
249 cksum(const UdpPtr &udp)
250 {
251  if (IpPtr(udp.packet())) {
252  return __tu_cksum(IpPtr(udp.packet()));
253  } else if (Ip6Ptr(udp.packet())) {
254  return __tu_cksum6(Ip6Ptr(udp.packet()));
255  } else {
256  panic("Unrecognized IP packet format");
257  }
258  return 0;
259 }
260 
261 bool
263 {
264  vec.clear();
265 
266  const uint8_t *data = bytes() + sizeof(struct ip_hdr);
267  int all = hlen() - sizeof(struct ip_hdr);
268  while (all > 0) {
269  const IpOpt *opt = (const IpOpt *)data;
270  int len = opt->len();
271  if (all < len)
272  return false;
273 
274  vec.push_back(opt);
275  all -= len;
276  data += len;
277  }
278 
279  return true;
280 }
281 
282 namespace
283 {
284 
285 bool
286 ip6Extension(uint8_t nxt)
287 {
288  return nxt == IP_PROTO_HOPOPTS || nxt == IP_PROTO_ROUTING ||
289  nxt == IP_PROTO_FRAGMENT || nxt == IP_PROTO_AH ||
290  nxt == IP_PROTO_ESP || nxt == IP_PROTO_DSTOPTS;
291 }
292 
293 } // anonymous namespace
294 
295 /* Scan the IP6 header for all header extensions
296  * and return the number of headers found
297  */
298 int
300 {
301  const uint8_t *data = bytes() + IP6_HDR_LEN;
302  uint8_t nxt = ip6_nxt;
303  int len = 0;
304  int all = plen();
305 
306  while (ip6Extension(nxt)) {
307  const Ip6Opt *ext = (const Ip6Opt *)data;
308  nxt = ext->nxt();
309  len += ext->len();
310  data += ext->len();
311  all -= ext->len();
312  assert(all >= 0);
313  }
314  return len;
315 }
316 
317 /* Scan the IP6 header for a particular extension
318  * header type and return a pointer to it if it
319  * exists, otherwise return NULL
320  */
321 const Ip6Opt*
322 Ip6Hdr::getExt(uint8_t ext_type) const
323 {
324  const uint8_t *data = bytes() + IP6_HDR_LEN;
325  uint8_t nxt = ip6_nxt;
326  Ip6Opt* opt = NULL;
327  int all = plen();
328 
329  while (ip6Extension(nxt)) {
330  opt = (Ip6Opt *)data;
331  if (nxt == ext_type) {
332  break;
333  }
334  nxt = opt->nxt();
335  data += opt->len();
336  all -= opt->len();
337  opt = NULL;
338  assert(all >= 0);
339  }
340  return (const Ip6Opt*)opt;
341 }
342 
343 /* Scan the IP6 header and any extension headers
344  * to find what type of Layer 4 header exists
345  * after this header
346  */
347 uint8_t
349 {
350  const uint8_t *data = bytes() + IP6_HDR_LEN;
351  uint8_t nxt = ip6_nxt;
352  int all = plen();
353 
354  while (ip6Extension(nxt)) {
355  const Ip6Opt *ext = (const Ip6Opt *)data;
356  nxt = ext->nxt();
357  data += ext->len();
358  all -= ext->len();
359  assert(all >= 0);
360  }
361  return nxt;
362 }
363 
364 bool
366 {
367  vec.clear();
368 
369  const uint8_t *data = bytes() + sizeof(struct tcp_hdr);
370  int all = off() - sizeof(struct tcp_hdr);
371  while (all > 0) {
372  const TcpOpt *opt = (const TcpOpt *)data;
373  int len = opt->len();
374  if (all < len)
375  return false;
376 
377  vec.push_back(opt);
378  all -= len;
379  data += len;
380  }
381 
382  return true;
383 }
384 
385 int
386 hsplit(const EthPacketPtr &ptr)
387 {
388  int split_point = 0;
389 
390  IpPtr ip(ptr);
391  Ip6Ptr ip6(ptr);
392  if (ip) {
393  split_point = ip.pstart();
394 
395  TcpPtr tcp(ip);
396  if (tcp)
397  split_point = tcp.pstart();
398 
399  UdpPtr udp(ip);
400  if (udp)
401  split_point = udp.pstart();
402  } else if (ip6) {
403  split_point = ip6.pstart();
404 
405  TcpPtr tcp(ip6);
406  if (tcp)
407  split_point = tcp.pstart();
408  UdpPtr udp(ip6);
409  if (udp)
410  split_point = udp.pstart();
411  }
412  return split_point;
413 }
414 
415 } // namespace networking
416 } // namespace gem5
gem5::networking::IpHdr::bytes
const uint8_t * bytes() const
Definition: inet.hh:351
gem5::MipsISA::ip6
Bitfield< 14 > ip6
Definition: pra_constants.hh:190
gem5::networking::IpAddress
Definition: inet.hh:237
gem5::ArmISA::len
Bitfield< 18, 16 > len
Definition: misc_types.hh:444
gem5::networking::TcpOpt
Definition: inet.hh:715
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::networking::Ip6Hdr::extensionLength
int extensionLength() const
Definition: inet.cc:299
gem5::networking::EthAddr::string
std::string string() const
Definition: inet.cc:119
gem5::networking::operator<<
std::ostream & operator<<(std::ostream &stream, const EthAddr &ea)
Definition: inet.cc:133
gem5::networking::IpHdr::len
uint16_t len() const
Definition: inet.hh:334
gem5::networking::cksum
uint16_t cksum(const IpPtr &ptr)
Definition: inet.cc:208
gem5::networking::Ip6Hdr::proto
uint8_t proto() const
Definition: inet.cc:348
gem5::networking::Ip6Hdr::getExt
const Ip6Opt * getExt(uint8_t ext) const
Definition: inet.cc:322
gem5::networking::hsplit
int hsplit(const EthPacketPtr &ptr)
Definition: inet.cc:386
gem5::networking::Ip6Ptr
Definition: inet.hh:487
gem5::networking::IpHdr::options
bool options(std::vector< const IpOpt * > &vec) const
Definition: inet.cc:262
gem5::networking::UdpPtr::packet
const EthPacketPtr packet() const
Definition: inet.hh:813
gem5::ArmISA::a
Bitfield< 8 > a
Definition: misc_types.hh:65
gem5::networking::IpNetmask
Definition: inet.hh:272
gem5::networking::IpWithPort
Definition: inet.hh:300
std::vector
STL vector class.
Definition: stl.hh:37
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::networking::operator==
bool operator==(const EthAddr &left, const EthAddr &right)
Definition: inet.cc:127
gem5::networking::TcpOpt::len
uint8_t len() const
Definition: inet.hh:718
gem5::ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
gem5::MipsISA::ia
Bitfield< 18, 16 > ia
Definition: pra_constants.hh:237
gem5::networking::EthAddr::parse
void parse(const std::string &addr)
Definition: inet.cc:97
gem5::networking::TcpHdr::options
bool options(std::vector< const TcpOpt * > &vec) const
Definition: inet.cc:365
gem5::networking::IpOpt
Definition: inet.hh:428
gem5::networking::UdpPtr::pstart
int pstart() const
Definition: inet.hh:818
gem5::networking::IpNetmask::netmask
uint8_t netmask() const
Definition: inet.hh:287
gem5::networking::IpNetmask::string
std::string string() const
Definition: inet.cc:165
gem5::EthPacketPtr
std::shared_ptr< EthPacketData > EthPacketPtr
Definition: etherpkt.hh:90
gem5::networking::EthAddr::EthAddr
EthAddr()
Definition: inet.cc:60
gem5::networking::IpOpt::len
uint8_t len() const
Definition: inet.hh:434
gem5::networking::__tu_cksum6
uint16_t __tu_cksum6(const Ip6Ptr &ip6)
Definition: inet.cc:225
gem5::networking::IpPtr
Definition: inet.hh:357
gem5::networking::Ip6Hdr::bytes
const uint8_t * bytes() const
Definition: inet.hh:479
gem5::networking::EthAddr
Definition: inet.hh:78
gem5::networking::EthAddr::operator=
const EthAddr & operator=(const eth_addr &ea)
Definition: inet.cc:83
cprintf.hh
gem5::ArmISA::ext
Bitfield< 12 > ext
Definition: misc_types.hh:427
gem5::igbreg::txd_op::ip
bool ip(TxDesc *d)
Definition: i8254xGBe_defs.hh:277
gem5::GEM5_DEPRECATED_NAMESPACE
GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi)
gem5::networking::IpWithPort::string
std::string string() const
Definition: inet.cc:187
gem5::networking::TcpHdr::off
uint8_t off() const
Definition: inet.hh:627
gem5::networking::Ip6Opt::nxt
uint8_t nxt() const
Definition: inet.hh:594
gem5::networking::EthAddr::bytes
const uint8_t * bytes() const
Definition: inet.hh:106
types.hh
gem5::PowerISA::vec
Bitfield< 25 > vec
Definition: misc.hh:108
gem5::networking::__tu_cksum
uint16_t __tu_cksum(const IpPtr &ip)
Definition: inet.cc:215
gem5::networking::Ip6Opt::len
uint8_t len() const
Definition: inet.hh:596
logging.hh
gem5::networking::IpAddress::string
std::string string() const
Definition: inet.cc:141
gem5::networking::IpHdr::hlen
uint8_t hlen() const
Definition: inet.hh:332
gem5::RiscvISA::sum
Bitfield< 18 > sum
Definition: misc.hh:545
gem5::networking::TcpHdr::bytes
const uint8_t * bytes() const
Definition: inet.hh:640
gem5::ArmISA::ea
Bitfield< 3 > ea
Definition: misc_types.hh:328
gem5::networking::EthAddr::addr
const uint8_t * addr() const
Definition: inet.hh:114
gem5::networking::IpWithPort::port
uint8_t port() const
Definition: inet.hh:315
inet.hh
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::networking::Ip6Hdr::plen
uint16_t plen() const
Definition: inet.hh:461
gem5::networking::UdpPtr
Definition: inet.hh:760
gem5::networking::Ip6Hdr::nxt
uint8_t nxt() const
Definition: inet.hh:463
gem5::igbreg::txd_op::tcp
bool tcp(TxDesc *d)
Definition: i8254xGBe_defs.hh:278
gem5::networking::TcpPtr
Definition: inet.hh:646
gem5::networking::IpAddress::ip
uint32_t ip() const
Definition: inet.hh:256
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::networking::Ip6Opt
Definition: inet.hh:592

Generated on Tue Sep 21 2021 12:24:57 for gem5 by doxygen 1.8.17