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