NDIS 드라이버 공부 내용 정리합니다.

http://www.htsns.com 를 참조해서 작성 되는 내용이므로 정확한 내용을 원하시는 분은 참고하시길 바랍니다.

 

드라이버를 공부하시려면 꼭 기억해야 될 내용이 있습니다. 일반적인 드라이버를 짤 때 우리는 아래 그림과 같은 문장을 사용합니다.

이 그림이 뭘 의미 하는 걸까요? 바로 콜백함수의 등록입니다. NDIS 드라이버도 마찬가지지만 콜백을 잘 끼워 맞추기만 하면 됩니다.

콜백의 기능, 전체적인 콜백 호출 흐름, 각 콜백 안에서 호출해야 할 API들을 파악했다면 NDIS의 절반 이상을 이해한 것이라고 합니다. (참조: http://xeraph.com/4787739)

 

 

IntermediateDriver의 초기화는 처음 공부하는 저에게는 상당히 어렵더군요. (사실 아직도 이해하는 중입니다.)

이 글에서는 일반적인 드라이버의 DriverEntry와 Intermediate 드라이버의 DriverEntry를 비교하겠습니다. 그래서 어떻게 다른지 개략적으로 설명하고 다음 글에서부터 본격적으로 분석을 해보도록 하겠습니다.

Intermediate 드라이버의 예제는 DDK 폴더 안의 passthru라는 예제가 있습니다. 그 예제를 기반으로 설명하겠습니다.

 

일반적인 드라이버의 경우 IoCreateDevice를 호출해서 드라이버를 생성하게 됩니다. 그 후 심볼릭(Symbolic) 링크를 만들고 MajorFunction(DDK WDM 문서 참조)의 콜백함수를 지정하는 것으로 넘어가게 됩니다.

 

 

하지만 NDIS 드라이버의 경우 많이 다릅니다. 우리가 작성하려고 하는 NDIS Intermediate Driver의 예를 들자면 여러 초기화 과정이 필요하게 됩니다.

passthru의 DriverEntry 함수를 보시면 크게 네 개의 초기화 단계(아래 그림 참조)로 나눌 수 있습니다.

또한, DDK 문서(참고: moltak.net: NDIS Driver 02) Intermediate Driver)에 MiniportXxx, ProtocolXxx함수를 노출시켜야 한다고 설명하고 있습니다.

그래서 NDIS의 초기화 단계는 Miniport, Protocol Driver의 콜백함수를 설정해야 합니다.

 

 

 

1. NdisMInitializeWrapper을 호출하고 NdisWapperHandle에서 리턴된 핸들을 지정한다.

2. 드라이버의 MiniportXxx 함수들을 등록하기 위해서 NdisIMRegisterLayeredMiniport를 호출하고 스텝 1에서 얻어진 핸들을 인자로 보낸다.

NdisMinitializeWrapper 함수를 호출해서 NDIS_HANDLE을 얻어 올 수 있습니다.(NdisWrapperHandle 변수)

그리고 이 변수를 이용해서 우리는 MiniportXxx와 ProtocolXxx를 노출 시켜줄 수 있습니다.

위 소스에서 MChars라는 변수에 여러 가지 콜백함수를 설정하고 있는 것을 볼 수 있습니다.

현재는 이것을 통해서 콜백을 등록하고 가장 아래 있는 NdisIMRegisterLayeredMiniport를 이용 MiniportXxx를 등록한다고만 아시면 됩니다. (자세한 설명은 다음 블로깅을 통해 하도록 하겠습니다.)

 

 

3. 만약 드라이버가 그 자신을 밑의 NDIS 드라이버에게 다음에 바인드 한다면 드라이버의 ProtocolXxx 함수들을 등록하기 위해서 NdisRegisterProtocol을 호출한다.

위 소스도 ProtocolXxx함수를 노출시키기 위해서 하는 것입니다. 각종 콜백함수를 등록하고 아래에 있는 NdisRegisterProtocol을 통해 인터미디엇 드라이버의 ProtocolXxx함수들을 노출시킵니다. 각 콜백함수의 내용은 복잡하고 역할은 아직 잘 모릅니다. (알아야 할게 너무 많네요ㅠㅠ)

 

 

4. 만약 드라이버가 MiniportXxx와 ProtocolXxx함수들 둘 다를 드러낸다면, 드라이버의 미니포트 하위경계와 프로토콜 상위경계에 대해서 NDIS 라이브러리를 형성하기 위해서 NdisIMAssociateMiniport를 호출한다.

우리는 MiniportXxx와 ProtocolXxx함수를 노출하길 원합니다. (노출하기 원하지 않다면 한 개의 핸들만 넣어도 되는 건지는 확실하지 않네요. ㅠㅠ)

NdisIMAssociateMiniport 함수는 NDIS에게 미니포트와 프로토콜을 위한 특정 lower와 upper 인터페이스들이 각각 같은 인터미디엇 드라이버에 속한다는 것을 알립니다.

 

 

여기까지 해서 DriverEntry에 대한 개략적인 설명이 끝났습니다. 원본 소스파일은 ddk\src\network\ndis\passthru\driver\passthru.c 파일을 참조하시기 바랍니다.

다음은 인터미디엇 드라이버의 DriverEntry에서 Miniport를 등록하는 부분을 더욱 세세하게 설명을 하도록 하겠습니다. 내용이 많아서 몇 챕터로 쪼개서 해야겠네요. 아무튼 모두들 즐공! 즐프! 하세요.

 

 

Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 02) Intermediate Driver  (0) 2010.05.06
NDIS Extending The PassThru IM Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18

