LCOV - code coverage report
Current view: top level - vnsw/agent/services - icmp_handler.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 61 0.0 %
Date: 2026-06-08 02:02:55 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <stdint.h>
       6             : #include <vr_defs.h>
       7             : #include <cmn/agent_cmn.h>
       8             : #include <pkt/pkt_init.h>
       9             : #include <pkt/control_interface.h>
      10             : #include <oper/interface_common.h>
      11             : #include <services/icmp_proto.h>
      12             : #include <boost/scoped_array.hpp>
      13             : 
      14           0 : IcmpHandler::IcmpHandler(Agent *agent, boost::shared_ptr<PktInfo> info,
      15           0 :                          boost::asio::io_context &io)
      16           0 :     : ProtoHandler(agent, info, io), icmp_(pkt_info_->transp.icmp) {
      17           0 :     icmp_len_ = ntohs(pkt_info_->ip->ip_len) - (pkt_info_->ip->ip_hl * 4);
      18           0 : }
      19             : 
      20           0 : IcmpHandler::~IcmpHandler() {
      21           0 : }
      22             : 
      23           0 : bool IcmpHandler::Run() {
      24             : 
      25           0 :     IcmpProto *icmp_proto = agent()->GetIcmpProto();
      26             :     Interface *itf =
      27           0 :         agent()->interface_table()->FindInterface(GetInterfaceIndex());
      28           0 :     if (itf == NULL) {
      29           0 :         icmp_proto->IncrStatsIntfNotInst();
      30           0 :         return true;
      31             :     }
      32           0 :     VmInterface *vm_itf = static_cast<VmInterface *>(itf);
      33           0 :     if (!vm_itf->layer3_forwarding()) {
      34           0 :         icmp_proto->IncrStatsNoL3Fwd();
      35           0 :         return true;
      36             :     }
      37           0 :     switch (icmp_->icmp_type) {
      38           0 :         case ICMP_ECHO:
      39           0 :             if (CheckPacket()) {
      40           0 :                 icmp_proto->IncrStatsGwPing();
      41           0 :                 SendResponse(vm_itf);
      42             :             } else
      43           0 :                 icmp_proto->IncrStatsGwPingErr();
      44           0 :             return true;
      45             : 
      46           0 :         default:
      47           0 :             icmp_proto->IncrStatsDrop();
      48           0 :             return true;
      49             :     }
      50             : }
      51             : 
      52           0 : bool IcmpHandler::CheckPacket() {
      53           0 :     if (pkt_info_->len < (sizeof(struct ether_header) + ntohs(pkt_info_->ip->ip_len)))
      54           0 :         return false;
      55             : 
      56           0 :     uint16_t checksum = icmp_->icmp_cksum;
      57           0 :     icmp_->icmp_cksum = 0;
      58           0 :     if (checksum == Csum((uint16_t *)icmp_, icmp_len_, 0))
      59           0 :         return true;
      60             : 
      61           0 :     return false;
      62             : }
      63             : 
      64           0 : void IcmpHandler::SendResponse(VmInterface *vm_intf) {
      65             :     // Max size of buffer
      66           0 :     char *ptr = (char *)pkt_info_->pkt;
      67           0 :     uint16_t buf_len = pkt_info_->max_pkt_len;
      68             : 
      69             :     // Copy the ICMP payload
      70           0 :     boost::scoped_array<char> icmp_payload(new char[icmp_len_]);
      71           0 :     memcpy(icmp_payload.get(), icmp_, icmp_len_);
      72             : 
      73           0 :     uint16_t len = 0;
      74             : 
      75             :     // Form ICMP Packet with following
      76             :     // EthHdr - IP Header - ICMP Header
      77           0 :     len += EthHdr(ptr + len, buf_len - len,
      78           0 :                   MacAddress(pkt_info_->eth->ether_dhost),
      79           0 :                   MacAddress(pkt_info_->eth->ether_shost),
      80           0 :                   ETHERTYPE_IP, vm_intf->tx_vlan_id());
      81             : 
      82           0 :     uint16_t ip_len = sizeof(struct ip) + icmp_len_;
      83             : 
      84           0 :     len += IpHdr(ptr + len, buf_len - len, ip_len,
      85           0 :                  htonl(pkt_info_->ip_daddr.to_v4().to_ulong()),
      86           0 :                  htonl(pkt_info_->ip_saddr.to_v4().to_ulong()),
      87             :                  IPPROTO_ICMP, DEFAULT_IP_ID, DEFAULT_IP_TTL);
      88             : 
      89             :     // Restore the ICMP header copied earlier
      90           0 :     struct icmp *hdr = (struct icmp *) (ptr + len);
      91           0 :     memcpy(ptr + len, icmp_payload.get(), icmp_len_);
      92           0 :     len += icmp_len_;
      93             : 
      94             :     // Change type to reply
      95           0 :     hdr->icmp_type = ICMP_ECHOREPLY;
      96             :     // Recompute ICMP checksum
      97           0 :     IcmpChecksum((char *)hdr, icmp_len_);
      98           0 :     pkt_info_->set_len(len);
      99             : 
     100             :     uint32_t interface =
     101           0 :         ((pkt_info_->agent_hdr.cmd == AgentHdr::TRAP_TOR_CONTROL_PKT) ?
     102           0 :          pkt_info_->agent_hdr.cmd_param : GetInterfaceIndex());
     103             :     uint16_t command =
     104           0 :         ((pkt_info_->agent_hdr.cmd == AgentHdr::TRAP_TOR_CONTROL_PKT) ?
     105           0 :          AgentHdr::TX_ROUTE : AgentHdr::TX_SWITCH);
     106           0 :     Send(interface, pkt_info_->vrf, command, PktHandler::ICMP);
     107           0 : }

Generated by: LCOV version 1.14