17 boost::shared_ptr<PktInfo> info,
18 boost::asio::io_context *io) :
26 if (
pkt_info_->len < (
sizeof(
struct ether_header) +
sizeof(
struct ip)))
40 vm_itf->
vn() == NULL) {
51 uint16_t data_len = ntohs(
pkt_info_->ip->ip_len);
58 bool is_nat_flow =
false;
60 if (
pkt_info_->agent_hdr.flow_index == (uint32_t)-1) {
62 if (
pkt_info_->ip_daddr.to_v4().to_ulong() != 0xFFFFFFFF) {
66 src_ip =
pkt_info_->ip_saddr.to_v4().to_ulong();
81 src_ip = key.
src_addr.to_v4().to_ulong();
86 if (ipam == NULL || ipam->
default_gw.is_v4() ==
false) {
93 uint16_t buf_len =
pkt_info_->max_pkt_len;
98 len +=
EthHdr(ptr + len, buf_len - len,
104 uint16_t ip_len =
sizeof(
struct ip) + icmp_len + data_len;
105 len +=
IpHdr(ptr + len, buf_len - len, ip_len,
109 char *icmp = ptr + len;
110 len +=
IcmpHdr(ptr + len, buf_len - len, ICMP_UNREACH,
111 ICMP_UNREACH_NEEDFRAG, 0,
pkt_info_->agent_hdr.mtu);
113 if (
pkt_info_->agent_hdr.flow_index != (uint32_t)-1) {
116 struct ip *ip = (
struct ip *)data;
117 uint16_t ip_hlen = ip->ip_hl * 4;
119 ip->ip_src.s_addr = htonl(key.
src_addr.to_v4().to_ulong());
120 ip->ip_dst.s_addr = htonl(key.
dst_addr.to_v4().to_ulong());
122 ip->ip_sum =
Csum((uint16_t *)data, ip_hlen, 0);
123 if (ip->ip_p == IPPROTO_UDP) {
124 udphdr *udp = (udphdr *)(data + ip_hlen);
125 udp->uh_sport = ntohs(key.
src_port);
126 udp->uh_dport = ntohs(key.
dst_port);
127 }
else if (ip->ip_p == IPPROTO_TCP) {
128 tcphdr *tcp = (tcphdr *)(data + ip_hlen);
129 tcp->th_sport = ntohs(key.
src_port);
130 tcp->th_dport = ntohs(key.
dst_port);
133 memcpy(ptr + len, data, data_len);
bool SendIcmpError(VmInterface *intf)
const VnIpam * GetIpam(const IpAddress &ip) const
const Interface * vhost_interface() const
static const int ICMP_PAYLOAD_LEN
InterfaceTable * interface_table() const
uint16_t Csum(uint16_t *, std::size_t, uint32_t) const
const MacAddress & mac() const
boost::shared_ptr< PktInfo > pkt_info_
uint16_t tx_vlan_id() const
int EthHdr(const MacAddress &src, const MacAddress &dest, const uint16_t proto)
uint32_t GetInterfaceIndex() const
void Send(uint32_t itf, uint32_t vrf, uint16_t, PktHandler::PktModuleName)
bool layer3_forwarding() const
const VnEntry * vn() const
boost::asio::ip::address_v4 Ip4Address
IcmpErrorHandler(Agent *agent, IcmpErrorProto *proto, boost::shared_ptr< PktInfo > info, boost::asio::io_context *io)
void IcmpChecksum(char *buff, uint16_t buf_len)
#define ICMP_UNREACH_HDR_LEN
void increment_interface_errors()
void increment_invalid_flow_index()
virtual ~IcmpErrorHandler()
const Interface * FindInterface(size_t index) const
bool FlowIndexToKey(uint32_t index, FlowKey *key, bool *is_nat_flow)
uint16_t IcmpHdr(char *buff, uint16_t buf_len, uint8_t type, uint8_t code, uint16_t word1, uint16_t word2)
void IpHdr(uint16_t len, in_addr_t src, in_addr_t dest, uint8_t protocol, uint16_t id, uint8_t ttl)