inet.cc revision 6712
12SN/A/*
21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
292SN/A */
302SN/A
316712Snate@binkert.org#include <cstdio>
322SN/A#include <sstream>
332SN/A#include <string>
342SN/A
3556SN/A#include "base/cprintf.hh"
366216Snate@binkert.org#include "base/inet.hh"
376214Snate@binkert.org#include "base/types.hh"
382SN/A
391078SN/Ausing namespace std;
401114SN/Anamespace Net {
411114SN/A
421114SN/AEthAddr::EthAddr()
431114SN/A{
441114SN/A    memset(data, 0, ETH_ADDR_LEN);
451114SN/A}
461114SN/A
471114SN/AEthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN])
481114SN/A{
491114SN/A    *data = *ea;
501114SN/A}
511114SN/A
521114SN/AEthAddr::EthAddr(const eth_addr &ea)
531114SN/A{
541114SN/A    *data = *ea.data;
551114SN/A}
561114SN/A
571114SN/AEthAddr::EthAddr(const std::string &addr)
581114SN/A{
591114SN/A    parse(addr);
601114SN/A}
611114SN/A
621114SN/Aconst EthAddr &
631114SN/AEthAddr::operator=(const eth_addr &ea)
641114SN/A{
651114SN/A    *data = *ea.data;
661114SN/A    return *this;
671114SN/A}
681114SN/A
691114SN/Aconst EthAddr &
701114SN/AEthAddr::operator=(const std::string &addr)
711114SN/A{
721114SN/A    parse(addr);
731114SN/A    return *this;
741114SN/A}
751114SN/A
761114SN/Avoid
771114SN/AEthAddr::parse(const std::string &addr)
781114SN/A{
791114SN/A    // the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise
801114SN/A    // the sscanf function won't work.
811114SN/A    int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1];
821114SN/A    if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1],
831114SN/A               &bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) {
841114SN/A        memset(data, 0xff, ETH_ADDR_LEN);
851114SN/A        return;
861114SN/A    }
871114SN/A
881114SN/A    for (int i = 0; i < ETH_ADDR_LEN; ++i) {
891114SN/A        if (bytes[i] & ~0xff) {
901114SN/A            memset(data, 0xff, ETH_ADDR_LEN);
911114SN/A            return;
921114SN/A        }
931114SN/A
941114SN/A        data[i] = bytes[i];
951114SN/A    }
961114SN/A}
971114SN/A
982SN/Astring
991114SN/AEthAddr::string() const
1002SN/A{
1012SN/A    stringstream stream;
1021114SN/A    stream << *this;
1032SN/A    return stream.str();
1042SN/A}
1052SN/A
1061114SN/Abool
1071114SN/Aoperator==(const EthAddr &left, const EthAddr &right)
1082SN/A{
1091114SN/A    return memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN);
1101114SN/A}
1111114SN/A
1121114SN/Aostream &
1131114SN/Aoperator<<(ostream &stream, const EthAddr &ea)
1141114SN/A{
1151114SN/A    const uint8_t *a = ea.addr();
1161114SN/A    ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]);
1171114SN/A    return stream;
1182SN/A}
1192SN/A
1201078SN/Auint16_t
1211114SN/Acksum(const IpPtr &ptr)
1221078SN/A{
1231114SN/A    int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0);
1241114SN/A    return ip_cksum_carry(sum);
1251078SN/A}
1261114SN/A
1271114SN/Auint16_t
1281114SN/A__tu_cksum(const IpPtr &ip)
1291114SN/A{
1301114SN/A    int tcplen = ip->len() - ip->hlen();
1311114SN/A    int sum = ip_cksum_add(ip->payload(), tcplen, 0);
1321114SN/A    sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination
1331114SN/A    sum += htons(ip->ip_p + tcplen);
1341114SN/A    return ip_cksum_carry(sum);
1351114SN/A}
1361114SN/A
1371114SN/Auint16_t
1381114SN/Acksum(const TcpPtr &tcp)
1391114SN/A{ return __tu_cksum(IpPtr(tcp.packet())); }
1401114SN/A
1411114SN/Auint16_t
1421114SN/Acksum(const UdpPtr &udp)
1431114SN/A{ return __tu_cksum(IpPtr(udp.packet())); }
1441114SN/A
1451114SN/Abool
1461114SN/AIpHdr::options(vector<const IpOpt *> &vec) const
1471114SN/A{
1481114SN/A    vec.clear();
1491114SN/A
1501114SN/A    const uint8_t *data = bytes() + sizeof(struct ip_hdr);
1511114SN/A    int all = hlen() - sizeof(struct ip_hdr);
1521114SN/A    while (all > 0) {
1531114SN/A        const IpOpt *opt = (const IpOpt *)data;
1541114SN/A        int len = opt->len();
1551114SN/A        if (all < len)
1561114SN/A            return false;
1571114SN/A
1581114SN/A        vec.push_back(opt);
1591114SN/A        all -= len;
1601114SN/A        data += len;
1611114SN/A    }
1621114SN/A
1631114SN/A    return true;
1641114SN/A}
1651114SN/A
1661114SN/Abool
1671114SN/ATcpHdr::options(vector<const TcpOpt *> &vec) const
1681114SN/A{
1691114SN/A    vec.clear();
1701114SN/A
1711114SN/A    const uint8_t *data = bytes() + sizeof(struct tcp_hdr);
1721114SN/A    int all = off() - sizeof(struct tcp_hdr);
1731114SN/A    while (all > 0) {
1741114SN/A        const TcpOpt *opt = (const TcpOpt *)data;
1751114SN/A        int len = opt->len();
1761114SN/A        if (all < len)
1771114SN/A            return false;
1781114SN/A
1791114SN/A        vec.push_back(opt);
1801114SN/A        all -= len;
1811114SN/A        data += len;
1821114SN/A    }
1831114SN/A
1841114SN/A    return true;
1851114SN/A}
1861114SN/A
1871114SN/Abool
1881114SN/ATcpOpt::sack(vector<SackRange> &vec) const
1891114SN/A{
1901114SN/A    vec.clear();
1911114SN/A
1921114SN/A    const uint8_t *data = bytes() + sizeof(struct tcp_hdr);
1931114SN/A    int all = len() - offsetof(tcp_opt, opt_data.sack);
1941114SN/A    while (all > 0) {
1951114SN/A        const uint16_t *sack = (const uint16_t *)data;
1961114SN/A        int len = sizeof(uint16_t) * 2;
1971114SN/A        if (all < len) {
1981114SN/A            vec.clear();
1991114SN/A            return false;
2001114SN/A        }
2011114SN/A
2021114SN/A        vec.push_back(RangeIn(ntohs(sack[0]), ntohs(sack[1])));
2031114SN/A        all -= len;
2041114SN/A        data += len;
2051114SN/A    }
2061114SN/A
2071114SN/A    return false;
2081114SN/A}
2091114SN/A
2105782Ssaidi@eecs.umich.eduint
2115782Ssaidi@eecs.umich.eduhsplit(const EthPacketPtr &ptr)
2125782Ssaidi@eecs.umich.edu{
2135782Ssaidi@eecs.umich.edu    int split_point = 0;
2145782Ssaidi@eecs.umich.edu
2155782Ssaidi@eecs.umich.edu    IpPtr ip(ptr);
2165782Ssaidi@eecs.umich.edu    if (ip) {
2175782Ssaidi@eecs.umich.edu        split_point = ip.pstart();
2185782Ssaidi@eecs.umich.edu
2195782Ssaidi@eecs.umich.edu        TcpPtr tcp(ip);
2205782Ssaidi@eecs.umich.edu        if (tcp)
2215782Ssaidi@eecs.umich.edu            split_point = tcp.pstart();
2225782Ssaidi@eecs.umich.edu
2235782Ssaidi@eecs.umich.edu        UdpPtr udp(ip);
2245782Ssaidi@eecs.umich.edu        if (udp)
2255782Ssaidi@eecs.umich.edu            split_point = udp.pstart();
2265782Ssaidi@eecs.umich.edu    }
2275782Ssaidi@eecs.umich.edu    return split_point;
2285782Ssaidi@eecs.umich.edu}
2295782Ssaidi@eecs.umich.edu
2305782Ssaidi@eecs.umich.edu
2311114SN/A/* namespace Net */ }
232