NDIS 드라이버 공부 내용 정리합니다.

http://www.htsns.com 를 참조해서 작성 되는 내용이므로 정확한 내용을 원하시는 분은 참고하시길 바랍니다.

 

NDIS 드라이버는 Miniport, Intermediate, Protocol 타입의 네트워크 드라이버들을 제공합니다.

3타입의 네트워크 드라이버들이 어떤 역할을 하는지 차근차근 알아보도록 하겠습니다.

 

 

1. Miniport Driver

Miniport Driver(이하 미니포트 드라이버)는 두 가지 역할을 수행합니다.

그림에서 보시는 바와 같이 NIC(Network Interface Card)바로 위에 위치해 있습니다. 미니포트 드라이버는 NIC을 통해 데이터를 보내고 받는 것을 포함해서, NIC을 관리합니다. 또, Intermediate Driver(이하 인터미디엇 드라이버)와 같은 상위 레벨 드라이버들과 통신합니다.

 

미니포트 드라이버는 NDIS 라이브러리를 통해 NIC과 그리고 상위 레벨 드라이버들과 통신합니다. NDIS 라이브러리는 미니포트가 호출하는데 필요한 운영체제의 모든 시스템 함수들을 캡슐화하는 NdisXxx함수들을 익스포트 합니다. 미니포트 드라이버는 상위 레벨 드라이버들이 미니포트 드라이버에 접근하기 위해서 또는, 자기 자신을 위해서 NDIS가 호출하는 엔트리 포인트들(MiniportXxx 함수들)을 익스포트 해야 합니다. 송/수신 연산들(패킷을 보내고 받고 하는 것을 말하는 듯)은 미니포트 드라이버들과 NDIS 상위 레벨 드라이버들간에 상호 작용입니다.

 

- 전송 계층 드라이버가 전송하고자 하는 패킷들을 가지고 있을 때, 전송 계층 드라이버는 NDIS라이브러리에 의해 익스포트 되어지는 NdisXxx 함수를 호출합니다. NDIS는 그러고 나서 미니포트에 의해 익스포트된 적당한 MiniportXxx함수를 호출함으로써 미니포트에게 패킷을 전달합니다. 패킷을 받은 미니포트 드라이버는 적당한 NdisXxx함수들을 호출함으로써 전송을 위해 NIC에게 패킷을 포워드 합니다.

 

- NIC이 패킷을 수신할 때, NDIS 혹은 NIC의 미니포트에 의해 처리될 수 있는 하드웨어 인터럽트를 포스트 할 수 있습니다. NDIS는 적당한 MiniportXxx함수를 호출함으로써 NIC의 미니포트 드라이버에게 알립니다. 미니포트 드라이버는 NIC으로부터 데이터 전송을 설정하고 그리고나서 적당한 NdisXxx 함수를 호출함으로써 바인드된 상위레벨 드라이버들에게 수신된 패킷의 존재를 (Indicate)알립니다.

 

 

2. Intermediate Driver

 

드라이버 계층도에서 보면 인터미디엇 드라이버는 Protocol Driver(이하 프로토콜 드라이버)와 미니포트 드라이버들 사이에 위치합니다. 그래서 "위"의 프로토콜 드라이버와 "아래"의 미니포트 드라이버들과 통신을 수행해야 합니다.

 

- Lower Edge에서 인터미디엇 드라이버는 NDIS가 미니포트 드라이버와 통신하기 위해 호출하는 프로토콜 엔트리 포인트들(ProtocolXxx 함수들)을 노출합니다. 미니포트 드라이버가 인터미디엇 드라이버를 볼 때 인터미디엇 드라이버는 프로토콜 드라이버가 되는 것으로 나타납니다.

 

- Upper Edge에서 인터미디엇 드라이버는 NDIS가 프로토콜 드라이버와 통신하기 위해 호출하는 미니포트 엔트리 포인트들(MiniportXxx 함수들)을 노출합니다. 프로토콜드라이버가 인터미디엇 드라이버를 볼 때 인터미디엇 드라이버는 미니포트 드라이버가 되는 것으로 나타닙니다.

 

- 인터미디엇 드라이버 요약 정리: 인터미디엇 드라이버는 upper edge에서 MiniportXxx 함수들의 subset을 익스포트 합니다. 하지만 실제로 물리 NIC을 관리하지는 않습니다. (NIC의 관리는 Miniport Driver가 합니다.) 그 대신에, 인터미디엇 드라이버 위의 프로토콜들이 바인드 할 수 있는 하나, 혹은 그 이상의 가상 어댑터들을 익스포트 합니다. 그리고 프로토콜 드라이버들은 인터미디엇 드라이버에 의해 익스포트되어지는 가상 어댑터들이 물리 NIC이 되는 것으로 보이게 됩니다.

프로토콜 드라이버가 가상 어댑터(인터미디엇 드라이버가 익스포트 한)에 요구 혹은 패킷들을 보낼 때, 인터미디엇 드라이버는 이런 요청과 패킷을 아래 미니포트 드라이버에 전달하게 됩니다.

 

- 인터미디엇 드라이버는 일반적으로 다음과 같이 사용됩니다.

다른 네트워크의 사이를 변환하기 위해: 예를 들어, Ethernet과 Token Ring 전송 계층들과 ATM 미니포트 사이에 인터미디엇 드라비어의 함수는 Ehternet과 Token Ring 패킷들을 ATM패킷들로 맵하거나 그 반대로 맵합니다.

