gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  * Authors: Nathan Binkert
42  * Gabe Black
43  * Geoffrey Blake
44  */
45 
46 #include "base/inet.hh"
47 
48 #include <cstddef>
49 #include <cstdio>
50 #include <sstream>
51 #include <string>
52 
53 #include "base/cprintf.hh"
54 #include "base/types.hh"
55 
56 using namespace std;
57 namespace Net {
58 
59 EthAddr::EthAddr()
60 {
61  memset(data, 0, ETH_ADDR_LEN);
62 }
63 
64 EthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN])
65 {
66  for (int i = 0; i < ETH_ADDR_LEN; ++i)
67  data[i] = ea[i];
68 }
69 
70 EthAddr::EthAddr(const eth_addr &ea)
71 {
72  for (int i = 0; i < ETH_ADDR_LEN; ++i)
73  data[i] = ea.data[i];
74 }
75 
76 EthAddr::EthAddr(const std::string &addr)
77 {
78  parse(addr);
79 }
80 
81 const EthAddr &
82 EthAddr::operator=(const eth_addr &ea)
83 {
84  *data = *ea.data;
85  return *this;
86 }
87 
88 const EthAddr &
89 EthAddr::operator=(const std::string &addr)
90 {
91  parse(addr);
92  return *this;
93 }
94 
95 void
96 EthAddr::parse(const std::string &addr)
97 {
98  // the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise
99  // the sscanf function won't work.
100  int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1];
101  if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1],
102  &bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) {
103  memset(data, 0xff, ETH_ADDR_LEN);
104  return;
105  }
106 
107  for (int i = 0; i < ETH_ADDR_LEN; ++i) {
108  if (bytes[i] & ~0xff) {
109  memset(data, 0xff, ETH_ADDR_LEN);
110  return;
111  }
112 
113  data[i] = bytes[i];
114  }
115 }
116 
117 string
118 EthAddr::string() const
119 {
120  stringstream stream;
121  stream << *this;
122  return stream.str();
123 }
124 
125 bool
126 operator==(const EthAddr &left, const EthAddr &right)
127 {
128  return !memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN);
129 }
130 
131 ostream &
132 operator<<(ostream &stream, const EthAddr &ea)
133 {
134  const uint8_t *a = ea.addr();
135  ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]);
136  return stream;
137 }
138 
139 string
140 IpAddress::string() const
141 {
142  stringstream stream;
143  stream << *this;
144  return stream.str();
145 }
146 
147 bool
148 operator==(const IpAddress &left, const IpAddress &right)
149 {
150  return left.ip() == right.ip();
151 }
152 
153 ostream &
154 operator<<(ostream &stream, const IpAddress &ia)
155 {
156  uint32_t ip = ia.ip();
157  ccprintf(stream, "%x.%x.%x.%x",
158  (uint8_t)(ip >> 24), (uint8_t)(ip >> 16),
159  (uint8_t)(ip >> 8), (uint8_t)(ip >> 0));
160  return stream;
161 }
162 
163 string
164 IpNetmask::string() const
165 {
166  stringstream stream;
167  stream << *this;
168  return stream.str();
169 }
170 
171 bool
172 operator==(const IpNetmask &left, const IpNetmask &right)
173 {
174  return (left.ip() == right.ip()) &&
175  (left.netmask() == right.netmask());
176 }
177 
178 ostream &
179 operator<<(ostream &stream, const IpNetmask &in)
180 {
181  ccprintf(stream, "%s/%d", (const IpAddress &)in, in.netmask());
182  return stream;
183 }
184 
185 string
186 IpWithPort::string() const
187 {
188  stringstream stream;
189  stream << *this;
190  return stream.str();
191 }
192 
193 bool
194 operator==(const IpWithPort &left, const IpWithPort &right)
195 {
196  return (left.ip() == right.ip()) && (left.port() == right.port());
197 }
198 
199 ostream &
200 operator<<(ostream &stream, const IpWithPort &iwp)
201 {
202  ccprintf(stream, "%s:%d", (const IpAddress &)iwp, iwp.port());
203  return stream;
204 }
205 
206 uint16_t
207 cksum(const IpPtr &ptr)
208 {
209  int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0);
210  return ip_cksum_carry(sum);
211 }
212 
213 uint16_t
215 {
216  int tcplen = ip->len() - ip->hlen();
217  int sum = ip_cksum_add(ip->payload(), tcplen, 0);
218  sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination
219  sum += htons(ip->ip_p + tcplen);
220  return ip_cksum_carry(sum);
221 }
222 
223 uint16_t
225 {
226  int tcplen = ip6->plen() - ip6->extensionLength();
227  int sum = ip_cksum_add(ip6->payload(), tcplen, 0);
228  sum = ip_cksum_add(ip6->src(), 32, sum);
229  sum += htons(ip6->proto() + tcplen);
230  return ip_cksum_carry(sum);
231 }
232 
233 uint16_t
234 cksum(const TcpPtr &tcp)
235 {
236  if (IpPtr(tcp.packet())) {
237  return __tu_cksum(IpPtr(tcp.packet()));
238  } else if (Ip6Ptr(tcp.packet())) {
239  return __tu_cksum6(Ip6Ptr(tcp.packet()));
240  } else {
241  assert(0);
242  }
243  // Should never reach here
244  return 0;
245 }
246 
247 uint16_t
248 cksum(const UdpPtr &udp)
249 {
250  if (IpPtr(udp.packet())) {
251  return __tu_cksum(IpPtr(udp.packet()));
252  } else if (Ip6Ptr(udp.packet())) {
253  return __tu_cksum6(Ip6Ptr(udp.packet()));
254  } else {
255  assert(0);
256  }
257  return 0;
258 }
259 
260 bool
261 IpHdr::options(vector<const IpOpt *> &vec) const
262 {
263  vec.clear();
264 
265  const uint8_t *data = bytes() + sizeof(struct ip_hdr);
266  int all = hlen() - sizeof(struct ip_hdr);
267  while (all > 0) {
268  const IpOpt *opt = (const IpOpt *)data;
269  int len = opt->len();
270  if (all < len)
271  return false;
272 
273  vec.push_back(opt);
274  all -= len;
275  data += len;
276  }
277 
278  return true;
279 }
280 
281 #define IP6_EXTENSION(nxt) (nxt == IP_PROTO_HOPOPTS) ? true : \
282  (nxt == IP_PROTO_ROUTING) ? true : \
283  (nxt == IP_PROTO_FRAGMENT) ? true : \
284  (nxt == IP_PROTO_AH) ? true : \
285  (nxt == IP_PROTO_ESP) ? true: \
286  (nxt == IP_PROTO_DSTOPTS) ? true : false
287 
288 /* Scan the IP6 header for all header extensions
289  * and return the number of headers found
290  */
291 int
292 Ip6Hdr::extensionLength() const
293 {
294  const uint8_t *data = bytes() + IP6_HDR_LEN;
295  uint8_t nxt = ip6_nxt;
296  int len = 0;
297  int all = plen();
298 
299  while (IP6_EXTENSION(nxt)) {
300  const Ip6Opt *ext = (const Ip6Opt *)data;
301  nxt = ext->nxt();
302  len += ext->len();
303  data += ext->len();
304  all -= ext->len();
305  assert(all >= 0);
306  }
307  return len;
308 }
309 
310 /* Scan the IP6 header for a particular extension
311  * header type and return a pointer to it if it
312  * exists, otherwise return NULL
313  */
314 const Ip6Opt*
315 Ip6Hdr::getExt(uint8_t ext_type) const
316 {
317  const uint8_t *data = bytes() + IP6_HDR_LEN;
318  uint8_t nxt = ip6_nxt;
319  Ip6Opt* opt = NULL;
320  int all = plen();
321 
322  while (IP6_EXTENSION(nxt)) {
323  opt = (Ip6Opt *)data;
324  if (nxt == ext_type) {
325  break;
326  }
327  nxt = opt->nxt();
328  data += opt->len();
329  all -= opt->len();
330  opt = NULL;
331  assert(all >= 0);
332  }
333  return (const Ip6Opt*)opt;
334 }
335 
336 /* Scan the IP6 header and any extension headers
337  * to find what type of Layer 4 header exists
338  * after this header
339  */
340 uint8_t
341 Ip6Hdr::proto() const
342 {
343  const uint8_t *data = bytes() + IP6_HDR_LEN;
344  uint8_t nxt = ip6_nxt;
345  int all = plen();
346 
347  while (IP6_EXTENSION(nxt)) {
348  const Ip6Opt *ext = (const Ip6Opt *)data;
349  nxt = ext->nxt();
350  data += ext->len();
351  all -= ext->len();
352  assert(all >= 0);
353  }
354  return nxt;
355 }
356 
357 bool
358 TcpHdr::options(vector<const TcpOpt *> &vec) const
359 {
360  vec.clear();
361 
362  const uint8_t *data = bytes() + sizeof(struct tcp_hdr);
363  int all = off() - sizeof(struct tcp_hdr);
364  while (all > 0) {
365  const TcpOpt *opt = (const TcpOpt *)data;
366  int len = opt->len();
367  if (all < len)
368  return false;
369 
370  vec.push_back(opt);
371  all -= len;
372  data += len;
373  }
374 
375  return true;
376 }
377 
378 int
379 hsplit(const EthPacketPtr &ptr)
380 {
381  int split_point = 0;
382 
383  IpPtr ip(ptr);
384  Ip6Ptr ip6(ptr);
385  if (ip) {
386  split_point = ip.pstart();
387 
388  TcpPtr tcp(ip);
389  if (tcp)
390  split_point = tcp.pstart();
391 
392  UdpPtr udp(ip);
393  if (udp)
394  split_point = udp.pstart();
395  } else if (ip6) {
396  split_point = ip6.pstart();
397 
398  TcpPtr tcp(ip6);
399  if (tcp)
400  split_point = tcp.pstart();
401  UdpPtr udp(ip6);
402  if (udp)
403  split_point = udp.pstart();
404  }
405  return split_point;
406 }
407 
408 
409 } // namespace Net
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
uint8_t proto() const
Definition: inet.cc:341
Bitfield< 7 > i
Definition: miscregs.hh:1378
uint32_t ip() const
Definition: inet.hh:204
uint16_t plen() const
Definition: inet.hh:368
const uint8_t * payload() const
Definition: inet.hh:387
int hsplit(const EthPacketPtr &ptr)
Definition: inet.cc:379
Bitfield< 8 > a
Definition: miscregs.hh:1377
const EthPacketPtr packet() const
Definition: inet.hh:671
ip6_addr_t addr
Definition: inet.hh:335
int pstart() const
Definition: inet.hh:445
const EthPacketPtr packet() const
Definition: inet.hh:576
Bitfield< 12 > ext
Definition: miscregs.hh:1609
STL vector class.
Definition: stl.hh:40
uint16_t cksum(const UdpPtr &udp)
Definition: inet.cc:248
uint8_t len() const
Definition: inet.hh:485
const char data[]
Definition: circlebuf.cc:43
const uint8_t * bytes() const
Definition: inet.hh:92
int pstart() const
Definition: inet.hh:329
uint8_t netmask() const
Definition: inet.hh:224
const uint8_t * addr() const
Definition: inet.hh:95
bool tcp(TxDesc *d)
ostream & operator<<(ostream &stream, const IpWithPort &iwp)
Definition: inet.cc:200
uint16_t len() const
Definition: inet.hh:258
uint8_t hlen() const
Definition: inet.hh:256
std::shared_ptr< EthPacketData > EthPacketPtr
Definition: etherpkt.hh:90
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
const uint8_t * src() const
Definition: inet.hh:373
Bitfield< 18, 16 > ia
Temp sum(Temp val)
Definition: statistics.hh:3224
int extensionLength() const
Definition: inet.cc:292
uint8_t len() const
Definition: inet.hh:340
#define IP6_EXTENSION(nxt)
Definition: inet.cc:281
Bitfield< 18, 16 > len
Definition: miscregs.hh:1626
uint16_t __tu_cksum6(const Ip6Ptr &ip6)
Definition: inet.cc:224
bool operator==(const IpWithPort &left, const IpWithPort &right)
Definition: inet.cc:194
uint8_t nxt() const
Definition: inet.hh:483
int pstart() const
Definition: inet.hh:581
bool ip(TxDesc *d)
const uint8_t * payload() const
Definition: inet.hh:276
uint8_t port() const
Definition: inet.hh:244
Bitfield< 3 > ea
Definition: miscregs.hh:1518
Bitfield< 14 > ip6
uint16_t __tu_cksum(const IpPtr &ip)
Definition: inet.cc:214
uint8_t len() const
Definition: inet.hh:589
const uint8_t * bytes() const
Definition: inet.hh:275
int pstart() const
Definition: inet.hh:676

Generated on Fri Jun 9 2017 13:03:40 for gem5 by doxygen 1.8.6