diff --git a/src/upf/arp-nd.cpp b/src/upf/arp-nd.cpp index abf0e7691..d2921b0ed 100644 --- a/src/upf/arp-nd.cpp +++ b/src/upf/arp-nd.cpp @@ -52,6 +52,16 @@ bool is_arp_req(uint8_t *data, uint len) return _parse_arp(pdu); } +uint32_t arp_parse_target_addr(uint8_t *data, uint len) +{ + EthernetII pdu(data, len); + if (pdu.payload_type() == ETHERTYPE_ARP) { + const ARP& arp = pdu.rfind_pdu(); + return arp.target_ip_addr(); + } + return 0x0; +} + uint8_t arp_reply(uint8_t *reply_data, uint8_t *request_data, uint len, const uint8_t *mac) { diff --git a/src/upf/arp-nd.h b/src/upf/arp-nd.h index 07e574a3e..8a26b8cd5 100644 --- a/src/upf/arp-nd.h +++ b/src/upf/arp-nd.h @@ -39,6 +39,7 @@ extern "C" { void set_source_mac(uint8_t *data); bool is_arp_req(uint8_t *data, uint len); +uint32_t arp_parse_target_addr(uint8_t *data, uint len); uint8_t arp_reply(uint8_t *reply_data, uint8_t *request_data, uint len, const uint8_t *mac); bool is_nd_req(uint8_t *data, uint len); diff --git a/src/upf/gtp-path.c b/src/upf/gtp-path.c index 9edce8ed7..c9cb44913 100644 --- a/src/upf/gtp-path.c +++ b/src/upf/gtp-path.c @@ -123,7 +123,9 @@ static void _gtpv1_tun_recv_common_cb( uint8_t size; if (eth_type == ETHERTYPE_ARP) { - if (is_arp_req(recvbuf->data, recvbuf->len)) { + if (is_arp_req(recvbuf->data, recvbuf->len) && + upf_sess_find_by_ipv4( + arp_parse_target_addr(recvbuf->data, recvbuf->len))) { replybuf = ogs_pkbuf_alloc(packet_pool, OGS_MAX_PKT_LEN); ogs_assert(replybuf); ogs_pkbuf_reserve(replybuf, OGS_TUN_MAX_HEADROOM);