패킷들을 필터하기: 방화벽 같은 것을 만들 때 사용합니다.

하나 이상의 NIC과 관련해서 패킷 전송의 균형을 맞춘다: 패킷을 분산합니다.(??)

 

 

3. Protocol Driver

드라이버들의 NDIS 계층도에서 가장 위에 있는 프로토콜 드라이버는 TCP/IP혹은 IPX/SPX 스택과 같은 전송 프로토콜 스택을 실행하는 전송 계층 드라이버내에서 가장 낮은 레벨 드라이버로서 사용됩니다. 전송 계층 드라이버는 패킷들을 할당하며 어플리케이션이 보내는 데이터를 패킷에 복사하며, 또 이러한 패킷들을 NDIS 함수들을 호출함으로써 낮은 레벨 드라이버에게 보냅니다. 프로토콜 드라이버는 낮은 레벨 드라이버로부터 들어오는 패킷들을 수신하기 위해 프로토콜 인터페이스를 제공합니다. 전송 계층 드라이버는 수신된 데이터를 요청된 클라이언트 어플리케이션에 전송합니다.

 

Lower Edge에서 프로토콜 드라이버는 인터미디엇 드라이버들과 미니포트 NIC드라이버들에 인터페이스 합니다. 프로토콜 드라이버는 패킷들을 보내기 위해서 NdisXxx함수들을 호출하고, Lower 레벨 드라이버들에 의해 유지된 정보를 읽고 설정하고 운영체제 서비스들을 사용합니다. 프로토콜 드라이버는 NDIS가 수신한 패킷들을 위로 전송하기 위해서 그리고 Lower 드라이버들의 상태를 알기 위해, 혹은 자신의 목적을 위해 호출하는 엔트리 포인트들(ProtocolXxx 함수들)의 집합을 익스포트 합니다.

 

Upper Edge에서 전송 계층 프로토콜 드라이버는 프로토콜 스택에서 상위 레벨 드라이버에 대한 private 인터페이스를 갖게 됩니다.

 

 

4. 정리

위 그림은 이제까지 설명해왔던 내용을 알기 쉽게 나타내 주는 그림입니다. (제 개인적인 생각)

위 그림에서는 Intermediate Driver가 빠져 있습니다. 대신 Wrapper가 포함되어 있죠. 이 것을 보고 여러가지로 생각 할 수 있겠지만 오늘 공부한 내용을 토대로 생각해 본다면 Intermediate Driver는 단순히 Miniport Driver의 Wrapper로 생각할 수 있다는 것입니다. (Miniport <-> Intermediate <-> Protocol 의 관계를 생각해 보세요) Intermediate Driver를 Miniport에 대한 Wrapper로 생각한다면 이해하기가 더 쉽습니다. 어떤 요청이던지 저 방어망을 치고 있는 Wrapper를 뚫지 않고서는 Miniport에게 갈 수가 없습니다. 그리고 Wrapper는 Upper Edge에 대해서는 자신이 Miniport인 것처럼 행세 할 것이며 Lower Edge에 대해서는 Protocol인양 행세 할 것입니다.

다만 NIC과 Miniport Driver와의 관계는 좀 이상하긴 하지만 그거 빼고는 맞는 것 같습니다. (아하하하하하;;)

이 글에서 가장 중요한 것은… 바로 제 프로젝트를 완수 하려면 어떤 드라이버에서 해도 상관 없지만 보통 Intermediate Driver에서 수행한다는 것입니다. (사실 Miniport에서도 할 수 있고 Hook Driver를 만들어서도 할 수 있습니다.)

 

 

 

Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 03) Intermediate Driver 초기화  (0) 2010.05.09
NDIS Extending The PassThru IM Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
이 자료는 정말 마음에 드네요. (아직 다 보지는 못했지만)


Thomas F. Divine님과 James Antognini님이 작성한 문서입니다.
DDK를 깔면 예제로 깔리는 PassThru를 확장해서 설명해 놓으셨습니다.
처음 Intermediate(IM) Driver를 공부하려고 하면 정말... 어떻게 해야 할지 막막했습니다.
DDK 문서와 이 문서를 갖고 계속 공부를 해 나가야겠습니다.
그럼 모두 즐프하세요.


Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 03) Intermediate Driver 초기화  (0) 2010.05.09
NDIS Driver 02) Intermediate Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18

NDIS 드라이버 공부 내용 정리합니다.

http://www.htsns.com 를 참조해서 작성 되는 내용이므로 정확한 내용을 원하시는 분은 참고하시길 바랍니다.

 

Chapter1 네트워크 드라이버 디자인 가이드에 대한 로드맵

Windows2000(XP, 2003 포함)은 세가지 기본 타입의 커널 모드 네트워크 드라이버들을 제공합니다. 이 세가지 타입에 대해서 정확히는 아니더라도 대략적으로 알고 있어야 차후 드라이버를 작성할 때 선택해서 할 수 있을 것입니다. 그러니 세 개다 살펴 보도록 하겠습니다. 그 전에 먼저 Windows의 Network Layer 부 터 알아보도록 하겠습니다.

 

 

위에 보시는 것이 Windows의 Network Layer입니다.

