A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#include "wifi-net-device.h"
21
23#include "sta-wifi-mac.h"
24#include "wifi-phy.h"
25
26#include "ns3/channel.h"
27#include "ns3/eht-configuration.h"
28#include "ns3/he-configuration.h"
29#include "ns3/ht-configuration.h"
30#include "ns3/llc-snap-header.h"
31#include "ns3/log.h"
32#include "ns3/node.h"
33#include "ns3/object-vector.h"
34#include "ns3/pointer.h"
35#include "ns3/uinteger.h"
36#include "ns3/vht-configuration.h"
37
38namespace ns3
39{
40
41NS_LOG_COMPONENT_DEFINE("WifiNetDevice");
42
43NS_OBJECT_ENSURE_REGISTERED(WifiNetDevice);
44
45TypeId
47{
48 static TypeId tid =
49 TypeId("ns3::WifiNetDevice")
51 .AddConstructor<WifiNetDevice>()
52 .SetGroupName("Wifi")
53 .AddAttribute("Mtu",
54 "The MAC-level Maximum Transmission Unit",
57 MakeUintegerChecker<uint16_t>(1, MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH))
58 .AddAttribute("Channel",
59 "The channel attached to this device",
62 MakePointerChecker<Channel>(),
64 "class WifiNetDevice; use the Channel "
65 "attribute of WifiPhy")
66 .AddAttribute("Phy",
67 "The PHY layer attached to this device.",
72 MakePointerChecker<WifiPhy>())
73 .AddAttribute(
74 "Phys",
75 "The PHY layers attached to this device (11be multi-link devices only).",
78 MakeObjectVectorChecker<WifiPhy>())
79 .AddAttribute("Mac",
80 "The MAC layer attached to this device.",
83 MakePointerChecker<WifiMac>())
84 .AddAttribute(
85 "RemoteStationManager",
86 "The station manager attached to this device.",
91 MakePointerChecker<WifiRemoteStationManager>())
92 .AddAttribute("RemoteStationManagers",
93 "The remote station managers attached to this device (11be multi-link "
94 "devices only).",
98 MakeObjectVectorChecker<WifiRemoteStationManager>())
99 .AddAttribute("HtConfiguration",
100 "The HtConfiguration object.",
101 PointerValue(),
103 MakePointerChecker<HtConfiguration>())
104 .AddAttribute("VhtConfiguration",
105 "The VhtConfiguration object.",
106 PointerValue(),
108 MakePointerChecker<VhtConfiguration>())
109 .AddAttribute("HeConfiguration",
110 "The HeConfiguration object.",
111 PointerValue(),
113 MakePointerChecker<HeConfiguration>())
114 .AddAttribute("EhtConfiguration",
115 "The EhtConfiguration object.",
116 PointerValue(),
118 MakePointerChecker<EhtConfiguration>());
119 return tid;
120}
121
123 : m_standard(WIFI_STANDARD_UNSPECIFIED),
124 m_configComplete(false)
125{
127}
128
130{
132}
133
134void
136{
138 m_node = nullptr;
139 if (m_mac)
140 {
141 m_mac->Dispose();
142 m_mac = nullptr;
143 }
144 for (auto& phy : m_phys)
145 {
146 if (phy)
147 {
148 phy->Dispose();
149 phy = nullptr;
150 }
151 }
152 m_phys.clear();
153 for (auto& stationManager : m_stationManagers)
154 {
155 if (stationManager)
156 {
157 stationManager->Dispose();
158 stationManager = nullptr;
159 }
160 }
161 m_stationManagers.clear();
163 {
164 m_htConfiguration->Dispose();
165 m_htConfiguration = nullptr;
166 }
168 {
170 m_vhtConfiguration = nullptr;
171 }
173 {
174 m_heConfiguration->Dispose();
175 m_heConfiguration = nullptr;
176 }
178 {
179 m_ehtConfiguration->Dispose();
180 m_ehtConfiguration = nullptr;
181 }
183}
184
185void
187{
189
190 for (const auto& phy : m_phys)
191 {
192 if (phy)
193 {
194 phy->Initialize();
195 }
196 }
197 if (m_mac)
198 {
199 m_mac->Initialize();
200 }
201 for (const auto& stationManager : m_stationManagers)
202 {
203 if (stationManager)
204 {
205 stationManager->Initialize();
206 }
207 }
209}
210
211void
213{
214 if (!m_mac || m_phys.empty() || m_stationManagers.empty() || !m_node || m_configComplete)
215 {
216 return;
217 }
218 NS_ABORT_IF(m_phys.size() != m_stationManagers.size());
224 for (std::size_t linkId = 0; linkId < m_stationManagers.size(); linkId++)
225 {
226 m_stationManagers.at(linkId)->SetupPhy(m_phys.at(linkId));
227 m_stationManagers.at(linkId)->SetupMac(m_mac);
228 }
229 m_configComplete = true;
230}
231
232void
234{
235 NS_ABORT_MSG_IF(m_standard != WIFI_STANDARD_UNSPECIFIED, "Wifi standard already set");
236 m_standard = standard;
237}
238
241{
242 return m_standard;
243}
244
245void
247{
248 m_mac = mac;
250}
251
252void
254{
255 m_phys.clear();
256 m_phys.push_back(phy);
257 phy->SetPhyId(0);
258 m_linkUp = true;
260}
261
262void
263WifiNetDevice::SetPhys(const std::vector<Ptr<WifiPhy>>& phys)
264{
265 NS_ABORT_MSG_IF(phys.size() > 1 && !m_ehtConfiguration,
266 "Multiple PHYs only allowed for 11be multi-link devices");
267 m_phys = phys;
268 for (std::size_t id = 0; id < phys.size(); ++id)
269 {
270 m_phys.at(id)->SetPhyId(id);
271 }
272 m_linkUp = true;
274}
275
276void
278{
279 m_stationManagers.clear();
280 m_stationManagers.push_back(manager);
282}
283
284void
286{
287 NS_ABORT_MSG_IF(managers.size() > 1 && !m_ehtConfiguration,
288 "Multiple remote station managers only allowed for 11be multi-link devices");
289 m_stationManagers = managers;
291}
292
295{
296 return m_mac;
297}
298
301{
303}
304
306WifiNetDevice::GetPhy(uint8_t i) const
307{
308 NS_ASSERT(i < GetPhys().size());
309 return GetPhys().at(i);
310}
311
312const std::vector<Ptr<WifiPhy>>&
314{
315 return m_phys;
316}
317
318uint8_t
320{
321 return GetPhys().size();
322}
323
326{
327 return GetRemoteStationManager(0);
328}
329
332{
333 NS_ASSERT(linkId < GetRemoteStationManagers().size());
334 return GetRemoteStationManagers().at(linkId);
335}
336
337const std::vector<Ptr<WifiRemoteStationManager>>&
339{
340 return m_stationManagers;
341}
342
343uint8_t
345{
346 return GetRemoteStationManagers().size();
347}
348
349void
351{
352 m_ifIndex = index;
353}
354
357{
358 return m_ifIndex;
359}
360
363{
364 for (uint8_t i = 1; i < GetNPhys(); i++)
365 {
366 if (GetPhy(i)->GetChannel() != GetPhy(i - 1)->GetChannel())
367 {
368 NS_ABORT_MSG("Do not call WifiNetDevice::GetChannel() when using multiple channels");
369 }
370 }
371
372 return m_phys[SINGLE_LINK_OP_ID]->GetChannel();
373}
374
375void
377{
379}
380
383{
384 Ptr<StaWifiMac> staMac;
385 std::set<uint8_t> linkIds;
386
387 /**
388 * Normally, the MAC address that the network device has to advertise to upper layers is
389 * the MLD address, if this device is an MLD, or the unique MAC address, otherwise.
390 * Advertising the MAC address returned by WifiMac::GetAddress() is therefore the right
391 * thing to do in both cases. However, there is an exception: if this device is a non-AP MLD
392 * associated with a single link AP (hence, no ML setup was done), we need to advertise the
393 * MAC address of the link used to communicate with the AP. In fact, if we advertised the
394 * MLD address, the AP could not forward a frame to us because it would not recognize our
395 * MLD address as the MAC address of an associated station.
396 */
397
398 // Handle the exception first
399 if (m_mac->GetTypeOfStation() == STA &&
400 (staMac = StaticCast<StaWifiMac>(m_mac))->IsAssociated() && m_mac->GetNLinks() > 1 &&
401 (linkIds = staMac->GetSetupLinkIds()).size() == 1 &&
402 !m_mac->GetWifiRemoteStationManager(*linkIds.begin())
403 ->GetMldAddress(m_mac->GetBssid(*linkIds.begin())))
404 {
405 return m_mac->GetFrameExchangeManager(*linkIds.begin())->GetAddress();
406 }
407
408 return m_mac->GetAddress();
409}
410
411bool
412WifiNetDevice::SetMtu(const uint16_t mtu)
413{
415 {
416 return false;
417 }
418 m_mtu = mtu;
419 return true;
420}
421
422uint16_t
424{
425 return m_mtu;
426}
427
428bool
430{
431 return !m_phys.empty() && m_linkUp;
432}
433
434void
436{
438}
439
440bool
442{
443 return true;
444}
445
448{
450}
451
452bool
454{
455 return true;
456}
457
460{
461 return Mac48Address::GetMulticast(multicastGroup);
462}
463
466{
467 return Mac48Address::GetMulticast(addr);
468}
469
470bool
472{
473 return false;
474}
475
476bool
478{
479 return false;
480}
481
482bool
483WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
484{
485 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
486 return DoSend(packet, std::nullopt, dest, protocolNumber);
487}
488
491{
492 return m_node;
493}
494
495void
497{
498 m_node = node;
500}
501
502bool
504{
505 return true;
506}
507
508void
510{
511 m_forwardUp = cb;
512}
513
514void
516{
517 NS_LOG_FUNCTION(this << packet << from << to);
518 LlcSnapHeader llc;
520 if (to.IsBroadcast())
521 {
523 }
524 else if (to.IsGroup())
525 {
527 }
528 else if (to == GetAddress())
529 {
531 }
532 else
533 {
535 }
536
537 Ptr<Packet> copy = packet->Copy();
538 if (type != NetDevice::PACKET_OTHERHOST)
539 {
540 m_mac->NotifyRx(packet);
541 copy->RemoveHeader(llc);
542 m_forwardUp(this, copy, llc.GetType(), from);
543 }
544 else
545 {
546 copy->RemoveHeader(llc);
547 }
548
549 if (!m_promiscRx.IsNull())
550 {
551 m_mac->NotifyPromiscRx(copy);
552 m_promiscRx(this, copy, llc.GetType(), from, to, type);
553 }
554}
555
556void
558{
559 m_linkUp = true;
561}
562
563void
565{
566 m_linkUp = false;
568}
569
570bool
572 const Address& source,
573 const Address& dest,
574 uint16_t protocolNumber)
575{
576 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
577 return DoSend(packet, source, dest, protocolNumber);
578}
579
580bool
582 std::optional<Address> source,
583 const Address& dest,
584 uint16_t protocolNumber)
585{
586 NS_LOG_FUNCTION(this << packet << dest << protocolNumber << source.value_or(Address()));
587
588 if (source)
589 {
591 *source << " is not compatible with a Mac48Address");
592 }
594 dest << " is not compatible with a Mac48Address");
595
596 auto realTo = Mac48Address::ConvertFrom(dest);
597
598 LlcSnapHeader llc;
599 llc.SetType(protocolNumber);
600 packet->AddHeader(llc);
601
602 m_mac->NotifyTx(packet);
603 if (source)
604 {
605 auto realFrom = Mac48Address::ConvertFrom(*source);
606 m_mac->Enqueue(packet, realTo, realFrom);
607 }
608 else
609 {
610 m_mac->Enqueue(packet, realTo);
611 }
612
613 return true;
614}
615
616void
618{
619 m_promiscRx = cb;
620 m_mac->SetPromisc();
621}
622
623bool
625{
626 return m_mac->SupportsSendFrom();
627}
628
629void
631{
632 m_htConfiguration = htConfiguration;
633}
634
637{
638 return (m_standard >= WIFI_STANDARD_80211n ? m_htConfiguration : nullptr);
639}
640
641void
643{
644 m_vhtConfiguration = vhtConfiguration;
645}
646
649{
651}
652
653void
655{
656 m_heConfiguration = heConfiguration;
657}
658
661{
662 return (m_standard >= WIFI_STANDARD_80211ax ? m_heConfiguration : nullptr);
663}
664
665void
667{
668 m_ehtConfiguration = ehtConfiguration;
669}
670
673{
675}
676
677} // namespace ns3
a polymophic address class
Definition: address.h:101
Callback template class.
Definition: callback.h:438
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Describes an IPv6 address.
Definition: ipv6-address.h:49
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
void SetType(uint16_t type)
Set the Ethertype.
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static bool IsMatchingType(const Address &address)
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
bool IsBroadcast() const
Network layer to device interface.
Definition: net-device.h:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:307
@ PACKET_BROADCAST
Packet addressed to all.
Definition: net-device.h:303
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition: net-device.h:305
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:214
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:451
void Dispose()
Dispose of this Object.
Definition: object.cc:258
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition: type-id.h:75
Hold an unsigned integer type.
Definition: uinteger.h:45
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:864
Mac48Address GetBssid(uint8_t linkId) const
Definition: wifi-mac.cc:478
TypeOfStation GetTypeOfStation() const
Return the type of station.
Definition: wifi-mac.cc:422
virtual void SetAddress(Mac48Address address)
Definition: wifi-mac.cc:445
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:933
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &stationManagers)
Definition: wifi-mac.cc:883
void NotifyPromiscRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:613
void NotifyTx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:595
virtual void Enqueue(Ptr< Packet > packet, Mac48Address to, Mac48Address from)
Definition: wifi-mac.cc:1479
void NotifyRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:607
void SetForwardUpCallback(ForwardUpCallback upCallback)
Definition: wifi-mac.cc:1284
virtual bool SupportsSendFrom() const
Definition: wifi-mac.cc:1278
void SetLinkDownCallback(Callback< void > linkDown)
Definition: wifi-mac.cc:1298
void SetPromisc()
Sets the interface in promiscuous mode.
Definition: wifi-mac.cc:484
virtual void SetLinkUpCallback(Callback< void > linkUp)
Definition: wifi-mac.cc:1291
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:906
Mac48Address GetAddress() const
Definition: wifi-mac.cc:452
virtual void SetWifiPhys(const std::vector< Ptr< WifiPhy > > &phys)
Definition: wifi-mac.cc:1146
Hold together all Wifi-related objects.
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Receive a packet from the lower layer and pass the packet up the stack.
static TypeId GetTypeId()
Get the type ID.
bool NeedsArp() const override
bool SupportsSendFrom() const override
void SetMac(const Ptr< WifiMac > mac)
Ptr< HtConfiguration > m_htConfiguration
the HtConfiguration
bool IsBroadcast() const override
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
void LinkDown()
Set that the link is down (i.e.
Ptr< EhtConfiguration > m_ehtConfiguration
the EhtConfiguration
virtual const std::vector< Ptr< WifiPhy > > & GetPhys() const
void SetPhys(const std::vector< Ptr< WifiPhy > > &phys)
void SetHeConfiguration(Ptr< HeConfiguration > heConfiguration)
void SetHtConfiguration(Ptr< HtConfiguration > htConfiguration)
Address GetBroadcast() const override
std::vector< Ptr< WifiPhy > > m_phys
the phy objects
bool SetMtu(const uint16_t mtu) override
virtual const std::vector< Ptr< WifiRemoteStationManager > > & GetRemoteStationManagers() const
bool IsBridge() const override
Return true if the net device is acting as a bridge.
Ptr< WifiMac > GetMac() const
uint32_t m_ifIndex
IF index.
Ptr< VhtConfiguration > m_vhtConfiguration
the VhtConfiguration
Ptr< VhtConfiguration > GetVhtConfiguration() const
bool m_configComplete
configuration complete
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
void SetIfIndex(const uint32_t index) override
NetDevice::ReceiveCallback m_forwardUp
forward up callback
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Ptr< HeConfiguration > m_heConfiguration
the HeConfiguration
Ptr< EhtConfiguration > GetEhtConfiguration() const
bool IsMulticast() const override
void DoDispose() override
Destructor implementation.
uint8_t GetNRemoteStationManagers() const
void SetVhtConfiguration(Ptr< VhtConfiguration > vhtConfiguration)
void DoInitialize() override
Initialize() implementation.
NetDevice::PromiscReceiveCallback m_promiscRx
promiscuous receive callback
TracedCallback m_linkChanges
link change callback
Ptr< HtConfiguration > GetHtConfiguration() const
void SetRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
Ptr< Channel > GetChannel() const override
WifiStandard GetStandard() const
Get the Wifi standard.
void SetNode(const Ptr< Node > node) override
void SetRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &managers)
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
uint8_t GetNPhys() const
bool IsLinkUp() const override
std::vector< Ptr< WifiRemoteStationManager > > m_stationManagers
the station managers
Ptr< HeConfiguration > GetHeConfiguration() const
void SetAddress(Address address) override
Set the address of this interface.
Ptr< WifiRemoteStationManager > GetRemoteStationManager() const
void SetStandard(WifiStandard standard)
Set the Wifi standard.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
Ptr< Node > m_node
the node
void SetEhtConfiguration(Ptr< EhtConfiguration > ehtConfiguration)
WifiStandard m_standard
Wifi standard.
Ptr< WifiPhy > GetPhy() const
uint32_t GetIfIndex() const override
void SetPhy(const Ptr< WifiPhy > phy)
Ptr< WifiMac > m_mac
the MAC
void CompleteConfig()
Complete the configuration of this Wi-Fi device by connecting all lower components (e....
bool DoSend(Ptr< Packet > packet, std::optional< Address > source, const Address &dest, uint16_t protocolNumber)
Send a packet.
Address GetAddress() const override
void AddLinkChangeCallback(Callback< void > callback) override
uint16_t GetMtu() const override
void LinkUp()
Set that the link is up.
Ptr< Node > GetNode() const override
virtual Ptr< Channel > GetChannel() const =0
Return the Channel this WifiPhy is connected to.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
@ STA
Definition: wifi-mac.h:65
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_STANDARD_80211ac
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
Definition: wifi-utils.h:192
static const uint16_t MAX_MSDU_SIZE
This value conforms to the 802.11 specification.
static const uint16_t LLC_SNAP_HEADER_LENGTH
The length in octets of the LLC/SNAP header.