Detecting 802.1p Priority Tags

Consider a case where a network application calls Windows QoS APIs to add a layer-2 IEEE 802.1Q UserPriority tag (almost always referred to as 802.1p) to outgoing traffic. Ascertaining whether the tag actually got added to an outgoing packet is not as simple as it seems due to the nature of how the Windows network stack is designed, and how framing actually occurs. From an internal implementation perspective, The QoS Packet Scheduler (Pacer.sys in Vista/2008 Server, and Psched.sys in XP/2003 Server) in the network stack merely updates an out-of-band structure (not the actual formed packet) that an 802.1Q UserPriority tag should be added. The specific NDIS structure is NDIS_NET_BUFFER_LIST_8021Q_INFO, which contains member variables for both VlanID and UserPriority, and is passed to the NDIS miniport driver for implementing both priority tagging (UserPriority) and VLAN (VlanId). It is up to the NDIS miniport driver to actually insert the 802.1Q tag into the frame based on these values before transmitting on the wire. A miniport driver will only insert this tag if the feature is supported and enabled in the advanced properties of the NIC driver; typically layer-2 priority tagging is disabled by default.

From a network stack layering perspective, it’s important to understand that Pacer.sys is an NDIS Lightweight Filter (LWF) driver, and will always be inserted above a miniport driver, which will always be the lowest network software in the stack because it communicates directly with the NIC hardware. Also note that network sniffing applications like NetMon and WireShark are also network stack filters, and will always be inserted above the miniport driver. This is important knowledge because it should be clear that taking a network sniff of traffic on the sending PC will never show the tag in a packet (because the tag gets added below the sniffing software). Also, the QoS Packet Scheduler can’t know for absolute certainty whether the miniport driver added the tag to the outgoing packet. 

What about trying to do a network sniff on the receiving PC? Good question, but also will show the layer-2 tag not present in packets. The reason for this is NDIS developer documentation clearly states that miniport drivers must strip the tag when received, and populate the NDIS_NET_BUFFER_LIST_8021Q_INFO UserPriority and VlanId fields with the values in the tag. This out-of-band structure can then be used by NDIS filter drivers higher up in the stack for implementing these features. The functional reason for stripping the layer-2 tag is because Tcpip.sys will drop any received packet that contains this tag. Therefore, if a misbehaving miniport driver does not strip the tag, the packet will never be received by the user-mode application because it will be dropped internally.

In conclusion:

  • A network sniffing app on the sending PC will never see a tag

  • A network sniffing app on the receiving PC will never see a tag

    • Unless the miniport driver is misbehaving, which will result in dropped packets

  • Monitoring tagged packets from intermediate network elements (such as a switch) is hard if at all possible

    • Perhaps a clever SNMP counter could be used, but would depend on the device manufacturer

If you have not came to this conclusion already, the only way to determine whether a layer-2 tag got added on the sending PC and/or received by the receiving PC is to monitor the NDIS_NET_BUFFER_LIST_8021Q_INFO.UserPriority field. Stay tuned for a follow-up post which describes how to do this.

— Gabe Frost