[참조: http://subsub.windowstest.net/bbs/view.asp?tb=ndis&no=221 ]

 

보통 Network 드라이버를 짤 때 NDIS와 TDI를 사용하게 됩니다. 만약 TDI Filter를 개발한다면 얻을 수 있는 것은 IP, Port, Application Protocol(TCP 이후의 데이터)를 얻을 수 있으며 모니터링, 변조, 차단등을 할 수 있다고 합니다. NDIS Protocol Driver를 개발한다면 Ethernet Header, IP Header, TCP Header, App Protocol까지 모든 Raw Packet의 정보를 얻을 수 있다고 하네요. 하지만 직접적인 변조, 차단을 할 수 없다고 합니다. 그것을 하기 위해서는 NDIS Intermediate 드라이버나 NDIS Hook Driver 혹은 WFP(Windows Filtering Platform) 드라이버를 작성해야 한다고 합니다.

 

 

 

1. Miniport NIC Drivers

미니포트 드라이버는 직접 NIC을 관리하고 상위 레벨 드라이버들에 대한 인터페이스를 제공한다. (NDIS DDK 문서)

 

 

2. Intermediate Drivers

인터미디엇 프로토콜 드라이버는 legacy 전송 드라이버와 같은 상위 레벨 프로토콜 드라이버들과 미니포트 사이에 인터페이스이다. 일반적인 인터미디엇 프로토콜 드라이버를 개발하는 일반적인 이유는 존재하는 legacy 드라이버와 전송 드라이버에 알려지지 않은 새로운 미디어 타입을 위한 NIC을 관리하는 미디포트 사이에 미디어 전환을 행하는 거다.

 

 

3. Protocol Drivers

상위 레벨 프로토콜 드라이버는 TDI 인터페이스를 실행하거나 네트워크 사용자들에 대한 서비스들을 제공하기 위해 상위 edge에 또 하나의 어플리케이션 특정 인터페이스를 행한다. lower edge에 이러한 타입의 드라이버는 다음 lower 드라이버로부터 들어오는 패킷들을 수신하고 패킷들을 프로토콜 인터페이스에 제공한다. 또 하나의 타입의 프로토콜 드라이버는 연결 지향 콜 매니저이다. 콜 매니저는 프로토콜 드라이버인 연결 지향 클라이언트들을 위해 서비스들을 콜 설정하고 tear-down 을 제공한다.

 

 

Windows2000에 의해 제공되는 또 하나 타입의 커널 모드 드라이버는 필터 hook 드라이버이다. 필터 패킷들에 사용되는 필터-hook 드라이버는 운영체제에 의해 제공되는 IP 필터 드라이버의 기능을 확장한다.

작성하려고하는 드라이버 타입의 상관없이 Part 1, Network Drivers Design Guide 의 Chapter 2-3을 읽어야 한다. 이러한 장들은 Windows2000네트워크 아키텍처와 프로그래밍 고려 사항들을 토론한다. 또한 Part5, Chapter 1을 읽어야 한다. 이 장은 네트워크 요소들을 인스톨하기 위해 사용된 네트워크 INF 파일들을 토론한다. 만약 네트워크 드라이버가 예를 들어 바인딩을 제어하기 위해 notify 객체를 요구한다면은, Part 5, Chapter 2를 읽어라.

읽어야 할 추가적인 chapters들을 알기 위해, 다음 그림에서 적당한 드라이버 타입을 클릭하라. 이것은 드라이버 타입의 선택을 재 정의하도록 하고 그 섹션으로 점프할 것이다.

Miniport Drivers

작성할 다음과 같은 타입을 선택한다.

Connectionless Miniport

만약 Ethernet, FDDI, 혹은 Token Ring과 같은 비연결 지향 네트워크 미디어을 위해 NIC을 제어하는 미니포트를 작성한다면은,

Part 2, Chaters 1-7, 9을 읽어라.

WAN Miniport

만약 WAN NIC을 제어하는 미니포트를 작성한다면은,

Part 2, Chapters 1-9를 읽어라.

Connection-Oriented Miniport

만약 ATM 혹은 ISDN과 같은 연결 지향 네트워크 미디어을 위한 NIC을 제어하는 미니포트를 쓴다면은,

Part 2, Chapters 1-7, 9
Part 4, Chapter 1을 읽어라.

Integrated Miniport Call Manager(MCM)

만약 콜 매니저 서비스들을 제공하는 연결 지향 NIC을 제어하는 미니포트를 작성한다면은,

Part 2, Chapters 1-7, 9
Part 3, Chapter 2
Part 4, Chapter 1 를 읽어라.

 

 

Intermediate Drivers

작성할 인터미디엇 타입을 선택한다.

With a Connectionless Lower Edge

만약 lower edge가 비연결지향 미니포트들에 대한 인터페이스를 제공하는 인터미디엇 드라이버를 작성한다면은

Part 3, Chapter 1을 읽어라.

With a Connection-Oriented Lower Edge

만약 lower edge가 연결 지향 미니포트들에 대한 인터페이스를 제공하는 인터미디엇 드라이버를 제공한다면은,

Part 3, Chapter 1
Part 4, Chapter 4를 읽어라.

 

 

Protocol Drivers

작성할 프로토콜 드라이버의 타입을 선택한다.

With a Connectionless Lower Edge

만약 lower edge가 비연결지향에 대한 인터페이스를 제공하는 프로토콜 드라이버를 작성한다면은,

Part 3, Chapters, 2를 읽어라.

With TDI upper edge

TDI upper edge를 가지는 프로토콜를 작성한다면은

Part 3, Chapters, 2, 3, 4, 5를 봐라.

With Winsock support

만약 Winsock 지원을 제공하는 프로토콜을 작성한다면은,

Part 3, Chapters, 2, 3, 4, 5, 6을 봐라.

Connection-Oriented Client or Call Manager

만약 연결 지향 미니포트들에 대한 인터페이스를 제공하는 연결 지향 클라이언트를 작성하거나, 연결 지향 콜 매니저를 작성한다면은

Part 3, Chapter 2
Part 4, Chapter 1을 봐라.

 

 

Filter-hook Drivers

Part 6, Chapter 1을 봐라.

 

 

 

Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 02) Intermediate Driver  (0) 2010.05.06
NDIS Extending The PassThru IM Driver  (0) 2010.05.06
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18

