-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCEthernetLayer.cpp
More file actions
109 lines (86 loc) · 2.65 KB
/
CEthernetLayer.cpp
File metadata and controls
109 lines (86 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// CEthernetLayer.cpp: implementation of the CEthernetLayer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "pch.h"
#include "CEthernetLayer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CEthernetLayer::CEthernetLayer(char* pName)
: CBaseLayer(pName)
{
ResetHeader();
}
CEthernetLayer::~CEthernetLayer()
{
}
void CEthernetLayer::ResetHeader()
{
memset(m_sHeader.enet_dstaddr, 0, 6);
memset(m_sHeader.enet_srcaddr, 0, 6);
memset(m_sHeader.enet_data, ETHER_MAX_DATA_SIZE, 6);
m_sHeader.enet_type = 0;
}
unsigned char* CEthernetLayer::GetSourceAddress()
{
return m_sHeader.enet_srcaddr;
}
unsigned char* CEthernetLayer::GetDestinAddress()
{
return m_sHeader.enet_dstaddr;
}
void CEthernetLayer::SetSourceAddress(unsigned char* pAddress)
{
memcpy(m_sHeader.enet_srcaddr, pAddress, 6);
}
void CEthernetLayer::SetDestinAddress(unsigned char* pAddress)
{
memcpy(m_sHeader.enet_dstaddr, pAddress, 6);
}
BOOL CEthernetLayer::Send(unsigned char* ppayload, int nlength, unsigned short type)
{
memcpy(m_sHeader.enet_data, ppayload, nlength);
m_sHeader.enet_type = type;
return mp_UnderLayer->Send((unsigned char*)&m_sHeader, nlength + ETHER_HEADER_SIZE);
}
BOOL CEthernetLayer::Receive(unsigned char* ppayload)
{
PETHERNET_HEADER pFrame = (PETHERNET_HEADER)ppayload;
BOOL bSuccess = FALSE;
// Only take in ethernet frames that are sent directly to us or is broadcast.
if (!AddressEquals(pFrame->enet_dstaddr, m_sHeader.enet_srcaddr) && !IsBroadcast(pFrame->enet_dstaddr))
{
return FALSE;
}
if (AddressEquals(pFrame->enet_srcaddr, m_sHeader.enet_srcaddr))
{
// If, for some reason, we got the packet that we've sent back to us, discard
return FALSE;
}
// Demultiplexing
if (pFrame->enet_type == CHAT_TYPE)
{
// Kind of a wonky hack. We're indicating that the message is broadcast by setting a field here when we receive the message
if (IsBroadcast(pFrame->enet_dstaddr))
{
((CChatAppLayer::PCHAT_APP_HEADER)pFrame->enet_data)->type = CChatAppLayer::CHAT_MESSAGE_BROADCAST;
}
bSuccess = GetUpperLayer(0)->Receive(pFrame->enet_data);
}
return bSuccess;
}
bool CEthernetLayer::AddressEquals(unsigned char* addr1, unsigned char* addr2)
{
return memcmp(addr1, addr2, 6) == 0;
}
bool CEthernetLayer::IsBroadcast(unsigned char* address)
{
static unsigned char broadcastAddress[6] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
return AddressEquals(address, broadcastAddress);
}