Comments (12)

  1. Rich Reynolds says:


    Interesting stuff.  I need to implement what’s coming in your next blog.

    In your description you mention that the Pacer.sys is always inserted directly above the miniport driver, however I cannot determine from your blog if this was also the case for the Psched.sys in XP.  

    My reason for asking is that I have been able to see 802.1p tagging in a Packet Capture on a Windows XP machine while running a WinPCap based tool. I admit this was on packets between different PCs.

    Does this mean that:

    1) I have a misbehaving miniport driver?

    2) The "WinPCap.sys" is inserted between the miniport driver and the Psched.sys on XP?

    3) It is possible to see packet tagging on packets between other PCs?



  2. wndpteam says:

    Hi Rich,

    LWF drivers are new to Vista/2008 Server (NDIS-6), but are designed to replace intermediate (IM) drivers (NDIS-5), which are layered similarly to LWF drivers. Psched.sys is an IM driver, and therefore will always be layered above a miniport driver in the stack.

    Regarding winpcap.sys, after a quick search, the following turns up: It turns out this driver is implemented as an NDIS protocol driver (like the built-in tcpip.sys driver). Protocol drivers are layered above IM or LWF drivers, and are subject to the same description in my post regarding layer-2 tags. Any number of protocol drivers can register to receive packets on send or receive from NDIS (there are caveats), this is how winpcap sees the traffic from apps. Interestingly, because Pacer.sys (or Psched.sys) is the Windows stack authority for populating the 1Q structure described in my post, the protocol driver above (winpcap.sys) would not see the desired tag value on the send path, only on receive. As such, my hunch is you saw the tag value on the receiving PC? If so, that value either was reported by winpacap from the received 1Q structure, or the underlying miniport misbehaved and didn’t strip the tag. If the latter was the case (tag wasn’t stripped), when tcpip.sys receives the tagged packet, it will be discarded and the winsock application which would receive it will not receive it.

    I don’t see how winpcap could see a tag value (or the desired tag value) on the send path. If you can confirm it does, I can investigate further. I’m betting you saw the tag value on receive, which was either reported from 1Q structure, or actual tag from misbehaving miniport.

    Hope that helps.

    – Gabe

  3. wndpteam says:


    On another note, can you describe the scenario for which you need to know that an 802.1p tag exists in a frame, and whether that is on send and/or receive? Is this a debugging tool or tracing application? Thanks!

    – Gabe

  4. Rich Reynolds says:


    Thanks for the responses, I’ll recreate my test where I saw tags and let you know what I find.

    To answer your question about why I want to know about the tags; we develop VoIP test applications.   In one scenario, we have a VoIP test-point which needs to confirm that the incoming stream is correctly tagged.  In a second scenario, we monitor passing VoIP streams and I need to add the capability to check the tagging of these streams.  I both cases I am interested in knowing the tag value of received packets.


  5. Rich Reynolds says:

    Hi Gabe,

    I feel like a fraud.  I was sure when I first added VLAN tagging to my VoIP client, some 3 years ago, I was able to see the VLAN tags on my old dev machine.  After dusting it off, installing Windows, I can’t recreate the trace.

    Again thanks for the clarification on NDIS layering in XP.  And the blogs you and Hemant have written about Detecting 802.1p tags. You’ve saved me a lot of head scratching.


  6. wndpteam says:

    No problem Rich, I greatly appreciate your feedback. Keep watching this blog for more in-depth information about QoS capabilities, as well as tools for validation. We’re always eager to hear how we’re doing from a community aspect.

  7. Bob says:

    Would it be possible to connect the sender and receiver through a software bridge (two network connections bridged in the OS) and sniff the bridge to see the QoS tag?

    ______        _______       _______

    | SUT   |<–>| Bridge |<–>| Client  |

    ———-       ———–        ———–

  8. wndpteam says:

    Hi Bob,

    Wow, that’s creative. Great thought, but that unfortunately won’t work. Bridging two interfaces within Windows won’t buy you anything because the sent packet doesn’t actually go all the way down to the miniport (which would add the tag), then back up.

    — Gabe

  9. William says:

    Hi Gabe,  

    Sorry to step back to XP, 2000, but I am wondering how the NDIS IM driver(5.1, 4.0) is layed in the network driver stack?  Is the Psched.sys sitting below the NDIS IM driver or on the top of IM driver?  

    I am facing a tough issue.  We have a NDIS 4.0 IM driver that applies a custom TOS/DSCP value to our kernel socket for the VoIP traffic by modifying the TOS byte directly before sending to the miniport.  I know it is not the way to do the QoS but it seems to be working in 2000, XP and 2003 for our own VoIP app and it was determined to implement this way long time ago.    

    Now I am asked to enhance this IM driver to support 802.1p.  Since I am not using the Vista, NDIS_PER_PACKET_INFO_FROM_PACKET(_Packet, Ieee8021pPriority) seems to the point to get/set 802.1p priority value.    Do you think if it is possible to apply the 802.1p tag by changing this Ieee8021pPriority OOB info in NDIS IM driver providing I enable the 802.1p on the NIC and enable the Packet Scheduler(do I really need it since I am not going to use it anyway?).   I know it should be viable to implement this with TC API(even with any 802.1p value, right?) but then I believe it would affect our current TOS implementation and I pretty much need to redo everything.  So I am little hesitate to go for this if our existing IM driver can do the job.  



  10. ajean says:


    I met this same question a few days ago.As Bob mentioned above, I have implemented a software bridge in Windows2003,and I can now see 802.1q tag with sniffer.To my puzzled,sniffer cann’t see 802.1q tag in Windows2000,only work fine in Windows2003,I am not sure whether there are some kernel differences between 2000 and 2003.


  11. Adrien says:

    Windows 2k didn’t support 802.1 so I guess the protocol isn’t enabling the option in the miniport (default is off) by sending an OID even if the miniport supported it.

  12. Darshan Laheri says:


    Will I be able to see the 802.1p values with the help of network analyzer (Finisar for example) installed between teo hosts?