netcore.c 59 KB

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