1. WDK - Windows Vista RTM 을 다운 받아 설치

   

2. http://www.hollistech.com/Resources/ddkbuild/ddkbuild.htm 에서 ddkbuild 를 받아 압축을 풀고 vs .net 이 참조 가능한 패스에 복사한다.( C:\Program Files\Microsoft Visual Studio .NET 2005\Vc7\bin

3. DDKBUILD 에게 사용할 DDK version 을 알려주기 위해 약간의 편집을 해야 한다. ( 설치한 DDK 경로 설정 )

   

4. 프로젝트 생성 -> 메이크 파일을 선택

    

5. 디버그 구성 구성 설정에서 그림과 같이 설정.

   

6. 참고로 드라이버는 일반 어플리케이션과는 달리 debug build/release build 라고 하지 않는다. 
Debug build checked build
Release build free build

    

7. Visual Studio .Net의 intellisense 기능활용하기.

lib\wxp, inc\ddk, inc\api 폴더추가.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Extending The PassThru IM Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18

출처 : http://www.htsns.com


질문1
 NDIS.sys란 계층이 있는데요
 저는 NDIS가 미니포트 IM 프로토콜 드라이버를 감싸고 있는
 그림만 봐서 이그림은 좀 생소하네요
 이그림의 의미가 미니포트에서는 어퍼에지쪽으로 NDIS인터페이스에 맞춰주고 프로토콜 드라이버에서는 로워에지쪽으로 NDIS의 인터페이스에 맞춰준다는 의미인가요?

 네 감싸고 있는 것이 맞습니다. 실제 코드 구현으로 하면, ndis.sys는 하나의 라이브러리라고 생각하시면 됩니다. 즉 표준 인터페이스를 제공함으로써 미니포트 드라이버와 프로토콜 드라이버를 분리시켜서 서로 다른 업체에서 개발할 수 있도록 합니다. 즉 Lower, Upper Edge 함수들은 콜백함수들입니다. 이 부분은 open block이라는 개념으로 미니포트와 프로토콜을 서로 연결 시켜서 미니포트에서는 Lower-Edge 함수들을 ndis 함수들을 통해 호출할 수 있도록 하고 Upper-Edge 함수들도 마찬가지입니다.
 즉 NdisSend 함수를 호출하면 내부적으로 초기화 시에 등록한 미니포트의 Upper-Edge 함수를 호출하게 합니다. 즉 MiniportSend함수를 호출합니다. 이런 구조가 ndis 라는 아키텍처입니다. 

질문2
 그럼 IM드라이버가 들어간다면 그림에서 어떤식으로 연결이 되는건가요?
 
 
프로토콜, 미니포트 드라이버 구조를 이해하고 계시면 im도 이해하는데 큰 어려움은 없을 겁니다. 즉 프로토콜과 연결하는 부분은 im의 미니포트에 해당하고 미니포트와 연결하는 부분은 im의 프로토콜의 해당합니다. 그리고 im 내에서 미니포트와 프로토콜 부분은 내부 바인딩 개념으로 ndis 가 알아서 처리를 해주고 잇습니다. 과거 im 인터페이스가 제공을 하지 않는 ndis 버전에서는 im 드라이버와 같은 역할을 하는 드라이버를 개발할 때, 직접 ndis protocol 드라이버와 가상 nic 드라이버를 만들어서 내부적으로 직접 연결을 시켜서 필터 드라이버를 개발했습니다.

 다시 함수 정리를 한다면, tcpip.sys라는 ndis protocol드라이버와 virtual nic driver와 바인딩 시키고 자체 ndis protocol 드라이버를 개발 미니포트 드라이버와 바인딩 시킵니다. tcpip.sys에서 ndissend함수를 호출하면 virtual nic driver와 바인딩 되었기 때문에 MiniportSend 함수가 호출될 겁니다. 그럼 MiniportSend 함수에서 자체 ndis protocol에서 ndisopenadapter함수를 통해 얻은 바인딩 핸들을 가지고 ndissend 함수를 호출하면 미니포트의 MiniportSend 함수가 호출되는 구조로 개발이 되었습니다. IM 드라이버인 경우 이런 컨텍스트 관리가 ndis 아키텍처에서 관리가 되는데 자체 위 구조로 개발하게 되면 자체적으로 연결 컨텍스트 관리를 해줘야 되는 불편함이 있습니다.

질문3
 그림에서 1번을 보면 TDI 트랜스포트와 프로토콜이 TCPIP.sys란
 파일로 묶여있는데요.. 두개가 원래 공존하는겁니까?
 
 
네 공존합니다.
즉 프로토콜 드라이버를 개발할 때 소켓단하고 연결을 하려면 tdi transport 계층이 필요합니다.

질문4
 그렇다면 DDK샘플에서 프로토콜드라이버 샘플도 TDI트랜스포트와 프로토콜드라이버로 이루어져 있는겁니까?
 
 
