Cisco AnyConnect VPN compatibility woes

Hi,

Firstly I’d like to say congratulations on the migration from legacy OSRONLINE!

I have recently inherited a WFP filter driver which redirects dns at the FWPS_LAYER_OUTBOUND_TRANSPORT_V4 layer into a usermode service and then NAT’s the response back as if it comes from the ‘original destination’.
The latter part is necessary as Windows DNS Service appears to throw its toys out of the pram unless the dns response comes from the same ip as the dns request.

The flow of the driver boils down to:

  1. Detect and ignore if previous redirections have occurred.
  2. If it’s remote port 53, absorb it and FwpsInjectTransportSendAsync it to usermode on port 55555
  3. It it’s remote port 53 but comes from our usermode, let it out
  4. If it’s local port 55555 then our usermode is trying to send back to the original application, absorb it and FwpsInjectTransportSendAsync back to the original destination

Visually (if this helps) it looks like:

  • |original_application :x| --(2)-> |55555: our_usermode: 55557| --(3)-> |53: dns_server|
  • |original_application :x| <-(4)-- |55555: our_usermode: 55557| <------ |53: dns_server|

Everything works like a dream until Cisco AnyConnect VPN is connected.
Then during (4) the nBufList->Status inside the CompletionFunction of FwpsInjectTransportSendAsync will fail with error code NDIS_STATUS_DATA_NOT_ACCEPTED.

The framework variables for a working (4) with no Cisco are:

—Layer: FWPS_LAYER_OUTBOUND_TRANSPORT_V4—
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_PROTOCOL: 0x11
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_ADDRESS: 172.16.80.129
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_ADDRESS_TYPE: 0x1
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_REMOTE_ADDRESS: 172.16.80.129
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_PORT: 0xd903
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_REMOTE_PORT: 0xdf32
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_INTERFACE: 0x6008000000000
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_INTERFACE_INDEX: 0x9
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_SUB_INTERFACE_INDEX: 0
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_DESTINATION_ADDRESS_TYPE: 0x1
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_FLAGS: 0x1
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_INTERFACE_TYPE: 0x6
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_TUNNEL_TYPE: 0
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_PROFILE_ID: 0x1

FWPS_METADATA_FIELD_FLOW_HANDLE=50
FWPS_METADATA_FIELD_SYSTEM_FLAGS=1
FWPS_METADATA_FIELD_RESERVED=3F3360E8
FWPS_METADATA_FIELD_TRANSPORT_HEADER_SIZE=8
FWPS_METADATA_FIELD_COMPARTMENT_ID=1
FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE=60

The framework variables for a failing (4) with Cisco are:

—Layer: FWPS_LAYER_OUTBOUND_TRANSPORT_V4—
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_PROTOCOL: 0x11
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_ADDRESS: 172.16.20.6
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_ADDRESS_TYPE: 0x1
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_REMOTE_ADDRESS: 172.16.20.6
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_PORT: 0xd903
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_REMOTE_PORT: 0xf8a6
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_LOCAL_INTERFACE: 0x6008004000000
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_INTERFACE_INDEX: 0x6
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_SUB_INTERFACE_INDEX: 0
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_IP_DESTINATION_ADDRESS_TYPE: 0x1
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_FLAGS: 0x1
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_INTERFACE_TYPE: 0x6
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_TUNNEL_TYPE: 0
FWPS_FIELD_OUTBOUND_TRANSPORT_V4_PROFILE_ID: 0x2

FWPS_METADATA_FIELD_FLOW_HANDLE=21B
FWPS_METADATA_FIELD_SYSTEM_FLAGS=1
FWPS_METADATA_FIELD_RESERVED=3EEEC0E8
FWPS_METADATA_FIELD_TRANSPORT_HEADER_SIZE=8
FWPS_METADATA_FIELD_COMPARTMENT_ID=1
FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE=1DF

A few points to note:

  • I can’t see anything obvious in Windows Message Analyser
  • I can’t see anything obvious at the TRANSPORT IN/OUT DISCARD layers
  • Our Filters/Callouts etc are all on their own sub layer with automatic weighting (FWP_EMPTY)

Some questions:

  1. How do I follow up on an error like NDIS_STATUS_DATA_NOT_ACCEPTED? Is there more information logged somewhere?
  2. I suspect they’ve got an NDIS driver as part of their product (both of which I know very little about), is there some mechanism to print a NDIS driver stack or other useful tools?

Thanks,
Jason

Firstly I’d like to say congratulations on the migration from legacy OSRONLINE!

Thanks! I won’t lie… it was tough. But with a lot of planning, and the patience and he,p,of the community, we managed to make it happen.

Peter

Update: I’ve managed to get everything working as desired by moving from Send to Receive Injection. Not exactly sure why this resolves it, but it has.
Jason