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