packet이나 ndisuio는 소켓 단과 연결을 하지 않습니다. 그래서 tdi transport 계층이 없습니다. 자체 프로토콜 드라이버기 때문에 바로 어플리케이션과 연결해서 패킷 송/수신을 할 수 있는 하나의 패킷 드라이버라고 할 수 있습니다.

질문5
 우리가 프로토콜 드라이버를 개발하면 기존에 있는 TCPIP.sys를 대체하게 되는겁니까?

 아님 아래쪽이나 위쪽으로 삽입이 되는겁니까?
 
 
병렬 구조입니다. 새로운 프로토콜 드라이버가 생기는 겁니다. 즉 tcpip.sys와는 독립적입니다.

질문6
 그림에서 2번의 TDI.sys는 NDIS.sys처럼 라이브러리(?)를 나타내는겁니까?
 
질문7
 그림 1에서 TDI Transport는 왜 Transport라는 이름이 붙은건가요?
 그림3에서 TDI Client는 왜? Client라는 이름이 붙은건가요?
 Afd.sys에서 Afd는 무슨 약자인가요?
 
 
음 의미상 그런 구조이기 때문에 그런 이름을 붙인것 같습니다. 제 생각입니다만,

transport라는 이름은 osi 7계층에서 전송 계층에 해당하는 부분이라 이런 이름을 사용하지 않았나 생각이 들고 client라는 것은 transport 서비스를 이용하는 부분이기 때문에 client라는 이름을 사용한 것 같습니다.

afd는 모르겠습니다. 추정하는 것은 address family driver 약자가 아닐까.... 생각이 듭니다. 소켓에서 AF_NET이라는 소켓 이름이 사용하는데 AF Address Family 약자라서 ...

질문8
그림3 TDI Client에서요 아래쪽은 TDI인터페이스에 마춰서 동작하는건가요?
그럼 위쪽으로는 유저모드인데 어떤식으로 동작하는지 감이 안잡히네요.. 여기서 IO메니저는 없나요?
 
 
드라이버 통신은 IO 매니저의 의해 이루어집니다. 즉 IRP 통신입니다.
즉 dll <-> sys 사이 통신은 CreateFile, ReadFile, WriteFile, DeviceIoControl, CloseHandle을 통해 이루어집니다. 즉 장치 이름을 ms에서 알고 있기 때문에 이런 인터페이스로 개발이 되었을 겁니다.

 
질문9
 TDI쪽 노란색 계층들도 NDIS의 초록색 계층들이 NDIS인터페이스에 맞춰서 작성되는것처럼
 TDI의 인터페이스가 따로있어서 거기 맞춰서 개발해야하는건가요?
 
네 맞습니다. tdi 문서에 보면 인터페이스 관련 내용들은 자세하게 나와 있습니다.

 
질문10
우리가 NDIS인터페이스에 맞춰서 드라이버를 개발하지만
실제로는 NDIS라이브러리가 윈도우즈의 드라이버 동작방식에
맞춰서 변환해주는건가요?
 
 
ndis 라이브러리의 내부 구조는 wdm 구조일 겁니다.

 
질문11
 이렇게까지 많은 계층들이 필요가 한가요?
 이렇게 여러단계로 나눠논 이유가 무엇인가요??
 
 
third party 개발을 위한 구조입니다. 그리고 os 의 아키텍처입니다. os 개발을 잘하기 위한 구조입니다.

 
한 반년동안 제대로 이해안되던 질문들입니다 ㅠㅠ
정확한 동작을 이해하기가 엄청 어렵네요
항상 답변해주시는 운영자님 감사합니다^^
수고하세요^^
 
 
운영자님 답변 정말 감사합니다^^
 많은 걸 이해하게 됐습니다^^
 
근데 또 질문이 있어요 하하~
프로토콜 드라이버를 보면 TCPIP.sys 란 파일있잖아요
여기는 IP기반 패킷만 이 드라이버로 가는건가요?
IPX라든가 IP기반이 아닌 패킷들은 다른 프로토콜 드라이버로 올라가잖아요


질문 1
 그렇다면 미니포트에서 이더넷 프레임을 검사해서 적절한 프로토콜 드라이버로 올리는 건가요?

미니포트에서는 바인딩된 모든 프로토콜 드라이버에 패킷들을 인디케이트합니다. 프로토콜 드라이버에서 자기 패킷이 아니면 드랍을 하는 방법입니다.

질문 2
 이더넷 헤더는 어디서 붙이고 버리나요?(?)
 TDI에서는 이더넷 헤더를 얻을 수 없다고 알고 있거든요

tdi에서 다루는 구조는 이더넷 프레임을 다루는 게 아니고 연결 관리를 핸들로 처리하기 때문에 즉 연결을 캡슐화해서 처리합니다. 즉 소켓 단위라고 생각하시면 될 겁니다. 그래서 이더넷 헤더를 파악할 수 없습니다.

질문 3
 TDI 클라이언트를 개발한다면
 이것두 병렬구조로 붙게 되나요?

네 그렇게 되겠죠.. 

질문 4
 Hook Driver라는건
 네트워크 계층에서 어떤 드라이버에도 붙일 수 있는건가요?

hook 방법을 이해하시면 좀 더 이해가 쉬울 겁니다. 훅은 함수 포인터를 훅하는 것이기 때문에 원본 함수 포인터를 알면 모든 함수들이 훅이 가능합니다. 네트워크 계층에 상관이 없습니다.

질문 5
 Ip Filter Hook Driver는 어떤 드라이버에 붙은 필터드라이번가요?

