inet.cc revision 1114
16892SBrad.Beckmann@amd.com/* 26892SBrad.Beckmann@amd.com * Copyright (c) 2002-2003 The Regents of The University of Michigan 36892SBrad.Beckmann@amd.com * All rights reserved. 46892SBrad.Beckmann@amd.com * 56892SBrad.Beckmann@amd.com * Redistribution and use in source and binary forms, with or without 66892SBrad.Beckmann@amd.com * modification, are permitted provided that the following conditions are 76892SBrad.Beckmann@amd.com * met: redistributions of source code must retain the above copyright 86892SBrad.Beckmann@amd.com * notice, this list of conditions and the following disclaimer; 96892SBrad.Beckmann@amd.com * redistributions in binary form must reproduce the above copyright 106892SBrad.Beckmann@amd.com * notice, this list of conditions and the following disclaimer in the 116892SBrad.Beckmann@amd.com * documentation and/or other materials provided with the distribution; 126892SBrad.Beckmann@amd.com * neither the name of the copyright holders nor the names of its 136892SBrad.Beckmann@amd.com * contributors may be used to endorse or promote products derived from 146892SBrad.Beckmann@amd.com * this software without specific prior written permission. 156892SBrad.Beckmann@amd.com * 166892SBrad.Beckmann@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176892SBrad.Beckmann@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186892SBrad.Beckmann@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196892SBrad.Beckmann@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206892SBrad.Beckmann@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216892SBrad.Beckmann@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226892SBrad.Beckmann@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236892SBrad.Beckmann@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246892SBrad.Beckmann@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256892SBrad.Beckmann@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266892SBrad.Beckmann@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276892SBrad.Beckmann@amd.com */ 286892SBrad.Beckmann@amd.com 296892SBrad.Beckmann@amd.com#include <cstdio> 306892SBrad.Beckmann@amd.com#include <sstream> 316892SBrad.Beckmann@amd.com#include <string> 326892SBrad.Beckmann@amd.com 336892SBrad.Beckmann@amd.com#include "base/cprintf.hh" 347538SBrad.Beckmann@amd.com#include "sim/host.hh" 357538SBrad.Beckmann@amd.com#include "base/inet.hh" 367538SBrad.Beckmann@amd.com 377538SBrad.Beckmann@amd.comusing namespace std; 387538SBrad.Beckmann@amd.comnamespace Net { 397538SBrad.Beckmann@amd.com 407538SBrad.Beckmann@amd.comEthAddr::EthAddr() 417538SBrad.Beckmann@amd.com{ 427538SBrad.Beckmann@amd.com memset(data, 0, ETH_ADDR_LEN); 437538SBrad.Beckmann@amd.com} 447538SBrad.Beckmann@amd.com 457538SBrad.Beckmann@amd.comEthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN]) 467538SBrad.Beckmann@amd.com{ 477538SBrad.Beckmann@amd.com *data = *ea; 487538SBrad.Beckmann@amd.com} 497538SBrad.Beckmann@amd.com 507538SBrad.Beckmann@amd.comEthAddr::EthAddr(const eth_addr &ea) 517555SBrad.Beckmann@amd.com{ 527555SBrad.Beckmann@amd.com *data = *ea.data; 537555SBrad.Beckmann@amd.com} 547555SBrad.Beckmann@amd.com 557538SBrad.Beckmann@amd.comEthAddr::EthAddr(const std::string &addr) 567538SBrad.Beckmann@amd.com{ 577538SBrad.Beckmann@amd.com parse(addr); 587538SBrad.Beckmann@amd.com} 597541SBrad.Beckmann@amd.com 606892SBrad.Beckmann@amd.comconst EthAddr & 617032SBrad.Beckmann@amd.comEthAddr::operator=(const eth_addr &ea) 627032SBrad.Beckmann@amd.com{ 636923SBrad.Beckmann@amd.com *data = *ea.data; 646893SBrad.Beckmann@amd.com return *this; 657557SBrad.Beckmann@amd.com} 667557SBrad.Beckmann@amd.com 676923SBrad.Beckmann@amd.comconst EthAddr & 686923SBrad.Beckmann@amd.comEthAddr::operator=(const std::string &addr) 697557SBrad.Beckmann@amd.com{ 706923SBrad.Beckmann@amd.com parse(addr); 716892SBrad.Beckmann@amd.com return *this; 727032SBrad.Beckmann@amd.com} 737032SBrad.Beckmann@amd.com 746892SBrad.Beckmann@amd.comvoid 757032SBrad.Beckmann@amd.comEthAddr::parse(const std::string &addr) 767032SBrad.Beckmann@amd.com{ 777557SBrad.Beckmann@amd.com // the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise 787557SBrad.Beckmann@amd.com // the sscanf function won't work. 797032SBrad.Beckmann@amd.com int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1]; 807032SBrad.Beckmann@amd.com if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1], 817557SBrad.Beckmann@amd.com &bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) { 827011SBrad.Beckmann@amd.com memset(data, 0xff, ETH_ADDR_LEN); 836918SBrad.Beckmann@amd.com return; 846918SBrad.Beckmann@amd.com } 856918SBrad.Beckmann@amd.com 866918SBrad.Beckmann@amd.com for (int i = 0; i < ETH_ADDR_LEN; ++i) { 876918SBrad.Beckmann@amd.com if (bytes[i] & ~0xff) { 886918SBrad.Beckmann@amd.com memset(data, 0xff, ETH_ADDR_LEN); 896892SBrad.Beckmann@amd.com return; 906903SBrad.Beckmann@amd.com } 917025SBrad.Beckmann@amd.com 927025SBrad.Beckmann@amd.com data[i] = bytes[i]; 937025SBrad.Beckmann@amd.com } 947025SBrad.Beckmann@amd.com} 956903SBrad.Beckmann@amd.com 966903SBrad.Beckmann@amd.comstring 976903SBrad.Beckmann@amd.comEthAddr::string() const 986903SBrad.Beckmann@amd.com{ 997541SBrad.Beckmann@amd.com stringstream stream; 1007541SBrad.Beckmann@amd.com stream << *this; 1016905SBrad.Beckmann@amd.com return stream.str(); 1026892SBrad.Beckmann@amd.com} 1036897SBrad.Beckmann@amd.com 1046892SBrad.Beckmann@amd.combool 1056893SBrad.Beckmann@amd.comoperator==(const EthAddr &left, const EthAddr &right) 1066892SBrad.Beckmann@amd.com{ 1076892SBrad.Beckmann@amd.com return memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN); 1086892SBrad.Beckmann@amd.com} 1096892SBrad.Beckmann@amd.com 1106892SBrad.Beckmann@amd.comostream & 1117555SBrad.Beckmann@amd.comoperator<<(ostream &stream, const EthAddr &ea) 1127555SBrad.Beckmann@amd.com{ 1136903SBrad.Beckmann@amd.com const uint8_t *a = ea.addr(); 1146892SBrad.Beckmann@amd.com ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]); 1156893SBrad.Beckmann@amd.com return stream; 1166892SBrad.Beckmann@amd.com} 1176892SBrad.Beckmann@amd.com 118uint16_t 119cksum(const IpPtr &ptr) 120{ 121 int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0); 122 return ip_cksum_carry(sum); 123} 124 125uint16_t 126__tu_cksum(const IpPtr &ip) 127{ 128 int tcplen = ip->len() - ip->hlen(); 129 int sum = ip_cksum_add(ip->payload(), tcplen, 0); 130 sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination 131 sum += htons(ip->ip_p + tcplen); 132 return ip_cksum_carry(sum); 133} 134 135uint16_t 136cksum(const TcpPtr &tcp) 137{ return __tu_cksum(IpPtr(tcp.packet())); } 138 139uint16_t 140cksum(const UdpPtr &udp) 141{ return __tu_cksum(IpPtr(udp.packet())); } 142 143bool 144IpHdr::options(vector<const IpOpt *> &vec) const 145{ 146 vec.clear(); 147 148 const uint8_t *data = bytes() + sizeof(struct ip_hdr); 149 int all = hlen() - sizeof(struct ip_hdr); 150 while (all > 0) { 151 const IpOpt *opt = (const IpOpt *)data; 152 int len = opt->len(); 153 if (all < len) 154 return false; 155 156 vec.push_back(opt); 157 all -= len; 158 data += len; 159 } 160 161 return true; 162} 163 164bool 165TcpHdr::options(vector<const TcpOpt *> &vec) const 166{ 167 vec.clear(); 168 169 const uint8_t *data = bytes() + sizeof(struct tcp_hdr); 170 int all = off() - sizeof(struct tcp_hdr); 171 while (all > 0) { 172 const TcpOpt *opt = (const TcpOpt *)data; 173 int len = opt->len(); 174 if (all < len) 175 return false; 176 177 vec.push_back(opt); 178 all -= len; 179 data += len; 180 } 181 182 return true; 183} 184 185bool 186TcpOpt::sack(vector<SackRange> &vec) const 187{ 188 vec.clear(); 189 190 const uint8_t *data = bytes() + sizeof(struct tcp_hdr); 191 int all = len() - offsetof(tcp_opt, opt_data.sack); 192 while (all > 0) { 193 const uint16_t *sack = (const uint16_t *)data; 194 int len = sizeof(uint16_t) * 2; 195 if (all < len) { 196 vec.clear(); 197 return false; 198 } 199 200 vec.push_back(RangeIn(ntohs(sack[0]), ntohs(sack[1]))); 201 all -= len; 202 data += len; 203 } 204 205 return false; 206} 207 208/* namespace Net */ } 209