inet.cc revision 2665:a124942bacb8
11689SN/A/* 210331Smitch.hayenga@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 39916Ssteve.reinhardt@amd.com * All rights reserved. 48707Sandreas.hansson@arm.com * 58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 148707Sandreas.hansson@arm.com * this software without specific prior written permission. 152325SN/A * 167897Shestness@cs.utexas.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A * 281689SN/A * Authors: Nathan Binkert 291689SN/A */ 301689SN/A 311689SN/A#include <sstream> 321689SN/A#include <string> 331689SN/A 341689SN/A#include "base/cprintf.hh" 351689SN/A#include "sim/host.hh" 361689SN/A#include "base/inet.hh" 371689SN/A 381689SN/Ausing namespace std; 391689SN/Anamespace Net { 401689SN/A 412665Ssaidi@eecs.umich.eduEthAddr::EthAddr() 422665Ssaidi@eecs.umich.edu{ 432756Sksewell@umich.edu memset(data, 0, ETH_ADDR_LEN); 447897Shestness@cs.utexas.edu} 451689SN/A 461689SN/AEthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN]) 478779Sgblack@eecs.umich.edu{ 486658Snate@binkert.org *data = *ea; 498887Sgeoffrey.blake@arm.com} 508887Sgeoffrey.blake@arm.com 518229Snate@binkert.orgEthAddr::EthAddr(const eth_addr &ea) 528229Snate@binkert.org{ 538229Snate@binkert.org *data = *ea.data; 544762Snate@binkert.org} 558779Sgblack@eecs.umich.edu 564762Snate@binkert.orgEthAddr::EthAddr(const std::string &addr) 574762Snate@binkert.org{ 588232Snate@binkert.org parse(addr); 599152Satgutier@umich.edu} 608232Snate@binkert.org 618232Snate@binkert.orgconst EthAddr & 624762Snate@binkert.orgEthAddr::operator=(const eth_addr &ea) 634762Snate@binkert.org{ 648793Sgblack@eecs.umich.edu *data = *ea.data; 658779Sgblack@eecs.umich.edu return *this; 664762Snate@binkert.org} 678460SAli.Saidi@ARM.com 684762Snate@binkert.orgconst EthAddr & 695702Ssaidi@eecs.umich.eduEthAddr::operator=(const std::string &addr) 705702Ssaidi@eecs.umich.edu{ 718232Snate@binkert.org parse(addr); 725702Ssaidi@eecs.umich.edu return *this; 735702Ssaidi@eecs.umich.edu} 748737Skoansin.tan@gmail.com 755529Snate@binkert.orgvoid 762669Sktlim@umich.eduEthAddr::parse(const std::string &addr) 776221Snate@binkert.org{ 781060SN/A // the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise 795529Snate@binkert.org // the sscanf function won't work. 805712Shsul@eecs.umich.edu int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1]; 811060SN/A if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1], 821060SN/A &bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) { 831060SN/A memset(data, 0xff, ETH_ADDR_LEN); 842292SN/A return; 852733Sktlim@umich.edu } 862292SN/A 872292SN/A for (int i = 0; i < ETH_ADDR_LEN; ++i) { 882292SN/A if (bytes[i] & ~0xff) { 892292SN/A memset(data, 0xff, ETH_ADDR_LEN); 908707Sandreas.hansson@arm.com return; 918707Sandreas.hansson@arm.com } 928975Sandreas.hansson@arm.com 938707Sandreas.hansson@arm.com data[i] = bytes[i]; 948707Sandreas.hansson@arm.com } 958948Sandreas.hansson@arm.com} 968948Sandreas.hansson@arm.com 978948Sandreas.hansson@arm.comstring 988707Sandreas.hansson@arm.comEthAddr::string() const 998707Sandreas.hansson@arm.com{ 1008707Sandreas.hansson@arm.com stringstream stream; 1018707Sandreas.hansson@arm.com stream << *this; 1028707Sandreas.hansson@arm.com return stream.str(); 1038707Sandreas.hansson@arm.com} 1048707Sandreas.hansson@arm.com 1058707Sandreas.hansson@arm.combool 1068707Sandreas.hansson@arm.comoperator==(const EthAddr &left, const EthAddr &right) 1078707Sandreas.hansson@arm.com{ 1088707Sandreas.hansson@arm.com return memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN); 1098707Sandreas.hansson@arm.com} 1108707Sandreas.hansson@arm.com 1118975Sandreas.hansson@arm.comostream & 1128707Sandreas.hansson@arm.comoperator<<(ostream &stream, const EthAddr &ea) 1138975Sandreas.hansson@arm.com{ 1148707Sandreas.hansson@arm.com const uint8_t *a = ea.addr(); 1158707Sandreas.hansson@arm.com ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]); 1168707Sandreas.hansson@arm.com return stream; 1178975Sandreas.hansson@arm.com} 1188975Sandreas.hansson@arm.com 1198948Sandreas.hansson@arm.comuint16_t 1208975Sandreas.hansson@arm.comcksum(const IpPtr &ptr) 1218948Sandreas.hansson@arm.com{ 1228948Sandreas.hansson@arm.com int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0); 1238948Sandreas.hansson@arm.com return ip_cksum_carry(sum); 1248707Sandreas.hansson@arm.com} 1258707Sandreas.hansson@arm.com 1268707Sandreas.hansson@arm.comuint16_t 1278707Sandreas.hansson@arm.com__tu_cksum(const IpPtr &ip) 1288707Sandreas.hansson@arm.com{ 1298707Sandreas.hansson@arm.com int tcplen = ip->len() - ip->hlen(); 1301060SN/A int sum = ip_cksum_add(ip->payload(), tcplen, 0); 1311755SN/A sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination 1325606Snate@binkert.org sum += htons(ip->ip_p + tcplen); 1331060SN/A return ip_cksum_carry(sum); 1341060SN/A} 1351060SN/A 1361060SN/Auint16_t 1371060SN/Acksum(const TcpPtr &tcp) 1381755SN/A{ return __tu_cksum(IpPtr(tcp.packet())); } 1391060SN/A 1401060SN/Auint16_t 1411060SN/Acksum(const UdpPtr &udp) 1421060SN/A{ return __tu_cksum(IpPtr(udp.packet())); } 1431060SN/A 1441060SN/Abool 1455336Shines@cs.fsu.eduIpHdr::options(vector<const IpOpt *> &vec) const 1461060SN/A{ 1474873Sstever@eecs.umich.edu vec.clear(); 1481060SN/A 1491060SN/A const uint8_t *data = bytes() + sizeof(struct ip_hdr); 1501060SN/A int all = hlen() - sizeof(struct ip_hdr); 1512829Sksewell@umich.edu while (all > 0) { 1525606Snate@binkert.org const IpOpt *opt = (const IpOpt *)data; 1532829Sksewell@umich.edu int len = opt->len(); 1542829Sksewell@umich.edu if (all < len) 1552829Sksewell@umich.edu return false; 1562829Sksewell@umich.edu 1572829Sksewell@umich.edu vec.push_back(opt); 1582829Sksewell@umich.edu all -= len; 1592829Sksewell@umich.edu data += len; 1602829Sksewell@umich.edu } 1612829Sksewell@umich.edu 1622829Sksewell@umich.edu return true; 1632829Sksewell@umich.edu} 1642829Sksewell@umich.edu 1652829Sksewell@umich.edubool 1662829Sksewell@umich.eduTcpHdr::options(vector<const TcpOpt *> &vec) const 1672829Sksewell@umich.edu{ 1682829Sksewell@umich.edu vec.clear(); 1692829Sksewell@umich.edu 1702829Sksewell@umich.edu const uint8_t *data = bytes() + sizeof(struct tcp_hdr); 1712829Sksewell@umich.edu int all = off() - sizeof(struct tcp_hdr); 1722829Sksewell@umich.edu while (all > 0) { 1732829Sksewell@umich.edu const TcpOpt *opt = (const TcpOpt *)data; 1745336Shines@cs.fsu.edu int len = opt->len(); 1752829Sksewell@umich.edu if (all < len) 1764873Sstever@eecs.umich.edu return false; 1772829Sksewell@umich.edu 1782829Sksewell@umich.edu vec.push_back(opt); 1792829Sksewell@umich.edu all -= len; 1802875Sksewell@umich.edu data += len; 1815606Snate@binkert.org } 1822875Sksewell@umich.edu 1832875Sksewell@umich.edu return true; 1842875Sksewell@umich.edu} 1852875Sksewell@umich.edu 1862875Sksewell@umich.edubool 1872875Sksewell@umich.eduTcpOpt::sack(vector<SackRange> &vec) const 1883859Sbinkertn@umich.edu{ 1892875Sksewell@umich.edu vec.clear(); 1902875Sksewell@umich.edu 1912875Sksewell@umich.edu const uint8_t *data = bytes() + sizeof(struct tcp_hdr); 1923859Sbinkertn@umich.edu int all = len() - offsetof(tcp_opt, opt_data.sack); 1932875Sksewell@umich.edu while (all > 0) { 1942875Sksewell@umich.edu const uint16_t *sack = (const uint16_t *)data; 1952875Sksewell@umich.edu int len = sizeof(uint16_t) * 2; 1962875Sksewell@umich.edu if (all < len) { 1972875Sksewell@umich.edu vec.clear(); 1982875Sksewell@umich.edu return false; 1992875Sksewell@umich.edu } 2003221Sktlim@umich.edu 2013221Sktlim@umich.edu vec.push_back(RangeIn(ntohs(sack[0]), ntohs(sack[1]))); 2022875Sksewell@umich.edu all -= len; 2032875Sksewell@umich.edu data += len; 2042875Sksewell@umich.edu } 2052875Sksewell@umich.edu 2065336Shines@cs.fsu.edu return false; 2072875Sksewell@umich.edu} 2084873Sstever@eecs.umich.edu 2092875Sksewell@umich.edu/* namespace Net */ } 2102875Sksewell@umich.edu