tcpip.sys에서 export한 필터 함수입니다. 그래서 기능이 제한되었습니다. 즉 제공된 함수이외의 기능은 불가능합니다.

질문 6
 TDI 계층에서도 어퍼에지 로워에지라는 개념이 있나요?

다른 이름으로 사용합니다. transport와 client 개념입니다. 통신 방법도 차이가 있습니다.

질문 7
 TDI를 개발하지 않고도(IM이나 HookDriver에서)
 소켓의 생성을 감지하고 차단할 수 있을까요?

소켓의 생성이라는 말의 의미에 따라 다릅니다. 소켓의 생성이 인터넷 차단인지 아니면 실제 소켓 함수의 차단인지에 따라 차이가 있습니다. 원하는 기능이나 구조에 따라 훅 방법과 접근 레이어가 달라집니다.

질문 8
 LSP계층에 대한 어떤 문서나 사이트는 없나요?
 이쪽은 자료가 전혀 없는거 같던데 ㅠㅠ

sdk에 샘플 코드가 있고 msdn 도움말과 과거 한국전산원에서 프로젝트로 한 문서가 있습니다.
그리고 lsp를 사용한 스팸 메일 차단 공개 프로젝트가 있습니다.

질문 9
 paathru예제를 보면 모든 callback(?)함수들을 다 구현해 주던데요
 보통 필터 드라이버에서 보면
 자신이 필요한 동작만 프록시함수를 만들어서 연결시켜주잖아요
 IM에서는 모든 동작을 다 정의해줘야 하나요?

훅 드라이버와 차이점입니다. 훅방법은 자신의 훅할 위치만 훅하면 되지만 im은 ndis 아키텍처입니다. 이 구조에 맞춰 개발을 해줘야 합니다.

질문 10
 윈도우 방화벽은 무슨 드라이버로 제작된건가요?

분석을 안해봐서 어떻게 개발되었는지는 모르겠습니다.
분석을 하실 때는 일단 사용된 바이너리를 검색하시고 바이너리를 역어샘블이나 바이너리 십육진 덤프등등의 리버스 엔지니어링 툴들을 사용해서 분석해 보세요.

질문 11
 미니포트 드라이버는 왜 미니포트라고 부르는건가요?
 
또 질문 많이 하게 되네요^^

과거 랜카드 드라이버는 풀 닉드라이버라고 했습니다. 말 그대로 입니다. 포트는 하드웨어와 통신을 하는 최단부분입니다. 버스 포트 등등... 미니는 최소 업체 스펙만 구현을 하면 되도록 os에서 전체 구조를 제공해주었기 때문에 미니 부분만 개발을 하면 되는게 아닌가 생각이 듭니다. 정확히 모르겠네요.. 정의에 대해서는 



-----------------------------------------------------------------------------------


sfilter.dll은 



NTDDK\src\network\config\filter를 build하면 sfilter.dll이 생성된다고 합니다.



저의 경우에는 ddk sample설치시 골라서 설치해서 이 폴더가 없었던것 같습니다.



이 파일의 기능은 hantech에 netcoder님이 잘 설명 해주셨더군요.



설치 관련 dll입니다.

notify object으로써 동적으로 설치 관련 부분을 담당합니다.

즉 프로토콜을 등록하면서 가상 미니포트를 등록하려하면 이 dll 안에서 설치 관련 연산을 하면 됩니다.

2003 dotnet ddk에서는 passthru의 notify object은 사용을 안해서 제거를 했습니다. mux에서는 이 부분을 사용해서 (프로토콜 + 가상 미니포트) 먼저 네트워크 등록 정보에서 muxp 프로토콜을 등록을 하면 네트워크 구성 서브시스템(네트워크 설치 관련 모듈:운영체제)에서 notify object(CoM)을 호출을 하면 이 내에서 가상 미니포트를 등록을 합니다.



즉 프로그램 상으로 설치 과정을 변경하려면(네트워크 등록 정보에서 새로운 프로퍼티 sheet 추가 등등) 이 dll을 등록을 해야 합니다.(inf 파일 내에 component dll 부분에)



보다 자세한 내용은 ddk의 네트워크 부분에서 install 부분을 참조하세요.

자세하게 나와 있습니다.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18
Fast I/O  (0) 2010.03.18

WDK에서는 드라이버에서 사용하기 위한 리스트를 제공한다. 리스트 뿐만아니라

KQUEUE, KDVICE_QUEUE, IO_REMOVE_LOCK, MDL 을 제공하고 있다.

아래는 LIST_ENTRY의 사용 예이다.

Snap2.bmp


참고 사이트: http://groups.google.co.kr/group/endless-creation/web/드라이버에서+링크드+리스트+구현시+참고사항

http://www.pyrasis.com/blog/17

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
Lookaside list  (0) 2010.03.18
Fast I/O  (0) 2010.03.18

Heap 관리자는 메모리 블럭의 크기가 무작위로 결정되기 때문에 인접한 free 블럭을 합치기 위해 많은 CPU 시간을 요구하게 됩니다.


항상 고정된 크기의 메모리 블럭만을 사용한다면 heap을 관리하는데 있어 훨씬 효율적인 방식으로 사용이 가능한데 예를 들면

큰 메모리 블럭을 미리 할당하여, 이를 주어진 크기로 조각냅니다. 블럭이 heap에 리턴되면 실제로 해제하는 것이 아니라 사용이

끝남으로 표시하면서 사용하게 되는데, 이에 대한 몇가지 문제점이 있습니다.


