2014-12-01 5 views
0

NDIS 6에서 필터 드라이버를 구축 중입니다. NET_BUFFER의 뒷면에 데이터를 추가하고 싶습니다. 데이터를 추가하려면 NdisAllocateMdl API를 통해 MDL을 할당했습니다. 이제이 MDL을 기존 MDL 체인에 추가하는 래퍼가 있는지 알고 싶습니다.NDIS 6에서 NdisChainBufferAtBack 대체

그렇지 않은 경우 마지막 MDL의 Next 포인터가 새 할당 MDL을 가리 키도록하는 것이 맞습니까? 그렇게 할 수 있었습니까? 또한 추가 된 MDL을 인식하도록 변경해야하는 NET_BUFFER의 필드는 무엇입니까?

답변

1

NET_BUFFER의 실제 패킷 페이로드는 전체 MDL 체인의 페이로드의 하위 집합입니다. 패킷이 MDL 체인의 시작 부분에서 시작되지 않을 수 있으며 패킷이 MDL 체인의 끝에서 끝나지 않을 수 있습니다.

따라서 가장 일반적인 경우에는 새 MDL을 추가하기 전에 실제로 NET_BUFFER 끝에서 일부 MDL을 제거해야합니다. 나 구체적인 예를 들어 보겠습니다 :이 예에서는 그래서

NET_BUFFER 
    * DataOffset=300 bytes 
    * DataLength=200 bytes 
    * MdlChain=[200 bytes]->[200 bytes]->[300 bytes]->[200 bytes] 

NET_BUFFER 포인트를 거기에 4 MDLs과 MDL 체인. 이제 ASCII 아트의 버퍼를 보자

0  100 200 300 400 500 600 700 800 900 
    |  |  |  |  |  |  |  |  |  | 

    [ First MDL ][ Second MDL ][ Third MDL  ][ Fourth MDL ] 


    ↑    ↑  [ Packet ]       ↑ 
    |    |            | 
    |    |  ↑   ↑       | 
    |    |  |   |       | 
MdlChain   | DataOffset DataLength    End-of-MDL-chain 
        | 
       CurrentMdl 

이루면서 다이어그램이 도시 실제 페이로드 패킷은 상기 제 & 제 MDLs 분산된다. 첫 번째 & 네 번째 MDL은 모두 무시됩니다. 당신이 패킷에 데이터를 추가하려는 경우, 당신은 다음을 수행해야합니다

  1. 는 MDL의 버퍼의 마지막 바이트 논리 패킷 버퍼의 일부가 아닌 MDL 체인의 끝에서 모든 MDLs를 제거합니다. 위의 예에서 세 번째 MDL 인 두 번째 &을 모두 제거합니다.
  2. 위의 1 단계에서 삭제 한 실제 패킷 페이로드와 데이터를 저장할만큼 큰 새 버퍼를 할당하십시오. (이 예에서는 세 번째 MDL에서 처음 100 바이트를 보유하기 위해 추가 100 바이트를 할당해야합니다.)
  3. 새 MDL을 체인 끝에 연결하십시오.
  4. 증분 NET_BUFFER::DataLength.
  5. 패킷을 NDIS에 보냅니다. 여기

는 패킷 3 단계 완료 후 어떻게 보일지도있다 :

0  100 200 300 400 500 600 700 800 900 
    |  |  |  |  |  |  |  |  |  | 

    [ First MDL ][ Second MDL ][ Your MDL ] 


    ↑    ↑  [ Packet ]  ↑ 
    |    |       | 
    |    |  ↑   ↑  | 
    |    |  |   |  | 
MdlChain   | DataOffset DataLength | 
        |       | 
       CurrentMdl    End-of-MDL-chain 

그런 후 단계 # 4 : 패킷이 드라이버로 다시 완료

0  100 200 300 400 500 600 700 800 900 
    |  |  |  |  |  |  |  |  |  | 

    [ First MDL ][ Second MDL ][ Your MDL ] 


    ↑    ↑  [ Packet   ] 
    |    | 
    |    |  ↑     ↑ 
    |    |  |     | 
MdlChain   | DataOffset   DataLength    
        |       | 
       CurrentMdl    End-of-MDL-chain 

이전에 수정 한 사항을 실행 취소해야합니다.

  1. 감소 DataLength.
  2. 추가 한 MDL을 제거하십시오.
  3. 추가 한 MDL을 해제하십시오.
  4. 제거한 원본 MDL을 복원하십시오.
+0

감사합니다. jeff.내가 여분의 바이트 (24 홀수) 및 현재 패킷 끝에있는 데이터를 보내고받을 때 LWF 드라이버를 만들고 있습니다. 위에서 언급 한 방법이 그렇게하는 가장 정확하고 효율적인 방법입니까? – user2963521

+0

어떻게 안전하게 마지막으로 mdl의 내용을 할당 된 mdl에 복사 할 수 있습니까? RtlCopyMemory가 작동해야합니까? – user2963521

+0

패킷 끝에 데이터를 추가하는 유일한 방법입니다. 만약 당신이 미니 포트를 가지고 있다면, 마지막 MDL의 끝 부분에 24 바이트의 사용되지 않은 공간을 남겨 두는 것에 동의하게 할 수 있습니다. 먼저 MmGetSystemAddressForMdlSafe를 사용하면 RtlCopyMemory가 좋습니다. –