VirtualBox

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

Last change on this file since 46861 was 44529, checked in by vboxsync, 12 years ago

header (C) fixes

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