너무 많은 메모리를 할당할 경우는 메모리 낭비를 가져올 수 있고, 너무 적게 할당할 경우는 알고리즘이 동작하지 않거나 더 많은 블럭을 얻으려고 heap 관리자를 너무 자주 사용하게 되는 것입니다.


Microsoft에서는 이러한 단점을 극복하기 위해 lookaside list 객체를 제공합니다.


lookaside list

  1. lookaside list 객체 초기화시 시스템에게 작업할 단위 메모리 블럭의 크기를 알립니다. ( 용량은 운영체제가 탄력적으로 감지합니다. )
  2. 메모리 블럭을 할당하기 위해서 시스템은 일단 하나의 블럭의 제거를 시도합니다.
    1. 더 이상 남은 블럭이 없다면 메모리 pool에서 빼옵니다.
  3. 메모리 블럭을 반환하려면, 시스템은 리스트에 되돌리기를 시도하게 되며, 리스트가 꽉 차면 일반 heap 관리 루틴을 사용해서 pool에 블럭을 되돌립니다.

시스템은 실제 사용에 따라 모든 lookaside list의 depth를 정기적으로 조작합니다.

  • 시스템에 최근 접근하지 않았거나, 총 시간에서 5% 이상 액세스 하지 않은 lookaside list에 대해 depth를 감소 시킵니다.
  • 처음의 새 리스트 값인 4 이하로는 줄어들지 않습니다.
  • driver verifier 실행시는 모든 lookaside list의 depth는 모두 0으로 바뀝니다. ( 메모리 오류와 관련된 드라이버 문제를 발견하기 쉽게 하기 위해서 입니다. )

Lookaside list 지원 함수

Lookaside list를 지원하는 함수는 paged / non-paged 두 분류로 나뉘게 됩니다.

  • ExInitializeNPagedLookasideList  / ExInitializePagedLookasideList : Lookaside list를 초기화 한다.
  • ExAllocateFromNPagedLookasideList / ExAllocateFromPagedLookasideList : 고정된 크기의 블럭을 할당한다.  
  • ExFreeToNPagedLookasideList / ExFreeToPagedLookasideList : 해제해서 lookaside list로 다시 돌려준다.
  • ExDeleteNPagedLookasideList / ExDeletePagedLookasideList : Lookaside list를 삭제한다.


lookaside list 객체를 위해 메모리를 확보하고 나서 적절한 초기화 루틴을 호출합니다.


각 함수에서 첫 번째 인수는 이미 공간을 확보해둔 (N)PAGED_LOOKASIDE_LIST 객체에 대한 포인터입니다. Allocate와 Free는 heap에서 메모리를 할당하거나 해제할 수 있는 루틴들에 대한 포인터 입니다. ExAllocatePoolWithTag와 ExFreePool을 쓸 시에는 이 인수들을 NULL로 하면 됩니다. blocksize 인수는 리스트에서 할당하는 메모리 블럭의 크기를 나타냅니다. tag는 이러한 각 블럭의 앞에 붙은 32비트 태그 값입니다.


리스트에서 메모리 블럭을 할당하려면 적절한 AllocateFrom 함수를 호출한다.

PVOID p = ExAllocateFromPagedLookasideList(pagelist);

PVOID p = ExAllocateFromNPagedLookasideList(nonpagedlist);

블럭을 리스트로 다시 돌리려면 적절한 FreeTo 함수를 호출하면 됩니다.

ExFreeToPagedLookasideList(pagedlist, p);

ExFreeToNPagedLookasideList(nonpagedlist, p);

마지막으로 리스트를 제거하려면 적절한 Delete 함수를 호출하면 됩니다.

ExDeletePagedLookasideList(pagedlist);

ExDeleteNPagedLookasideList(nonpagedlist);

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Fast I/O  (0) 2010.03.18

2006/10/31 19:10


복사http://blog.naver.com/dbtalk/110010329621


Fast I/O는 Cached file을 read/write함에 있어서 IRP를 만들지 않고 가능하게 해줍니다.
 
ReadFile를 예로 들어 Fast I/O의 흐름을 설명하면 다음과 같습니다.


순서1. NtReadFile에서 요청된 data가 Cached data인지 또는 Synchronous I/O인지를 판단하여

         Yes이면 File system driver를 호출합니다.
 
순서2. File system Driver에서는 Fast I/O가 가능한지를 판단하여 가능하면 Cache manager로

          제어를 넘긴다.


순서3. Cache Manager가 실제 Data를 I/O를 요청한 Process buffer로 복사한다.
 
순서4. 만약 순서1 또는 순서2에서 조건이 만족하지 않으면 IRP를 만들어서 I/O를 수행한다.


-- 부가 설명 --


일반적으로 File system에서의 I/O 요청은 
(1) File system driver(FSD)
(2) Cache Manager
(3) Memory Manager
(4) File system driver 재 진입
(5) DISK I/O 순으로 IRP 가 처리됩니다.
 
이 과정에서 Synchronous, buffered I/O 인 경우 I/O 요청은 결국 Cache Manager가 처리하게 된다. FSD는 단지 IRP를 Cache Manger에게 전달하는 역할 뿐이다.
따라서 Fast I/O는 IRP를 생성하고 FSD를 호출하는 부담을 줄이고 막바로 Cache Manger의 service를 호출 하는 방식이다.
fast의 원래 목적인 Synchronous, Buffered I/O read/write를 지원하면서 좀 더 확장되어 여러가지 FSD 함수들도 Fast I/O로 서비스 되고 있다.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18

+ Recent posts