netcore.c 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. netcore.c
  5. Abstract:
  6. This module implements the networking core library.
  7. Author:
  8. Evan Green 4-Apr-2013
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/driver.h>
  16. #include "netcore.h"
  17. #include "ethernet.h"
  18. //
  19. // ---------------------------------------------------------------- Definitions
  20. //
  21. //
  22. // ------------------------------------------------------ Data Type Definitions
  23. //
  24. /*++
  25. Structure Description:
  26. This structure defines a basic network socket option.
  27. Members:
  28. InformationType - Stores the information type for the socket option.
  29. Option - Stores the type-specific option identifier.
  30. Size - Stores the size of the option value, in bytes.
  31. SetAllowed - Stores a boolean indicating whether or not the option is
  32. allowed to be set.
  33. --*/
  34. typedef struct _NET_SOCKET_OPTION {
  35. SOCKET_INFORMATION_TYPE InformationType;
  36. UINTN Option;
  37. UINTN Size;
  38. BOOL SetAllowed;
  39. } NET_SOCKET_OPTION, *PNET_SOCKET_OPTION;
  40. //
  41. // ----------------------------------------------- Internal Function Prototypes
  42. //
  43. KSTATUS
  44. NetCreateSocket (
  45. NET_DOMAIN_TYPE Domain,
  46. NET_SOCKET_TYPE Type,
  47. ULONG Protocol,
  48. PSOCKET *NewSocket
  49. );
  50. VOID
  51. NetDestroySocket (
  52. PSOCKET Socket
  53. );
  54. KSTATUS
  55. NetBindToAddress (
  56. PSOCKET Socket,
  57. PVOID Link,
  58. PNETWORK_ADDRESS Address
  59. );
  60. KSTATUS
  61. NetListen (
  62. PSOCKET Socket,
  63. ULONG BacklogCount
  64. );
  65. KSTATUS
  66. NetAccept (
  67. PSOCKET Socket,
  68. PIO_HANDLE *NewConnectionSocket,
  69. PNETWORK_ADDRESS RemoteAddress
  70. );
  71. KSTATUS
  72. NetConnect (
  73. PSOCKET Socket,
  74. PNETWORK_ADDRESS Address
  75. );
  76. KSTATUS
  77. NetCloseSocket (
  78. PSOCKET Socket
  79. );
  80. KSTATUS
  81. NetSendData (
  82. BOOL FromKernelMode,
  83. PSOCKET Socket,
  84. PSOCKET_IO_PARAMETERS Parameters,
  85. PIO_BUFFER IoBuffer
  86. );
  87. KSTATUS
  88. NetReceiveData (
  89. BOOL FromKernelMode,
  90. PSOCKET Socket,
  91. PSOCKET_IO_PARAMETERS Parameters,
  92. PIO_BUFFER IoBuffer
  93. );
  94. KSTATUS
  95. NetGetSetSocketInformation (
  96. PSOCKET Socket,
  97. SOCKET_INFORMATION_TYPE InformationType,
  98. UINTN SocketOption,
  99. PVOID Data,
  100. PUINTN DataSize,
  101. BOOL Set
  102. );
  103. KSTATUS
  104. NetShutdown (
  105. PSOCKET Socket,
  106. ULONG ShutdownType
  107. );
  108. KSTATUS
  109. NetUserControl (
  110. PSOCKET Socket,
  111. ULONG CodeNumber,
  112. BOOL FromKernelMode,
  113. PVOID ContextBuffer,
  114. UINTN ContextBufferSize
  115. );
  116. VOID
  117. NetpDestroyProtocol (
  118. PNET_PROTOCOL_ENTRY Protocol
  119. );
  120. //
  121. // -------------------------------------------------------------------- Globals
  122. //
  123. //
  124. // Define the lists of supported types for various networking layers.
  125. //
  126. LIST_ENTRY NetProtocolList;
  127. LIST_ENTRY NetNetworkList;
  128. LIST_ENTRY NetDataLinkList;
  129. PSHARED_EXCLUSIVE_LOCK NetPluginListLock;
  130. BOOL NetInitialized = FALSE;
  131. //
  132. // Define the global debug flag, which propagates throughout the networking
  133. // subsystem.
  134. //
  135. BOOL NetGlobalDebug = FALSE;
  136. //
  137. // Optimize a bit by storing pointers directly to the super common network and
  138. // protocol entries.
  139. //
  140. PNET_NETWORK_ENTRY NetArpNetworkEntry = NULL;
  141. PNET_NETWORK_ENTRY NetIp4NetworkEntry = NULL;
  142. PNET_NETWORK_ENTRY NetIp6NetworkEntry = NULL;
  143. PNET_PROTOCOL_ENTRY NetTcpProtocolEntry = NULL;
  144. PNET_PROTOCOL_ENTRY NetUdpProtocolEntry = NULL;
  145. PNET_PROTOCOL_ENTRY NetRawProtocolEntry = NULL;
  146. NET_INTERFACE NetInterface = {
  147. NetCreateSocket,
  148. NetDestroySocket,
  149. NetBindToAddress,
  150. NetListen,
  151. NetAccept,
  152. NetConnect,
  153. NetCloseSocket,
  154. NetSendData,
  155. NetReceiveData,
  156. NetGetSetSocketInformation,
  157. NetShutdown,
  158. NetUserControl
  159. };
  160. NET_SOCKET_OPTION NetBasicSocketOptions[] = {
  161. {
  162. SocketInformationBasic,
  163. SocketBasicOptionType,
  164. sizeof(NET_SOCKET_TYPE),
  165. FALSE
  166. },
  167. {
  168. SocketInformationBasic,
  169. SocketBasicOptionDomain,
  170. sizeof(NET_DOMAIN_TYPE),
  171. FALSE
  172. },
  173. {
  174. SocketInformationBasic,
  175. SocketBasicOptionLocalAddress,
  176. sizeof(NETWORK_ADDRESS),
  177. FALSE
  178. },
  179. {
  180. SocketInformationBasic,
  181. SocketBasicOptionRemoteAddress,
  182. sizeof(NETWORK_ADDRESS),
  183. FALSE
  184. },
  185. {
  186. SocketInformationBasic,
  187. SocketBasicOptionReuseAnyAddress,
  188. sizeof(ULONG),
  189. TRUE
  190. },
  191. {
  192. SocketInformationBasic,
  193. SocketBasicOptionReuseTimeWait,
  194. sizeof(ULONG),
  195. TRUE
  196. },
  197. {
  198. SocketInformationBasic,
  199. SocketBasicOptionReuseExactAddress,
  200. sizeof(ULONG),
  201. TRUE
  202. },
  203. {
  204. SocketInformationBasic,
  205. SocketBasicOptionBroadcastEnabled,
  206. sizeof(ULONG),
  207. TRUE
  208. },
  209. {
  210. SocketInformationBasic,
  211. SocketBasicOptionErrorStatus,
  212. sizeof(KSTATUS),
  213. FALSE
  214. },
  215. {
  216. SocketInformationBasic,
  217. SocketBasicOptionAcceptConnections,
  218. sizeof(ULONG),
  219. FALSE
  220. },
  221. {
  222. SocketInformationBasic,
  223. SocketBasicOptionSendTimeout,
  224. sizeof(SOCKET_TIME),
  225. FALSE
  226. },
  227. };
  228. //
  229. // ------------------------------------------------------------------ Functions
  230. //
  231. KSTATUS
  232. DriverEntry (
  233. PDRIVER Driver
  234. )
  235. /*++
  236. Routine Description:
  237. This routine implements the initial entry point of the networking core
  238. library, called when the library is first loaded.
  239. Arguments:
  240. Driver - Supplies a pointer to the driver object.
  241. Return Value:
  242. Status code.
  243. --*/
  244. {
  245. BOOL BuffersInitialized;
  246. KSTATUS Status;
  247. ASSERT(NetInitialized == FALSE);
  248. BuffersInitialized = FALSE;
  249. //
  250. // The core networking driver never goes away, even if the driver that
  251. // imported it is unloaded.
  252. //
  253. IoDriverAddReference(Driver);
  254. INITIALIZE_LIST_HEAD(&NetProtocolList);
  255. INITIALIZE_LIST_HEAD(&NetNetworkList);
  256. INITIALIZE_LIST_HEAD(&NetDataLinkList);
  257. NetPluginListLock = KeCreateSharedExclusiveLock();
  258. if (NetPluginListLock == NULL) {
  259. Status = STATUS_INSUFFICIENT_RESOURCES;
  260. goto DriverEntryEnd;
  261. }
  262. Status = NetpInitializeBuffers();
  263. if (!KSUCCESS(Status)) {
  264. goto DriverEntryEnd;
  265. }
  266. BuffersInitialized = TRUE;
  267. Status = NetpInitializeNetworkLayer();
  268. if (!KSUCCESS(Status)) {
  269. goto DriverEntryEnd;
  270. }
  271. //
  272. // Set up the built in protocols, networks, data links and miscellaneous
  273. // components.
  274. //
  275. NetpEthernetInitialize();
  276. NetpIp4Initialize();
  277. NetpArpInitialize();
  278. NetpUdpInitialize();
  279. NetpTcpInitialize();
  280. NetpRawInitialize();
  281. NetpDhcpInitialize();
  282. NetpNetlinkInitialize();
  283. NetpNetlinkGenericInitialize(0);
  284. //
  285. // Set up the networking interface to the kernel.
  286. //
  287. IoInitializeCoreNetworking(&NetInterface);
  288. NetInitialized = TRUE;
  289. Status = STATUS_SUCCESS;
  290. //
  291. // Handle any post-registration work for the built in protocols, networks,
  292. // data links and miscellaneous components.
  293. //
  294. NetpNetlinkGenericInitialize(1);
  295. DriverEntryEnd:
  296. if (!KSUCCESS(Status)) {
  297. if (NetPluginListLock != NULL) {
  298. KeDestroySharedExclusiveLock(NetPluginListLock);
  299. NetPluginListLock = NULL;
  300. }
  301. if (BuffersInitialized != FALSE) {
  302. NetpDestroyBuffers();
  303. }
  304. }
  305. return Status;
  306. }
  307. NET_API
  308. KSTATUS
  309. NetRegisterProtocol (
  310. PNET_PROTOCOL_ENTRY NewProtocol,
  311. PHANDLE ProtocolHandle
  312. )
  313. /*++
  314. Routine Description:
  315. This routine registers a new protocol type with the core networking
  316. library.
  317. Arguments:
  318. NewProtocol - Supplies a pointer to the protocol information. The core
  319. library will not reference this memory after the function returns, a
  320. copy will be made.
  321. ProtocolHandle - Supplies an optional pointer that receives a handle to the
  322. registered protocol on success.
  323. Return Value:
  324. STATUS_SUCCESS on success.
  325. STATUS_INVALID_PARAMETER if part of the structure isn't filled out
  326. correctly.
  327. STATUS_INSUFFICIENT_RESOURCES if memory could not be allocated.
  328. STATUS_DUPLICATE_ENTRY if the socket type is already registered.
  329. --*/
  330. {
  331. PLIST_ENTRY CurrentEntry;
  332. HANDLE Handle;
  333. BOOL LockHeld;
  334. PNET_PROTOCOL_ENTRY NewProtocolCopy;
  335. PNET_PROTOCOL_ENTRY Protocol;
  336. KSTATUS Status;
  337. ASSERT(KeGetRunLevel() == RunLevelLow);
  338. LockHeld = FALSE;
  339. Handle = INVALID_HANDLE;
  340. NewProtocolCopy = NULL;
  341. if ((NewProtocol->Type == NetSocketInvalid) ||
  342. (NewProtocol->Interface.CreateSocket == NULL) ||
  343. (NewProtocol->Interface.DestroySocket == NULL) ||
  344. (NewProtocol->Interface.BindToAddress == NULL) ||
  345. (NewProtocol->Interface.Listen == NULL) ||
  346. (NewProtocol->Interface.Accept == NULL) ||
  347. (NewProtocol->Interface.Connect == NULL) ||
  348. (NewProtocol->Interface.Close == NULL) ||
  349. (NewProtocol->Interface.Shutdown == NULL) ||
  350. (NewProtocol->Interface.Send == NULL) ||
  351. (NewProtocol->Interface.ProcessReceivedData == NULL) ||
  352. (NewProtocol->Interface.Receive == NULL) ||
  353. (NewProtocol->Interface.GetSetInformation == NULL) ||
  354. (NewProtocol->Interface.UserControl == NULL) ||
  355. (NewProtocol->Interface.ProcessReceivedSocketData == NULL)) {
  356. Status = STATUS_INVALID_PARAMETER;
  357. goto RegisterProtocolEnd;
  358. }
  359. //
  360. // Create a copy of the new protocol.
  361. //
  362. NewProtocolCopy = MmAllocatePagedPool(sizeof(NET_PROTOCOL_ENTRY),
  363. NET_CORE_ALLOCATION_TAG);
  364. if (NewProtocolCopy == NULL) {
  365. Status = STATUS_INSUFFICIENT_RESOURCES;
  366. goto RegisterProtocolEnd;
  367. }
  368. RtlCopyMemory(NewProtocolCopy, NewProtocol, sizeof(NET_PROTOCOL_ENTRY));
  369. NewProtocolCopy->SocketLock = KeCreateSharedExclusiveLock();
  370. if (NewProtocolCopy->SocketLock == NULL) {
  371. Status = STATUS_INSUFFICIENT_RESOURCES;
  372. goto RegisterProtocolEnd;
  373. }
  374. RtlRedBlackTreeInitialize(&(NewProtocolCopy->SocketTree[SocketUnbound]),
  375. 0,
  376. NetpCompareUnboundSockets);
  377. RtlRedBlackTreeInitialize(
  378. &(NewProtocolCopy->SocketTree[SocketLocallyBound]),
  379. 0,
  380. NetpCompareLocallyBoundSockets);
  381. RtlRedBlackTreeInitialize(&(NewProtocolCopy->SocketTree[SocketFullyBound]),
  382. 0,
  383. NetpCompareFullyBoundSockets);
  384. KeAcquireSharedExclusiveLockExclusive(NetPluginListLock);
  385. LockHeld = TRUE;
  386. //
  387. // Loop through looking for a previous registration with this protocol type
  388. // and parent protocol number pair.
  389. //
  390. CurrentEntry = NetProtocolList.Next;
  391. while (CurrentEntry != &NetProtocolList) {
  392. Protocol = LIST_VALUE(CurrentEntry, NET_PROTOCOL_ENTRY, ListEntry);
  393. if ((Protocol->Type == NewProtocol->Type) &&
  394. (Protocol->ParentProtocolNumber ==
  395. NewProtocol->ParentProtocolNumber)) {
  396. Status = STATUS_DUPLICATE_ENTRY;
  397. goto RegisterProtocolEnd;
  398. }
  399. CurrentEntry = CurrentEntry->Next;
  400. }
  401. //
  402. // There are no duplicates, add this entry to the back of the list.
  403. //
  404. INSERT_BEFORE(&(NewProtocolCopy->ListEntry), &NetProtocolList);
  405. //
  406. // Save the common ones for quick access.
  407. //
  408. if ((NewProtocolCopy->Type == NetSocketStream) &&
  409. (NewProtocolCopy->ParentProtocolNumber ==
  410. SOCKET_INTERNET_PROTOCOL_TCP)) {
  411. NetTcpProtocolEntry = NewProtocolCopy;
  412. } else if ((NewProtocolCopy->Type == NetSocketDatagram) &&
  413. (NewProtocolCopy->ParentProtocolNumber ==
  414. SOCKET_INTERNET_PROTOCOL_UDP)) {
  415. NetUdpProtocolEntry = NewProtocolCopy;
  416. } else if (NewProtocolCopy->Type == NetSocketRaw) {
  417. NetRawProtocolEntry = NewProtocolCopy;
  418. }
  419. Status = STATUS_SUCCESS;
  420. Handle = NewProtocolCopy;
  421. RegisterProtocolEnd:
  422. if (LockHeld != FALSE) {
  423. KeReleaseSharedExclusiveLockExclusive(NetPluginListLock);
  424. }
  425. if (!KSUCCESS(Status)) {
  426. if (NewProtocolCopy != NULL) {
  427. NetpDestroyProtocol(NewProtocolCopy);
  428. }
  429. }
  430. if (ProtocolHandle != NULL) {
  431. *ProtocolHandle = Handle;
  432. }
  433. return Status;
  434. }
  435. NET_API
  436. VOID
  437. NetUnregisterProtocol (
  438. HANDLE ProtocolHandle
  439. )
  440. /*++
  441. Routine Description:
  442. This routine unregisters the given protocol from the core networking
  443. library.
  444. Arguments:
  445. ProtocolHandle - Supplies the handle to the protocol to unregister.
  446. Return Value:
  447. None.
  448. --*/
  449. {
  450. PLIST_ENTRY CurrentEntry;
  451. PNET_PROTOCOL_ENTRY FoundProtocol;
  452. PNET_PROTOCOL_ENTRY Protocol;
  453. FoundProtocol = NULL;
  454. //
  455. // Loop through looking for a previous registration with this protocol
  456. // handle.
  457. //
  458. KeAcquireSharedExclusiveLockExclusive(NetPluginListLock);
  459. CurrentEntry = NetProtocolList.Next;
  460. while (CurrentEntry != &NetProtocolList) {
  461. Protocol = LIST_VALUE(CurrentEntry, NET_PROTOCOL_ENTRY, ListEntry);
  462. if (Protocol == ProtocolHandle) {
  463. FoundProtocol = Protocol;
  464. LIST_REMOVE(CurrentEntry);
  465. break;
  466. }
  467. CurrentEntry = CurrentEntry->Next;
  468. }
  469. KeReleaseSharedExclusiveLockExclusive(NetPluginListLock);
  470. if (FoundProtocol != NULL) {
  471. NetpDestroyProtocol(FoundProtocol);
  472. }
  473. return;
  474. }
  475. NET_API
  476. KSTATUS
  477. NetRegisterNetworkLayer (
  478. PNET_NETWORK_ENTRY NewNetworkEntry,
  479. PHANDLE NetworkHandle
  480. )
  481. /*++
  482. Routine Description:
  483. This routine registers a new network type with the core networking library.
  484. Arguments:
  485. NewNetworkEntry - Supplies a pointer to the network information. The core
  486. library will not reference this memory after the function returns, a
  487. copy will be made.
  488. NetworkHandle - Supplies a pointer that receives a handle to the
  489. registered network layer on success.
  490. Return Value:
  491. STATUS_SUCCESS on success.
  492. STATUS_INVALID_PARAMETER if part of the structure isn't filled out
  493. correctly.
  494. STATUS_INSUFFICIENT_RESOURCES if memory could not be allocated.
  495. STATUS_DUPLICATE_ENTRY if the network type is already registered.
  496. --*/
  497. {
  498. PLIST_ENTRY CurrentEntry;
  499. HANDLE Handle;
  500. BOOL LockHeld;
  501. PNET_NETWORK_ENTRY Network;
  502. PNET_NETWORK_ENTRY NewNetworkCopy;
  503. KSTATUS Status;
  504. ASSERT(KeGetRunLevel() == RunLevelLow);
  505. LockHeld = FALSE;
  506. Handle = INVALID_HANDLE;
  507. NewNetworkCopy = NULL;
  508. if ((NewNetworkEntry->Domain == NetDomainInvalid) ||
  509. (NewNetworkEntry->Interface.InitializeLink == NULL) ||
  510. (NewNetworkEntry->Interface.DestroyLink == NULL) ||
  511. (NewNetworkEntry->Interface.ProcessReceivedData == NULL) ||
  512. (NewNetworkEntry->Interface.PrintAddress == NULL)) {
  513. Status = STATUS_INVALID_PARAMETER;
  514. goto RegisterNetworkLayerEnd;
  515. }
  516. //
  517. // Networks on which sockets will be created must register with the socket
  518. // API functions.
  519. //
  520. if ((NET_IS_SOCKET_NETWORK_DOMAIN(NewNetworkEntry->Domain) != FALSE) &&
  521. ((NewNetworkEntry->Interface.InitializeSocket == NULL) ||
  522. (NewNetworkEntry->Interface.BindToAddress == NULL) ||
  523. (NewNetworkEntry->Interface.Listen == NULL) ||
  524. (NewNetworkEntry->Interface.Connect == NULL) ||
  525. (NewNetworkEntry->Interface.Disconnect == NULL) ||
  526. (NewNetworkEntry->Interface.Close == NULL) ||
  527. (NewNetworkEntry->Interface.Send == NULL) ||
  528. (NewNetworkEntry->Interface.GetSetInformation == NULL))) {
  529. Status = STATUS_INVALID_PARAMETER;
  530. goto RegisterNetworkLayerEnd;
  531. }
  532. //
  533. // Create a copy of the new network entry.
  534. //
  535. NewNetworkCopy = MmAllocatePagedPool(sizeof(NET_NETWORK_ENTRY),
  536. NET_CORE_ALLOCATION_TAG);
  537. if (NewNetworkCopy == NULL) {
  538. Status = STATUS_INSUFFICIENT_RESOURCES;
  539. goto RegisterNetworkLayerEnd;
  540. }
  541. RtlCopyMemory(NewNetworkCopy, NewNetworkEntry, sizeof(NET_NETWORK_ENTRY));
  542. KeAcquireSharedExclusiveLockExclusive(NetPluginListLock);
  543. LockHeld = TRUE;
  544. //
  545. // Loop through looking for a previous registration with this network layer
  546. // number.
  547. //
  548. CurrentEntry = NetNetworkList.Next;
  549. while (CurrentEntry != &NetNetworkList) {
  550. Network = LIST_VALUE(CurrentEntry, NET_NETWORK_ENTRY, ListEntry);
  551. if (Network->Domain == NewNetworkEntry->Domain) {
  552. Status = STATUS_DUPLICATE_ENTRY;
  553. goto RegisterNetworkLayerEnd;
  554. }
  555. CurrentEntry = CurrentEntry->Next;
  556. }
  557. //
  558. // There are no duplicates, add this entry to the back of the list.
  559. //
  560. INSERT_BEFORE(&(NewNetworkCopy->ListEntry), &NetNetworkList);
  561. //
  562. // Save quick-access pointers for the common ones.
  563. //
  564. if (NewNetworkCopy->Domain == NetDomainIp4) {
  565. NetIp4NetworkEntry = NewNetworkCopy;
  566. } else if (NewNetworkCopy->Domain == NetDomainIp6) {
  567. NetIp6NetworkEntry = NewNetworkCopy;
  568. } else if (NewNetworkCopy->Domain == NetDomainArp) {
  569. NetArpNetworkEntry = NewNetworkCopy;
  570. }
  571. Status = STATUS_SUCCESS;
  572. Handle = NewNetworkCopy;
  573. RegisterNetworkLayerEnd:
  574. if (LockHeld != FALSE) {
  575. KeReleaseSharedExclusiveLockExclusive(NetPluginListLock);
  576. }
  577. if (!KSUCCESS(Status)) {
  578. if (NewNetworkCopy != NULL) {
  579. MmFreePagedPool(NewNetworkCopy);
  580. }
  581. }
  582. if (NetworkHandle != NULL) {
  583. *NetworkHandle = Handle;
  584. }
  585. return Status;
  586. }
  587. NET_API
  588. VOID
  589. NetUnregisterNetworkLayer (
  590. HANDLE NetworkHandle
  591. )
  592. /*++
  593. Routine Description:
  594. This routine unregisters the given network layer from the core networking
  595. library.
  596. Arguments:
  597. NetworkHandle - Supplies the handle to the network layer to unregister.
  598. Return Value:
  599. None.
  600. --*/
  601. {
  602. PLIST_ENTRY CurrentEntry;
  603. PNET_NETWORK_ENTRY FoundNetwork;
  604. PNET_NETWORK_ENTRY Network;
  605. FoundNetwork = NULL;
  606. //
  607. // Loop through looking for a previous registration with this network
  608. // handle.
  609. //
  610. KeAcquireSharedExclusiveLockExclusive(NetPluginListLock);
  611. CurrentEntry = NetNetworkList.Next;
  612. while (CurrentEntry != &NetNetworkList) {
  613. Network = LIST_VALUE(CurrentEntry, NET_NETWORK_ENTRY, ListEntry);
  614. if (Network == NetworkHandle) {
  615. FoundNetwork = Network;
  616. LIST_REMOVE(CurrentEntry);
  617. break;
  618. }
  619. CurrentEntry = CurrentEntry->Next;
  620. }
  621. KeReleaseSharedExclusiveLockExclusive(NetPluginListLock);
  622. if (FoundNetwork != NULL) {
  623. MmFreePagedPool(FoundNetwork);
  624. }
  625. return;
  626. }
  627. NET_API
  628. KSTATUS
  629. NetRegisterDataLinkLayer (
  630. PNET_DATA_LINK_ENTRY NewDataLinkEntry,
  631. PHANDLE DataLinkHandle
  632. )
  633. /*++
  634. Routine Description:
  635. This routine registers a new data link type with the core networking
  636. library.
  637. Arguments:
  638. NewDataLinkEntry - Supplies a pointer to the link information. The core
  639. library will not reference this memory after the function returns, a
  640. copy will be made.
  641. DataLinkHandle - Supplies a pointer that receives a handle to the
  642. registered data link layer on success.
  643. Return Value:
  644. STATUS_SUCCESS on success.
  645. STATUS_INVALID_PARAMETER if part of the structure isn't filled out
  646. correctly.
  647. STATUS_INSUFFICIENT_RESOURCES if memory could not be allocated.
  648. STATUS_DUPLICATE_ENTRY if the link type is already registered.
  649. --*/
  650. {
  651. PLIST_ENTRY CurrentEntry;
  652. PNET_DATA_LINK_ENTRY DataLink;
  653. HANDLE Handle;
  654. BOOL LockHeld;
  655. PNET_DATA_LINK_ENTRY NewDataLinkCopy;
  656. KSTATUS Status;
  657. ASSERT(KeGetRunLevel() == RunLevelLow);
  658. LockHeld = FALSE;
  659. Handle = INVALID_HANDLE;
  660. NewDataLinkCopy = NULL;
  661. if ((NewDataLinkEntry->Domain == NetDomainInvalid) ||
  662. (NewDataLinkEntry->Interface.InitializeLink == NULL) ||
  663. (NewDataLinkEntry->Interface.DestroyLink == NULL) ||
  664. (NewDataLinkEntry->Interface.Send == NULL) ||
  665. (NewDataLinkEntry->Interface.ProcessReceivedPacket == NULL) ||
  666. (NewDataLinkEntry->Interface.GetBroadcastAddress == NULL) ||
  667. (NewDataLinkEntry->Interface.PrintAddress == NULL) ||
  668. (NewDataLinkEntry->Interface.GetPacketSizeInformation == NULL)) {
  669. Status = STATUS_INVALID_PARAMETER;
  670. goto RegisterDataLinkLayerEnd;
  671. }
  672. //
  673. // Create a copy of the new link entry.
  674. //
  675. NewDataLinkCopy = MmAllocatePagedPool(sizeof(NET_DATA_LINK_ENTRY),
  676. NET_CORE_ALLOCATION_TAG);
  677. if (NewDataLinkCopy == NULL) {
  678. Status = STATUS_INSUFFICIENT_RESOURCES;
  679. goto RegisterDataLinkLayerEnd;
  680. }
  681. RtlCopyMemory(NewDataLinkCopy,
  682. NewDataLinkEntry,
  683. sizeof(NET_DATA_LINK_ENTRY));
  684. KeAcquireSharedExclusiveLockExclusive(NetPluginListLock);
  685. LockHeld = TRUE;
  686. //
  687. // Loop through looking for a previous registration with this data link
  688. // type.
  689. //
  690. CurrentEntry = NetDataLinkList.Next;
  691. while (CurrentEntry != &NetDataLinkList) {
  692. DataLink = LIST_VALUE(CurrentEntry, NET_DATA_LINK_ENTRY, ListEntry);
  693. if (DataLink->Domain == NewDataLinkEntry->Domain) {
  694. Status = STATUS_DUPLICATE_ENTRY;
  695. goto RegisterDataLinkLayerEnd;
  696. }
  697. CurrentEntry = CurrentEntry->Next;
  698. }
  699. //
  700. // There are no duplicates, add this entry to the back of the list.
  701. //
  702. INSERT_BEFORE(&(NewDataLinkCopy->ListEntry), &NetDataLinkList);
  703. Status = STATUS_SUCCESS;
  704. Handle = NewDataLinkCopy;
  705. RegisterDataLinkLayerEnd:
  706. if (LockHeld != FALSE) {
  707. KeReleaseSharedExclusiveLockExclusive(NetPluginListLock);
  708. }
  709. if (!KSUCCESS(Status)) {
  710. if (NewDataLinkCopy != NULL) {
  711. MmFreePagedPool(NewDataLinkCopy);
  712. }
  713. }
  714. if (DataLinkHandle != NULL) {
  715. *DataLinkHandle = Handle;
  716. }
  717. return Status;
  718. }
  719. NET_API
  720. VOID
  721. NetUnregisterDataLinkLayer (
  722. HANDLE DataLinkHandle
  723. )
  724. /*++
  725. Routine Description:
  726. This routine unregisters the given data link layer from the core networking
  727. library.
  728. Arguments:
  729. DataLinkHandle - Supplies the handle to the data link layer to unregister.
  730. Return Value:
  731. None.
  732. --*/
  733. {
  734. PLIST_ENTRY CurrentEntry;
  735. PNET_DATA_LINK_ENTRY DataLink;
  736. PNET_DATA_LINK_ENTRY FoundDataLink;
  737. FoundDataLink = NULL;
  738. //
  739. // Loop through looking for a previous registration with this data link
  740. // handle.
  741. //
  742. KeAcquireSharedExclusiveLockExclusive(NetPluginListLock);
  743. CurrentEntry = NetDataLinkList.Next;
  744. while (CurrentEntry != &NetDataLinkList) {
  745. DataLink = LIST_VALUE(CurrentEntry, NET_DATA_LINK_ENTRY, ListEntry);
  746. if (DataLink == DataLinkHandle) {
  747. FoundDataLink = DataLink;
  748. LIST_REMOVE(CurrentEntry);
  749. break;
  750. }
  751. CurrentEntry = CurrentEntry->Next;
  752. }
  753. KeReleaseSharedExclusiveLockExclusive(NetPluginListLock);
  754. if (FoundDataLink != NULL) {
  755. MmFreePagedPool(FoundDataLink);
  756. }
  757. return;
  758. }
  759. NET_API
  760. PNET_NETWORK_ENTRY
  761. NetGetNetworkEntry (
  762. ULONG ParentProtocolNumber
  763. )
  764. /*++
  765. Routine Description:
  766. This routine looks up a registered network layer given the parent protocol
  767. number.
  768. Arguments:
  769. ParentProtocolNumber - Supplies the parent protocol number of the desired
  770. network layer.
  771. Return Value:
  772. Returns a pointer to the network layer entry on success.
  773. --*/
  774. {
  775. PLIST_ENTRY CurrentEntry;
  776. PNET_NETWORK_ENTRY NetworkEntry;
  777. BOOL NetworkFound;
  778. //
  779. // Try the common ones first before going heavy by acquiring the lock and
  780. // looping over the list.
  781. //
  782. if (ParentProtocolNumber == IP4_PROTOCOL_NUMBER) {
  783. NetworkEntry = NetIp4NetworkEntry;
  784. } else if (ParentProtocolNumber == ARP_PROTOCOL_NUMBER) {
  785. NetworkEntry = NetArpNetworkEntry;
  786. } else if (ParentProtocolNumber == IP6_PROTOCOL_NUMBER) {
  787. NetworkEntry = NetIp6NetworkEntry;
  788. } else {
  789. //
  790. // Search through the list of known network entries.
  791. //
  792. NetworkEntry = NULL;
  793. NetworkFound = FALSE;
  794. KeAcquireSharedExclusiveLockShared(NetPluginListLock);
  795. CurrentEntry = NetNetworkList.Next;
  796. while (CurrentEntry != &NetNetworkList) {
  797. NetworkEntry = LIST_VALUE(CurrentEntry,
  798. NET_NETWORK_ENTRY,
  799. ListEntry);
  800. if (NetworkEntry->ParentProtocolNumber == ParentProtocolNumber) {
  801. NetworkFound = TRUE;
  802. break;
  803. }
  804. CurrentEntry = CurrentEntry->Next;
  805. }
  806. KeReleaseSharedExclusiveLockShared(NetPluginListLock);
  807. if (NetworkFound == FALSE) {
  808. return NULL;
  809. }
  810. }
  811. return NetworkEntry;
  812. }
  813. NET_API
  814. PNET_PROTOCOL_ENTRY
  815. NetGetProtocolEntry (
  816. ULONG ParentProtocolNumber
  817. )
  818. /*++
  819. Routine Description:
  820. This routine looks up a registered protocol layer given the parent protocol
  821. number.
  822. Arguments:
  823. ParentProtocolNumber - Supplies the parent protocol number of the desired
  824. protocol layer.
  825. Return Value:
  826. Returns a pointer to the protocol layer entry on success.
  827. --*/
  828. {
  829. PLIST_ENTRY CurrentEntry;
  830. PNET_PROTOCOL_ENTRY ProtocolEntry;
  831. BOOL ProtocolFound;
  832. //
  833. // Try the common ones first before getting heavy with the spin lock.
  834. //
  835. if (ParentProtocolNumber == SOCKET_INTERNET_PROTOCOL_TCP) {
  836. ProtocolEntry = NetTcpProtocolEntry;
  837. } else if (ParentProtocolNumber == SOCKET_INTERNET_PROTOCOL_UDP) {
  838. ProtocolEntry = NetUdpProtocolEntry;
  839. } else if (ParentProtocolNumber == SOCKET_INTERNET_PROTOCOL_RAW) {
  840. ProtocolEntry = NetRawProtocolEntry;
  841. } else {
  842. //
  843. // Search through the list of known protocols.
  844. //
  845. ProtocolEntry = NULL;
  846. ProtocolFound = FALSE;
  847. KeAcquireSharedExclusiveLockShared(NetPluginListLock);
  848. CurrentEntry = NetProtocolList.Next;
  849. while (CurrentEntry != &NetProtocolList) {
  850. ProtocolEntry = LIST_VALUE(CurrentEntry,
  851. NET_PROTOCOL_ENTRY,
  852. ListEntry);
  853. if (ProtocolEntry->ParentProtocolNumber == ParentProtocolNumber) {
  854. ProtocolFound = TRUE;
  855. break;
  856. }
  857. CurrentEntry = CurrentEntry->Next;
  858. }
  859. KeReleaseSharedExclusiveLockShared(NetPluginListLock);
  860. if (ProtocolFound == FALSE) {
  861. return NULL;
  862. }
  863. }
  864. return ProtocolEntry;
  865. }
  866. NET_API
  867. VOID
  868. NetProcessReceivedPacket (
  869. PNET_LINK Link,
  870. PNET_PACKET_BUFFER Packet
  871. )
  872. /*++
  873. Routine Description:
  874. This routine is called by the low level NIC driver to pass received packets
  875. onto the core networking library for dispatching.
  876. Arguments:
  877. Link - Supplies a pointer to the link that received the packet.
  878. Packet - Supplies a pointer to a structure describing the incoming packet.
  879. This structure may be used as a scratch space while this routine
  880. executes and the packet travels up the stack, but will not be accessed
  881. after this routine returns.
  882. Return Value:
  883. None. When the function returns, the memory associated with the packet may
  884. be reclaimed and reused.
  885. --*/
  886. {
  887. //
  888. // Call the data link layer to process the packet.
  889. //
  890. Link->DataLinkEntry->Interface.ProcessReceivedPacket(Link->DataLinkContext,
  891. Packet);
  892. return;
  893. }
  894. NET_API
  895. BOOL
  896. NetGetGlobalDebugFlag (
  897. VOID
  898. )
  899. /*++
  900. Routine Description:
  901. This routine returns the current value of the global networking debug flag.
  902. Arguments:
  903. None.
  904. Return Value:
  905. TRUE if debug information should be collected throughout the networking
  906. subsystem.
  907. FALSE if verbose debug information should be suppressed globally.
  908. --*/
  909. {
  910. return NetGlobalDebug;
  911. }
  912. NET_API
  913. VOID
  914. NetDebugPrintAddress (
  915. PNETWORK_ADDRESS Address
  916. )
  917. /*++
  918. Routine Description:
  919. This routine prints the given address to the debug console.
  920. Arguments:
  921. Address - Supplies a pointer to the address to print.
  922. Return Value:
  923. None.
  924. --*/
  925. {
  926. PLIST_ENTRY CurrentEntry;
  927. PNET_DATA_LINK_ENTRY DataLinkEntry;
  928. ULONG Length;
  929. PNET_NETWORK_ENTRY NetworkEntry;
  930. CHAR StringBuffer[NET_PRINT_ADDRESS_STRING_LENGTH];
  931. if (Address == NULL) {
  932. RtlDebugPrint("(NullNetworkAddress)");
  933. return;
  934. }
  935. StringBuffer[0] = '\0';
  936. //
  937. // If the address is a physical one, find the data link layer and print the
  938. // string.
  939. //
  940. KeAcquireSharedExclusiveLockShared(NetPluginListLock);
  941. if (NET_IS_PHYSICAL_DOMAIN(Address->Domain) != FALSE) {
  942. CurrentEntry = NetDataLinkList.Next;
  943. while (CurrentEntry != &NetDataLinkList) {
  944. DataLinkEntry = LIST_VALUE(CurrentEntry,
  945. NET_DATA_LINK_ENTRY,
  946. ListEntry);
  947. if (DataLinkEntry->Domain == Address->Domain) {
  948. Length = DataLinkEntry->Interface.PrintAddress(
  949. Address,
  950. StringBuffer,
  951. NET_PRINT_ADDRESS_STRING_LENGTH);
  952. ASSERT(Length <= NET_PRINT_ADDRESS_STRING_LENGTH);
  953. break;
  954. }
  955. CurrentEntry = CurrentEntry->Next;
  956. }
  957. //
  958. // Otherwise, find the network layer and print this string.
  959. //
  960. } else {
  961. CurrentEntry = NetNetworkList.Next;
  962. while (CurrentEntry != &NetNetworkList) {
  963. NetworkEntry = LIST_VALUE(CurrentEntry,
  964. NET_NETWORK_ENTRY,
  965. ListEntry);
  966. if (NetworkEntry->Domain == Address->Domain) {
  967. Length = NetworkEntry->Interface.PrintAddress(
  968. Address,
  969. StringBuffer,
  970. NET_PRINT_ADDRESS_STRING_LENGTH);
  971. ASSERT(Length <= NET_PRINT_ADDRESS_STRING_LENGTH);
  972. break;
  973. }
  974. CurrentEntry = CurrentEntry->Next;
  975. }
  976. }
  977. KeReleaseSharedExclusiveLockShared(NetPluginListLock);
  978. StringBuffer[NET_PRINT_ADDRESS_STRING_LENGTH - 1] = '\0';
  979. RtlDebugPrint("%s", StringBuffer);
  980. return;
  981. }
  982. KSTATUS
  983. NetCreateSocket (
  984. NET_DOMAIN_TYPE Domain,
  985. NET_SOCKET_TYPE Type,
  986. ULONG Protocol,
  987. PSOCKET *NewSocket
  988. )
  989. /*++
  990. Routine Description:
  991. This routine allocates resources associated with a new socket. The core
  992. networking driver is responsible for allocating the structure (with
  993. additional length for any of its context). The kernel will fill in the
  994. common header when this routine returns.
  995. Arguments:
  996. Domain - Supplies the network domain to use on the socket.
  997. Type - Supplies the socket connection type.
  998. Protocol - Supplies the raw protocol value for this socket used on the
  999. network. This value is network specific.
  1000. NewSocket - Supplies a pointer where a pointer to a newly allocated
  1001. socket structure will be returned. The caller is responsible for
  1002. allocating the socket (and potentially a larger structure for its own
  1003. context). The kernel will fill in the standard socket structure after
  1004. this routine returns.
  1005. Return Value:
  1006. Status code.
  1007. --*/
  1008. {
  1009. PLIST_ENTRY CurrentEntry;
  1010. PNET_NETWORK_ENTRY NetworkEntry;
  1011. BOOL NetworkFound;
  1012. PNET_PROTOCOL_ENTRY ProtocolEntry;
  1013. BOOL ProtocolFound;
  1014. PNET_SOCKET Socket;
  1015. KSTATUS Status;
  1016. Socket = NULL;
  1017. NetworkEntry = NULL;
  1018. ProtocolEntry = NULL;
  1019. //
  1020. // If the domain is not within the bounds of the socket portion of the
  1021. // net domain namespace, error out immediately.
  1022. //
  1023. if (NET_IS_SOCKET_NETWORK_DOMAIN(Domain) == FALSE) {
  1024. Status = STATUS_DOMAIN_NOT_SUPPORTED;
  1025. goto CreateSocketEnd;
  1026. }
  1027. //
  1028. // Attempt to find a handler for this protocol and network. Make sure that
  1029. // the supplied network protocol matches the found protocol entry's parent
  1030. // protocol. If not, then it's a protocol for a different network.
  1031. //
  1032. ProtocolFound = FALSE;
  1033. NetworkFound = FALSE;
  1034. KeAcquireSharedExclusiveLockShared(NetPluginListLock);
  1035. CurrentEntry = NetProtocolList.Next;
  1036. while (CurrentEntry != &NetProtocolList) {
  1037. ProtocolEntry = LIST_VALUE(CurrentEntry, NET_PROTOCOL_ENTRY, ListEntry);
  1038. CurrentEntry = CurrentEntry->Next;
  1039. if (ProtocolEntry->Type != Type) {
  1040. continue;
  1041. }
  1042. if ((Type != NetSocketRaw) &&
  1043. (Protocol != 0) &&
  1044. (ProtocolEntry->ParentProtocolNumber != Protocol)) {
  1045. continue;
  1046. }
  1047. ProtocolFound = TRUE;
  1048. break;
  1049. }
  1050. CurrentEntry = NetNetworkList.Next;
  1051. while (CurrentEntry != &NetNetworkList) {
  1052. NetworkEntry = LIST_VALUE(CurrentEntry, NET_NETWORK_ENTRY, ListEntry);
  1053. if (NetworkEntry->Domain == Domain) {
  1054. NetworkFound = TRUE;
  1055. break;
  1056. }
  1057. CurrentEntry = CurrentEntry->Next;
  1058. }
  1059. KeReleaseSharedExclusiveLockShared(NetPluginListLock);
  1060. if (NetworkFound == FALSE) {
  1061. Status = STATUS_DOMAIN_NOT_SUPPORTED;
  1062. goto CreateSocketEnd;
  1063. }
  1064. if (ProtocolFound == FALSE) {
  1065. Status = STATUS_PROTOCOL_NOT_SUPPORTED;
  1066. goto CreateSocketEnd;
  1067. }
  1068. if (Protocol == 0) {
  1069. Protocol = ProtocolEntry->ParentProtocolNumber;
  1070. }
  1071. //
  1072. // Call the protocol to create the socket.
  1073. //
  1074. Status = ProtocolEntry->Interface.CreateSocket(ProtocolEntry,
  1075. NetworkEntry,
  1076. Protocol,
  1077. &Socket);
  1078. if (!KSUCCESS(Status)) {
  1079. goto CreateSocketEnd;
  1080. }
  1081. //
  1082. // Initialize core networking common parameters.
  1083. //
  1084. Socket->Protocol = ProtocolEntry;
  1085. Socket->Network = NetworkEntry;
  1086. Socket->BindingType = SocketBindingInvalid;
  1087. Socket->LastError = STATUS_SUCCESS;
  1088. RtlCopyMemory(&(Socket->UnboundPacketSizeInformation),
  1089. &(Socket->PacketSizeInformation),
  1090. sizeof(NET_PACKET_SIZE_INFORMATION));
  1091. CreateSocketEnd:
  1092. if (!KSUCCESS(Status)) {
  1093. if (Socket != NULL) {
  1094. ProtocolEntry->Interface.Close(Socket);
  1095. Socket = NULL;
  1096. }
  1097. }
  1098. if (NetGlobalDebug != FALSE) {
  1099. RtlDebugPrint("Net: Create socket (%d, %d, %d): 0x%x: %d\n",
  1100. Domain,
  1101. Type,
  1102. Protocol,
  1103. Socket,
  1104. Status);
  1105. }
  1106. *NewSocket = (PSOCKET)Socket;
  1107. return Status;
  1108. }
  1109. VOID
  1110. NetDestroySocket (
  1111. PSOCKET Socket
  1112. )
  1113. /*++
  1114. Routine Description:
  1115. This routine destroys resources associated with an open socket, officially
  1116. marking the end of the kernel's knowledge of this structure. It is called
  1117. automatically when a socket's reference count drops to zero.
  1118. Arguments:
  1119. Socket - Supplies a pointer to the socket to destroy. The kernel will have
  1120. already destroyed any resources inside the common header, the core
  1121. networking library should not reach through any pointers inside the
  1122. socket header.
  1123. Return Value:
  1124. None. This routine is responsible for freeing the memory associated with
  1125. the socket structure itself.
  1126. --*/
  1127. {
  1128. PNET_SOCKET NetSocket;
  1129. NetSocket = (PNET_SOCKET)Socket;
  1130. if (NetGlobalDebug != FALSE) {
  1131. RtlDebugPrint("Net: Destroy socket 0x%x\n", NetSocket);
  1132. }
  1133. if (NetSocket->Link != NULL) {
  1134. NetLinkReleaseReference(NetSocket->Link);
  1135. NetSocket->Link = NULL;
  1136. }
  1137. NetSocket->Protocol->Interface.DestroySocket(NetSocket);
  1138. return;
  1139. }
  1140. KSTATUS
  1141. NetBindToAddress (
  1142. PSOCKET Socket,
  1143. PVOID Link,
  1144. PNETWORK_ADDRESS Address
  1145. )
  1146. /*++
  1147. Routine Description:
  1148. This routine binds the socket to the given address and starts listening for
  1149. client requests.
  1150. Arguments:
  1151. Socket - Supplies a pointer to the socket to bind.
  1152. Link - Supplies an optional pointer to a link to bind to.
  1153. Address - Supplies a pointer to the address to bind the socket to.
  1154. Return Value:
  1155. Status code.
  1156. --*/
  1157. {
  1158. PNET_SOCKET NetSocket;
  1159. KSTATUS Status;
  1160. NetSocket = (PNET_SOCKET)Socket;
  1161. Status = NetSocket->Protocol->Interface.BindToAddress(NetSocket,
  1162. Link,
  1163. Address);
  1164. if (!KSUCCESS(Status)) {
  1165. goto BindToAddressEnd;
  1166. }
  1167. Status = STATUS_SUCCESS;
  1168. BindToAddressEnd:
  1169. if (NetGlobalDebug != FALSE) {
  1170. RtlDebugPrint("Net: Bind socket 0x%x to ", NetSocket);
  1171. NetDebugPrintAddress(Address);
  1172. RtlDebugPrint(" on link 0x%08x: %d.\n", Link, Status);
  1173. }
  1174. return Status;
  1175. }
  1176. KSTATUS
  1177. NetListen (
  1178. PSOCKET Socket,
  1179. ULONG BacklogCount
  1180. )
  1181. /*++
  1182. Routine Description:
  1183. This routine adds a bound socket to the list of listening sockets,
  1184. officially allowing sockets to attempt to connect to it.
  1185. Arguments:
  1186. Socket - Supplies a pointer to the socket to mark as listening.
  1187. BacklogCount - Supplies the number of attempted connections that can be
  1188. queued before additional connections are refused.
  1189. Return Value:
  1190. Status code.
  1191. --*/
  1192. {
  1193. NETWORK_ADDRESS LocalAddress;
  1194. PNET_SOCKET NetSocket;
  1195. KSTATUS Status;
  1196. NetSocket = (PNET_SOCKET)Socket;
  1197. if ((BacklogCount == 0) || (BacklogCount > NET_MAX_INCOMING_CONNECTIONS)) {
  1198. BacklogCount = NET_MAX_INCOMING_CONNECTIONS;
  1199. }
  1200. NetSocket->MaxIncomingConnections = BacklogCount;
  1201. //
  1202. // If the socket is not yet bound, bind it to any address and a random
  1203. // port.
  1204. //
  1205. if (NetSocket->BindingType == SocketBindingInvalid) {
  1206. RtlZeroMemory(&LocalAddress, sizeof(NETWORK_ADDRESS));
  1207. LocalAddress.Domain = NetSocket->Network->Domain;
  1208. Status = NetBindToAddress(Socket, NULL, &LocalAddress);
  1209. if (!KSUCCESS(Status)) {
  1210. if (NetGlobalDebug != FALSE) {
  1211. RtlDebugPrint("Net: Socket 0x%x implicit bind in listen "
  1212. "failed: %d\n",
  1213. NetSocket,
  1214. Status);
  1215. }
  1216. return Status;
  1217. }
  1218. }
  1219. Status = NetSocket->Protocol->Interface.Listen(NetSocket);
  1220. if (NetGlobalDebug != FALSE) {
  1221. RtlDebugPrint("Net: Socket 0x%x listen %d: %d\n",
  1222. NetSocket,
  1223. BacklogCount,
  1224. Status);
  1225. }
  1226. return Status;
  1227. }
  1228. KSTATUS
  1229. NetAccept (
  1230. PSOCKET Socket,
  1231. PIO_HANDLE *NewConnectionSocket,
  1232. PNETWORK_ADDRESS RemoteAddress
  1233. )
  1234. /*++
  1235. Routine Description:
  1236. This routine accepts an incoming connection on a listening connection-based
  1237. socket.
  1238. Arguments:
  1239. Socket - Supplies a pointer to the socket to accept a connection from.
  1240. NewConnectionSocket - Supplies a pointer where a new socket will be
  1241. returned that represents the accepted connection with the remote
  1242. host.
  1243. RemoteAddress - Supplies a pointer where the address of the connected
  1244. remote host will be returned.
  1245. Return Value:
  1246. Status code.
  1247. --*/
  1248. {
  1249. PNET_SOCKET NetSocket;
  1250. KSTATUS Status;
  1251. NetSocket = (PNET_SOCKET)Socket;
  1252. if (NetGlobalDebug != FALSE) {
  1253. RtlDebugPrint("Net: Socket 0x%x accept...\n", NetSocket);
  1254. }
  1255. Status = NetSocket->Protocol->Interface.Accept(NetSocket,
  1256. NewConnectionSocket,
  1257. RemoteAddress);
  1258. if (NetGlobalDebug != FALSE) {
  1259. RtlDebugPrint("Net: Socket 0x%x accepted ", NetSocket);
  1260. if (RemoteAddress != NULL) {
  1261. NetDebugPrintAddress(RemoteAddress);
  1262. }
  1263. RtlDebugPrint("\n");
  1264. }
  1265. return Status;
  1266. }
  1267. KSTATUS
  1268. NetConnect (
  1269. PSOCKET Socket,
  1270. PNETWORK_ADDRESS Address
  1271. )
  1272. /*++
  1273. Routine Description:
  1274. This routine attempts to make an outgoing connection to a server.
  1275. Arguments:
  1276. Socket - Supplies a pointer to the socket to use for the connection.
  1277. Address - Supplies a pointer to the address to connect to.
  1278. Return Value:
  1279. Status code.
  1280. --*/
  1281. {
  1282. PNET_SOCKET NetSocket;
  1283. KSTATUS Status;
  1284. NetSocket = (PNET_SOCKET)Socket;
  1285. if (NetGlobalDebug != FALSE) {
  1286. RtlDebugPrint("Net: Connecting socket 0x%x to ", NetSocket);
  1287. NetDebugPrintAddress(Address);
  1288. RtlDebugPrint("...\n");
  1289. }
  1290. Status = NetSocket->Protocol->Interface.Connect(NetSocket, Address);
  1291. if (NetGlobalDebug != FALSE) {
  1292. RtlDebugPrint("Net: Connect socket 0x%x to ", NetSocket);
  1293. NetDebugPrintAddress(Address);
  1294. RtlDebugPrint(" : %d\n", Status);
  1295. }
  1296. return Status;
  1297. }
  1298. KSTATUS
  1299. NetCloseSocket (
  1300. PSOCKET Socket
  1301. )
  1302. /*++
  1303. Routine Description:
  1304. This routine closes a socket connection.
  1305. Arguments:
  1306. Socket - Supplies a pointer to the socket to shut down.
  1307. Return Value:
  1308. Status code.
  1309. --*/
  1310. {
  1311. PNET_SOCKET NetSocket;
  1312. NetSocket = (PNET_SOCKET)Socket;
  1313. if (NetGlobalDebug != FALSE) {
  1314. RtlDebugPrint("Net: Close 0x%x\n", NetSocket);
  1315. }
  1316. return NetSocket->Protocol->Interface.Close(NetSocket);
  1317. }
  1318. KSTATUS
  1319. NetSendData (
  1320. BOOL FromKernelMode,
  1321. PSOCKET Socket,
  1322. PSOCKET_IO_PARAMETERS Parameters,
  1323. PIO_BUFFER IoBuffer
  1324. )
  1325. /*++
  1326. Routine Description:
  1327. This routine sends the given data buffer through the network.
  1328. Arguments:
  1329. FromKernelMode - Supplies a boolean indicating whether the request is
  1330. coming from kernel mode (TRUE) or user mode (FALSE).
  1331. Socket - Supplies a pointer to the socket to send the data to.
  1332. Parameters - Supplies a pointer to the socket I/O parameters. This will
  1333. always be a kernel mode pointer.
  1334. IoBuffer - Supplies a pointer to the I/O buffer containing the data to
  1335. send.
  1336. Return Value:
  1337. Status code.
  1338. --*/
  1339. {
  1340. PNET_SOCKET NetSocket;
  1341. KSTATUS Status;
  1342. NetSocket = (PNET_SOCKET)Socket;
  1343. if (NetGlobalDebug != FALSE) {
  1344. RtlDebugPrint("Net: Sending %ld on socket 0x%x...\n",
  1345. Parameters->Size,
  1346. NetSocket);
  1347. }
  1348. Status = NetSocket->Protocol->Interface.Send(FromKernelMode,
  1349. NetSocket,
  1350. Parameters,
  1351. IoBuffer);
  1352. if (NetGlobalDebug != FALSE) {
  1353. RtlDebugPrint("Net: Sent %ld on socket 0x%x: %d.\n",
  1354. Parameters->Size,
  1355. NetSocket,
  1356. Status);
  1357. }
  1358. return Status;
  1359. }
  1360. KSTATUS
  1361. NetReceiveData (
  1362. BOOL FromKernelMode,
  1363. PSOCKET Socket,
  1364. PSOCKET_IO_PARAMETERS Parameters,
  1365. PIO_BUFFER IoBuffer
  1366. )
  1367. /*++
  1368. Routine Description:
  1369. This routine is called by the user to receive data from the socket.
  1370. Arguments:
  1371. FromKernelMode - Supplies a boolean indicating whether the request is
  1372. coming from kernel mode (TRUE) or user mode (FALSE).
  1373. Socket - Supplies a pointer to the socket to receive data from.
  1374. Parameters - Supplies a pointer to the socket I/O parameters.
  1375. IoBuffer - Supplies a pointer to the I/O buffer where the received data
  1376. will be returned.
  1377. Return Value:
  1378. STATUS_SUCCESS if any bytes were read.
  1379. STATUS_TIMEOUT if the request timed out.
  1380. STATUS_BUFFER_TOO_SMALL if the incoming datagram was too large for the
  1381. buffer. The remainder of the datagram is discarded in this case.
  1382. Other error codes on other failures.
  1383. --*/
  1384. {
  1385. PNET_SOCKET NetSocket;
  1386. KSTATUS Status;
  1387. NetSocket = (PNET_SOCKET)Socket;
  1388. if (NetGlobalDebug != FALSE) {
  1389. RtlDebugPrint("Net: Receiving %ld on socket 0x%x...\n",
  1390. Parameters->Size,
  1391. NetSocket);
  1392. }
  1393. Status = NetSocket->Protocol->Interface.Receive(FromKernelMode,
  1394. NetSocket,
  1395. Parameters,
  1396. IoBuffer);
  1397. if (NetGlobalDebug != FALSE) {
  1398. RtlDebugPrint("Net: Received %ld on socket 0x%x: %d.\n",
  1399. Parameters->Size,
  1400. NetSocket,
  1401. Status);
  1402. }
  1403. return Status;
  1404. }
  1405. KSTATUS
  1406. NetGetSetSocketInformation (
  1407. PSOCKET Socket,
  1408. SOCKET_INFORMATION_TYPE InformationType,
  1409. UINTN Option,
  1410. PVOID Data,
  1411. PUINTN DataSize,
  1412. BOOL Set
  1413. )
  1414. /*++
  1415. Routine Description:
  1416. This routine returns information about the given socket.
  1417. Arguments:
  1418. Socket - Supplies a pointer to the socket to get or set information for.
  1419. InformationType - Supplies the socket information type category to which
  1420. specified option belongs.
  1421. Option - Supplies the option to get or set, which is specific to the
  1422. information type. The type of this value is generally
  1423. SOCKET_<information_type>_OPTION.
  1424. Data - Supplies a pointer to the data buffer where the data is either
  1425. returned for a get operation or given for a set operation.
  1426. DataSize - Supplies a pointer that on input constains the size of the data
  1427. buffer. On output, this contains the required size of the data buffer.
  1428. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  1429. a set operation (TRUE).
  1430. Return Value:
  1431. STATUS_SUCCESS on success.
  1432. STATUS_INVALID_PARAMETER if the information type is incorrect.
  1433. STATUS_BUFFER_TOO_SMALL if the data buffer is too small to receive the
  1434. requested option.
  1435. STATUS_NOT_SUPPORTED_BY_PROTOCOL if the socket option is not supported by
  1436. the socket.
  1437. --*/
  1438. {
  1439. NETWORK_ADDRESS Address;
  1440. SOCKET_BASIC_OPTION BasicOption;
  1441. ULONG BooleanOption;
  1442. ULONG Count;
  1443. KSTATUS ErrorOption;
  1444. ULONG Flags;
  1445. ULONG Index;
  1446. PNET_SOCKET NetSocket;
  1447. PNET_PROTOCOL_ENTRY Protocol;
  1448. PNET_SOCKET_OPTION SocketOption;
  1449. SOCKET_TIME SocketTime;
  1450. PVOID Source;
  1451. KSTATUS Status;
  1452. NetSocket = (PNET_SOCKET)Socket;
  1453. Protocol = NetSocket->Protocol;
  1454. Status = STATUS_SUCCESS;
  1455. //
  1456. // If the requested option is something that this layer can answer, then
  1457. // answer it.
  1458. //
  1459. switch (InformationType) {
  1460. case SocketInformationBasic:
  1461. //
  1462. // Send the call down to the protocol layer, which can override a basic
  1463. // option's default behavior. If the not handled status is returned,
  1464. // then the protocol did not override the default behavior.
  1465. //
  1466. Status = NetSocket->Protocol->Interface.GetSetInformation(
  1467. NetSocket,
  1468. InformationType,
  1469. Option,
  1470. Data,
  1471. DataSize,
  1472. Set);
  1473. if (Status != STATUS_NOT_HANDLED) {
  1474. goto GetSetSocketInformationEnd;
  1475. }
  1476. //
  1477. // Search to see if there is a default behavior for the socket option.
  1478. //
  1479. Count = sizeof(NetBasicSocketOptions) /
  1480. sizeof(NetBasicSocketOptions[0]);
  1481. for (Index = 0; Index < Count; Index += 1) {
  1482. SocketOption = &(NetBasicSocketOptions[Index]);
  1483. if ((SocketOption->InformationType == InformationType) &&
  1484. (SocketOption->Option == Option)) {
  1485. break;
  1486. }
  1487. }
  1488. if (Index == Count) {
  1489. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  1490. goto GetSetSocketInformationEnd;
  1491. }
  1492. //
  1493. // Handle failure cases common to all options.
  1494. //
  1495. if (Set != FALSE) {
  1496. if (SocketOption->SetAllowed == FALSE) {
  1497. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  1498. goto GetSetSocketInformationEnd;
  1499. }
  1500. if (*DataSize < SocketOption->Size) {
  1501. *DataSize = SocketOption->Size;
  1502. Status = STATUS_BUFFER_TOO_SMALL;
  1503. goto GetSetSocketInformationEnd;
  1504. }
  1505. }
  1506. //
  1507. // Truncate all copies for get requests down to the required size and
  1508. // only return the required size on set requests.
  1509. //
  1510. if (*DataSize > SocketOption->Size) {
  1511. *DataSize = SocketOption->Size;
  1512. }
  1513. Source = NULL;
  1514. Status = STATUS_SUCCESS;
  1515. BasicOption = (SOCKET_BASIC_OPTION)Option;
  1516. switch (BasicOption) {
  1517. case SocketBasicOptionType:
  1518. ASSERT(Set == FALSE);
  1519. Source = &(Socket->Type);
  1520. break;
  1521. case SocketBasicOptionDomain:
  1522. ASSERT(Set == FALSE);
  1523. Source = &(Socket->Domain);
  1524. break;
  1525. case SocketBasicOptionLocalAddress:
  1526. case SocketBasicOptionRemoteAddress:
  1527. ASSERT(Set == FALSE);
  1528. //
  1529. // Socket addresses are synchronized on the protocol's socket tree.
  1530. // Acquire the lock to not return a torn address.
  1531. //
  1532. if (NetSocket->KernelSocket.Type == NetSocketRaw) {
  1533. KeAcquireSharedExclusiveLockShared(NetRawSocketsLock);
  1534. } else {
  1535. KeAcquireSharedExclusiveLockShared(Protocol->SocketLock);
  1536. }
  1537. if (BasicOption == SocketBasicOptionLocalAddress) {
  1538. RtlCopyMemory(&Address,
  1539. &(NetSocket->LocalAddress),
  1540. sizeof(NETWORK_ADDRESS));
  1541. //
  1542. // Even if the local address is not yet initialized, return the
  1543. // any address and any port on the correct network.
  1544. //
  1545. if (Address.Domain == NetDomainInvalid) {
  1546. Address.Domain = NetSocket->KernelSocket.Domain;
  1547. }
  1548. //
  1549. // The port should be zero for all raw sockets. The address
  1550. // request returns the protocol as the port value.
  1551. //
  1552. if (NetSocket->KernelSocket.Type == NetSocketRaw) {
  1553. Address.Port = NetSocket->KernelSocket.Protocol;
  1554. }
  1555. RtlCopyMemory(Data, &Address, *DataSize);
  1556. } else {
  1557. ASSERT(BasicOption == SocketBasicOptionRemoteAddress);
  1558. RtlCopyMemory(Data, &(NetSocket->RemoteAddress), *DataSize);
  1559. }
  1560. if (NetSocket->KernelSocket.Type == NetSocketRaw) {
  1561. KeReleaseSharedExclusiveLockShared(NetRawSocketsLock);
  1562. } else {
  1563. KeReleaseSharedExclusiveLockShared(Protocol->SocketLock);
  1564. }
  1565. break;
  1566. case SocketBasicOptionReuseAnyAddress:
  1567. case SocketBasicOptionReuseTimeWait:
  1568. case SocketBasicOptionReuseExactAddress:
  1569. case SocketBasicOptionBroadcastEnabled:
  1570. if (BasicOption == SocketBasicOptionReuseAnyAddress) {
  1571. Flags = NET_SOCKET_FLAG_REUSE_ANY_ADDRESS |
  1572. NET_SOCKET_FLAG_REUSE_TIME_WAIT;
  1573. } else if (BasicOption == SocketBasicOptionReuseTimeWait) {
  1574. Flags = NET_SOCKET_FLAG_REUSE_TIME_WAIT;
  1575. } else if (BasicOption == SocketBasicOptionReuseExactAddress) {
  1576. Flags = NET_SOCKET_FLAG_REUSE_EXACT_ADDRESS;
  1577. } else {
  1578. ASSERT(BasicOption == SocketBasicOptionBroadcastEnabled);
  1579. Flags = NET_SOCKET_FLAG_BROADCAST_ENABLED;
  1580. }
  1581. if (Set != FALSE) {
  1582. if (*((PULONG)Data) != FALSE) {
  1583. RtlAtomicOr32(&(NetSocket->Flags), Flags);
  1584. } else {
  1585. RtlAtomicAnd32(&(NetSocket->Flags), ~Flags);
  1586. }
  1587. } else {
  1588. Source = &BooleanOption;
  1589. BooleanOption = FALSE;
  1590. if ((NetSocket->Flags & Flags) == Flags) {
  1591. BooleanOption = TRUE;
  1592. }
  1593. }
  1594. break;
  1595. case SocketBasicOptionErrorStatus:
  1596. ASSERT(Set == FALSE);
  1597. ASSERT(sizeof(KSTATUS) == sizeof(ULONG));
  1598. ErrorOption = NET_SOCKET_GET_AND_CLEAR_LAST_ERROR(NetSocket);
  1599. Source = &ErrorOption;
  1600. break;
  1601. case SocketBasicOptionAcceptConnections:
  1602. ASSERT(Set == FALSE);
  1603. Source = &BooleanOption;
  1604. BooleanOption = FALSE;
  1605. break;
  1606. case SocketBasicOptionSendTimeout:
  1607. ASSERT(Set == FALSE);
  1608. //
  1609. // The indefinite wait time is represented as 0 time for the
  1610. // SOCKET_TIME structure.
  1611. //
  1612. SocketTime.Seconds = 0;
  1613. SocketTime.Microseconds = 0;
  1614. Source = &SocketTime;
  1615. break;
  1616. case SocketBasicOptionDebug:
  1617. case SocketBasicOptionInlineOutOfBand:
  1618. case SocketBasicOptionRoutingDisabled:
  1619. //
  1620. // TODO: Implement network routing and urgent messages.
  1621. //
  1622. default:
  1623. ASSERT(FALSE);
  1624. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  1625. break;
  1626. }
  1627. if (!KSUCCESS(Status)) {
  1628. break;
  1629. }
  1630. //
  1631. // For get requests, copy the gathered information to the supplied data
  1632. // buffer.
  1633. //
  1634. if (Set == FALSE) {
  1635. if (Source != NULL) {
  1636. RtlCopyMemory(Data, Source, *DataSize);
  1637. }
  1638. //
  1639. // If the copy truncated the data, report that the given buffer was
  1640. // too small. The caller can choose to ignore this if the truncated
  1641. // data is enough.
  1642. //
  1643. if (*DataSize < SocketOption->Size) {
  1644. *DataSize = SocketOption->Size;
  1645. Status = STATUS_BUFFER_TOO_SMALL;
  1646. }
  1647. }
  1648. break;
  1649. //
  1650. // IPv4 and IPv6 socket information is handled at the network layer.
  1651. //
  1652. case SocketInformationIp4:
  1653. case SocketInformationIp6:
  1654. case SocketInformationNetlink:
  1655. Status = NetSocket->Network->Interface.GetSetInformation(
  1656. NetSocket,
  1657. InformationType,
  1658. Option,
  1659. Data,
  1660. DataSize,
  1661. Set);
  1662. if (!KSUCCESS(Status)) {
  1663. goto GetSetSocketInformationEnd;
  1664. }
  1665. break;
  1666. //
  1667. // TCP and UDP socket information is handled at the protocol layer.
  1668. //
  1669. case SocketInformationTcp:
  1670. case SocketInformationUdp:
  1671. case SocketInformationNetlinkGeneric:
  1672. Status = NetSocket->Protocol->Interface.GetSetInformation(
  1673. NetSocket,
  1674. InformationType,
  1675. Option,
  1676. Data,
  1677. DataSize,
  1678. Set);
  1679. if (!KSUCCESS(Status)) {
  1680. goto GetSetSocketInformationEnd;
  1681. }
  1682. break;
  1683. default:
  1684. Status = STATUS_INVALID_PARAMETER;
  1685. break;
  1686. }
  1687. GetSetSocketInformationEnd:
  1688. if (NetGlobalDebug != FALSE) {
  1689. RtlDebugPrint("Net: GetSetSocketInformation on socket 0x%x: %d.\n",
  1690. NetSocket,
  1691. Status);
  1692. }
  1693. return Status;
  1694. }
  1695. KSTATUS
  1696. NetShutdown (
  1697. PSOCKET Socket,
  1698. ULONG ShutdownType
  1699. )
  1700. /*++
  1701. Routine Description:
  1702. This routine shuts down communication with a given socket.
  1703. Arguments:
  1704. Socket - Supplies a pointer to the socket.
  1705. ShutdownType - Supplies the shutdown type to perform. See the
  1706. SOCKET_SHUTDOWN_* definitions.
  1707. Return Value:
  1708. Status code.
  1709. --*/
  1710. {
  1711. PNET_SOCKET NetSocket;
  1712. KSTATUS Status;
  1713. NetSocket = (PNET_SOCKET)Socket;
  1714. if (NetGlobalDebug != FALSE) {
  1715. RtlDebugPrint("Net: Shutdown socket 0x%x, %d...\n",
  1716. NetSocket,
  1717. ShutdownType);
  1718. }
  1719. Status = NetSocket->Protocol->Interface.Shutdown(NetSocket, ShutdownType);
  1720. if (NetGlobalDebug != FALSE) {
  1721. RtlDebugPrint("Net: Shutdown socket 0x%x, %d: %d\n",
  1722. NetSocket,
  1723. ShutdownType,
  1724. Status);
  1725. }
  1726. return Status;
  1727. }
  1728. KSTATUS
  1729. NetUserControl (
  1730. PSOCKET Socket,
  1731. ULONG CodeNumber,
  1732. BOOL FromKernelMode,
  1733. PVOID ContextBuffer,
  1734. UINTN ContextBufferSize
  1735. )
  1736. /*++
  1737. Routine Description:
  1738. This routine handles user control requests destined for a socket.
  1739. Arguments:
  1740. Socket - Supplies a pointer to the socket.
  1741. CodeNumber - Supplies the minor code of the request.
  1742. FromKernelMode - Supplies a boolean indicating whether or not this request
  1743. (and the buffer associated with it) originates from user mode (FALSE)
  1744. or kernel mode (TRUE).
  1745. ContextBuffer - Supplies a pointer to the context buffer allocated by the
  1746. caller for the request.
  1747. ContextBufferSize - Supplies the size of the supplied context buffer.
  1748. Return Value:
  1749. Status code.
  1750. --*/
  1751. {
  1752. PNET_SOCKET NetSocket;
  1753. KSTATUS Status;
  1754. NetSocket = (PNET_SOCKET)Socket;
  1755. Status = NetSocket->Protocol->Interface.UserControl(NetSocket,
  1756. CodeNumber,
  1757. FromKernelMode,
  1758. ContextBuffer,
  1759. ContextBufferSize);
  1760. if (NetGlobalDebug != FALSE) {
  1761. RtlDebugPrint("Net: UserControl socket 0x%x, %d: %d\n",
  1762. NetSocket,
  1763. CodeNumber,
  1764. Status);
  1765. }
  1766. return Status;
  1767. }
  1768. //
  1769. // --------------------------------------------------------- Internal Functions
  1770. //
  1771. VOID
  1772. NetpDestroyProtocol (
  1773. PNET_PROTOCOL_ENTRY Protocol
  1774. )
  1775. /*++
  1776. Routine Description:
  1777. This routine destroys the given protocol and all its resources.
  1778. Arguments:
  1779. Protocol - Supplies a pointer to the protocol to destroy.
  1780. Return Value:
  1781. None.
  1782. --*/
  1783. {
  1784. if (Protocol->SocketLock != NULL) {
  1785. KeDestroySharedExclusiveLock(Protocol->SocketLock);
  1786. }
  1787. MmFreePagedPool(Protocol);
  1788. return;
  1789. }