VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/NetLib/VBoxNetARP.cpp

Last change on this file was 106061, checked in by vboxsync, 7 weeks ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1/* $Id: VBoxNetARP.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBoxNetARP - IntNet ARP Client Routines.
4 */
5
6/*
7 * Copyright (C) 2009-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DEFAULT
33#include "VBoxNetLib.h"
34#include <iprt/string.h>
35#include <VBox/intnetinline.h>
36#include <VBox/log.h>
37
38
39/**
40 * Deal with ARP queries.
41 *
42 * @returns true if ARP.
43 *
44 * @param pSession The support driver session.
45 * @param hIf The internal network interface handle.
46 * @param pBuf The internal network interface buffer.
47 * @param pMacAddr Our MAC address.
48 * @param IPv4Addr Our IPv4 address.
49 */
50bool VBoxNetArpHandleIt(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf, PCRTMAC pMacAddr, RTNETADDRIPV4 IPv4Addr)
51{
52 /*
53 * Valid IntNet Ethernet frame? Skip GSO, no ARP in there.
54 */
55 PCINTNETHDR pHdr = IntNetRingGetNextFrameToRead(&pBuf->Recv);
56 if ( !pHdr
57 || pHdr->u8Type != INTNETHDR_TYPE_FRAME)
58 return false;
59
60 size_t cbFrame = pHdr->cbFrame;
61 const void *pvFrame = IntNetHdrGetFramePtr(pHdr, pBuf);
62 PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pvFrame;
63
64 /*
65 * Arp frame?
66 */
67 if (pEthHdr->EtherType != RT_H2N_U16_C(RTNET_ETHERTYPE_ARP))
68 return false;
69 if ( ( pEthHdr->DstMac.au16[0] != 0xffff
70 || pEthHdr->DstMac.au16[1] != 0xffff
71 || pEthHdr->DstMac.au16[2] != 0xffff)
72 && ( pEthHdr->DstMac.au16[0] != pMacAddr->au16[0]
73 || pEthHdr->DstMac.au16[1] != pMacAddr->au16[1]
74 || pEthHdr->DstMac.au16[2] != pMacAddr->au16[2])
75 )
76 return false;
77 if (cbFrame < sizeof(RTNETARPIPV4) + sizeof(RTNETETHERHDR))
78 return false;
79
80 PCRTNETARPHDR pArpHdr = (PCRTNETARPHDR)(pEthHdr + 1);
81 if (pArpHdr->ar_htype != RT_H2N_U16_C(RTNET_ARP_ETHER))
82 return false;
83 if (pArpHdr->ar_hlen != sizeof(RTMAC))
84 return false;
85 if (pArpHdr->ar_ptype != RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4))
86 return false;
87 if (pArpHdr->ar_plen != sizeof(RTNETADDRIPV4))
88 return false;
89
90 /* It's ARP, alright. Anything we need to do something about. */
91 PCRTNETARPIPV4 pArp = (PCRTNETARPIPV4)pArpHdr;
92 switch (pArp->Hdr.ar_oper)
93 {
94 case RT_H2N_U16_C(RTNET_ARPOP_REQUEST):
95 case RT_H2N_U16_C(RTNET_ARPOP_REVREQUEST):
96 case RT_H2N_U16_C(RTNET_ARPOP_INVREQUEST):
97 break;
98 default:
99 return true;
100 }
101
102 /*
103 * Deal with the queries.
104 */
105 RTNETARPIPV4 Reply;
106 switch (pArp->Hdr.ar_oper)
107 {
108 /* 'Who has ar_tpa? Tell ar_spa.' */
109 case RT_H2N_U16_C(RTNET_ARPOP_REQUEST):
110 if (pArp->ar_tpa.u != IPv4Addr.u)
111 return true;
112 Reply.Hdr.ar_oper = RT_H2N_U16_C(RTNET_ARPOP_REPLY);
113 break;
114
115 case RT_H2N_U16_C(RTNET_ARPOP_REVREQUEST):
116 if ( pArp->ar_tha.au16[0] != pMacAddr->au16[0]
117 || pArp->ar_tha.au16[1] != pMacAddr->au16[1]
118 || pArp->ar_tha.au16[2] != pMacAddr->au16[2])
119 return true;
120 Reply.Hdr.ar_oper = RT_H2N_U16_C(RTNET_ARPOP_REVREPLY);
121 break;
122
123 case RT_H2N_U16_C(RTNET_ARPOP_INVREQUEST):
124 /** @todo RTNET_ARPOP_INVREQUEST */
125 return true;
126 //Reply.Hdr.ar_oper = RT_H2N_U16_C(RTNET_ARPOP_INVREPLY);
127 //break;
128 }
129
130 /*
131 * Complete the reply and send it.
132 */
133 Reply.Hdr.ar_htype = RT_H2N_U16_C(RTNET_ARP_ETHER);
134 Reply.Hdr.ar_ptype = RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4);
135 Reply.Hdr.ar_hlen = sizeof(RTMAC);
136 Reply.Hdr.ar_plen = sizeof(RTNETADDRIPV4);
137 Reply.ar_sha = *pMacAddr;
138 Reply.ar_spa = IPv4Addr;
139 Reply.ar_tha = pArp->ar_sha;
140 Reply.ar_tpa = pArp->ar_spa;
141
142
143 RTNETETHERHDR EthHdr;
144 EthHdr.DstMac = pArp->ar_sha;
145 EthHdr.SrcMac = *pMacAddr;
146 EthHdr.EtherType = RT_H2N_U16_C(RTNET_ETHERTYPE_ARP);
147
148 uint8_t abTrailer[60 - sizeof(Reply) - sizeof(EthHdr)];
149 RT_ZERO(abTrailer);
150
151 INTNETSEG aSegs[3];
152 aSegs[0].cb = sizeof(EthHdr);
153 aSegs[0].pv = &EthHdr;
154
155 aSegs[1].pv = &Reply;
156 aSegs[1].cb = sizeof(Reply);
157
158 aSegs[2].pv = &abTrailer[0];
159 aSegs[2].cb = sizeof(abTrailer);
160
161 VBoxNetIntIfSend(pSession, hIf, pBuf, RT_ELEMENTS(aSegs), &aSegs[0], true /* fFlush */);
162
163 return true;
164}
165
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette