VirtualBox

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

Last change on this file since 62495 was 62481, checked in by vboxsync, 8 years ago

(C) 2016

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