28 if (buf.getLength() - buf.getPosition() < ETHERNET_HEADER_LEN) {
30 <<
"packet is invalid, expected at least "
31 << ETHERNET_HEADER_LEN <<
" bytes, received "
32 << buf.getLength() - buf.getPosition() <<
" bytes");
47 size_t start_pos = buf.getPosition();
50 std::vector<uint8_t> dest_addr;
54 std::vector<uint8_t> src_addr;
58 buf.setPosition(start_pos + ETHERNET_HEADER_LEN);
65 if (buf.getLength() - buf.getPosition() < MIN_IP_HEADER_LEN + UDP_HEADER_LEN) {
67 <<
"received packet is invalid, expected at least "
68 << MIN_IP_HEADER_LEN + UDP_HEADER_LEN
69 <<
" bytes, received " << buf.getLength() - buf.getPosition()
79 BOOST_STATIC_ASSERT(IP_SRC_ADDR_OFFSET < MIN_IP_HEADER_LEN);
82 size_t start_pos = buf.getPosition();
85 uint8_t ip_len = buf.readUint8() & 0xF;
90 <<
" lower than 5 words. The length of the received header is "
91 <<
static_cast<unsigned>(ip_len) <<
".");
95 buf.setPosition(start_pos + IP_SRC_ADDR_OFFSET);
97 pkt->setRemoteAddr(
IOAddress(buf.readUint32()));
99 pkt->setLocalAddr(
IOAddress(buf.readUint32()));
103 buf.setPosition(start_pos + ip_len * 4);
106 pkt->setRemotePort(buf.readUint16());
108 pkt->setLocalPort(buf.readUint16());
112 buf.setPosition(start_pos + ip_len * 4 + UDP_HEADER_LEN);
118 HWAddrPtr remote_addr = pkt->getRemoteHWAddr();
122 << remote_addr->hwaddr_.size() <<
" when constructing"
123 <<
" an ethernet frame header; expected size is"
125 }
else if (!pkt->isRelayed() &&
130 out_buf.writeData(&remote_addr->hwaddr_[0],
143 HWAddrPtr local_addr = pkt->getLocalHWAddr();
146 out_buf.writeData(&local_addr->hwaddr_[0],
150 << local_addr->hwaddr_.size() <<
" when constructing"
151 <<
" an ethernet frame header; expected size is"
161 out_buf.writeUint16(ETHERNET_TYPE_IP);
167 out_buf.writeUint8(0x45);
168 out_buf.writeUint8(IPTOS_LOWDELAY);
169 out_buf.writeUint16(28 + pkt->getBuffer().getLength());
170 out_buf.writeUint16(0);
171 out_buf.writeUint16(0x4000);
172 out_buf.writeUint8(128);
173 out_buf.writeUint8(IPPROTO_UDP);
174 out_buf.writeUint16(0);
175 out_buf.writeUint32(pkt->getLocalAddr().toUint32());
176 out_buf.writeUint32(pkt->getRemoteAddr().toUint32());
181 uint32_t udp_len = 8 + pkt->getBuffer().getLength();
188 uint16_t pseudo_hdr_checksum =
189 calcChecksum(out_buf.getData() + out_buf.getLength() - 8,
190 8, IPPROTO_UDP + udp_len);
193 uint16_t ip_checksum = ~calcChecksum(out_buf.getData()
194 + out_buf.getLength() - 20, 20);
197 out_buf.writeUint16At(ip_checksum, out_buf.getLength() - 10);
200 out_buf.writeUint16(pkt->getLocalPort());
201 out_buf.writeUint16(pkt->getRemotePort());
202 out_buf.writeUint16(udp_len);
208 uint16_t udp_checksum =
209 ~calcChecksum(out_buf.getData() + out_buf.getLength() - 6, 6,
211 pkt->getBuffer().getLength(),
212 pseudo_hdr_checksum));
214 out_buf.writeUint16(udp_checksum);