netcore.c 61 KB

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