raw.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036
  1. /*++
  2. Copyright (c) 2014 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. raw.c
  9. Abstract:
  10. This module implements the raw socket protocol.
  11. Author:
  12. Chris Stevens 20-May-2014
  13. Environment:
  14. Kernel
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. //
  20. // Protocol drivers are supposed to be able to stand on their own (ie be able to
  21. // be implemented outside the core net library). For the builtin ones, avoid
  22. // including netcore.h, but still redefine those functions that would otherwise
  23. // generate imports.
  24. //
  25. #define NET_API __DLLEXPORT
  26. #include <minoca/kernel/driver.h>
  27. #include <minoca/net/netdrv.h>
  28. //
  29. // ---------------------------------------------------------------- Definitions
  30. //
  31. //
  32. // Define the allocation tag used by the raw socket protocol.
  33. //
  34. #define RAW_PROTOCOL_ALLOCATION_TAG 0x21707352 // '!psR'
  35. //
  36. // Define the default size of the RAW socket's receive data buffer, in bytes.
  37. //
  38. #define RAW_DEFAULT_RECEIVE_BUFFER_SIZE (256 * _1KB)
  39. //
  40. // Define the minimum receive buffer size.
  41. //
  42. #define RAW_MIN_RECEIVE_BUFFER_SIZE _2KB
  43. //
  44. // Define the default minimum number of bytes necessary for the RAW socket to
  45. // become readable.
  46. //
  47. #define RAW_DEFAULT_RECEIVE_MINIMUM 1
  48. //
  49. // Define the minimum number of bytes necessary for RAW sockets to become
  50. // writable. There is no minimum and bytes are immediately sent on the wire.
  51. //
  52. #define RAW_SEND_MINIMUM 1
  53. //
  54. // Define the maximum packet size allowed on a raw socket.
  55. //
  56. #define RAW_MAX_PACKET_SIZE MAX_ULONG
  57. //
  58. // Define the default protocol entry flags.
  59. //
  60. #define RAW_DEFAULT_PROTOCOL_FLAGS \
  61. NET_PROTOCOL_FLAG_MATCH_ANY_PROTOCOL | \
  62. NET_PROTOCOL_FLAG_FIND_ALL_SOCKETS | \
  63. NET_PROTOCOL_FLAG_NO_DEFAULT_PROTOCOL | \
  64. NET_PROTOCOL_FLAG_PORTLESS | \
  65. NET_PROTOCOL_FLAG_NO_BIND_PERMISSIONS
  66. //
  67. // ------------------------------------------------------ Data Type Definitions
  68. //
  69. /*++
  70. Structure Description:
  71. This structure defines a raw socket protocol's data socket.
  72. Members:
  73. NetSocket - Stores the common core networking parameters.
  74. ReceivedPacketList - Stores the list of packets ready to be read by the
  75. user.
  76. ReceiveLock - Stores the lock that protects the received packets list,
  77. dropped packet count, and various receive buffer parameters. This lock
  78. must always be acquired at low level.
  79. ReceiveBufferTotalSize - Stores the total size of the receive buffer, in
  80. bytes. Packets that are received but will not fit in the buffer are
  81. discarded.
  82. ReceiveBufferFreeSize - Stores the receive buffer's free space, in bytes.
  83. Packets that are received but do not fit in the free space are
  84. discarded.
  85. ReceiveTimeout - Stores the maximum amount of time, in milliseconds, that
  86. the socket will wait when receiving data.
  87. ReceiveMinimum - Stores the minimum amount of bytes that must be available
  88. before the socket is made readable. This is ignored.
  89. DroppedPacketCount - Stores the number of packets that have been dropped
  90. because the receive queue was full.
  91. ShutdownTypes - Stores the mask of shutdowns that have occurred on this
  92. socket.
  93. MaxPacketSize - Stores the maximum size of RAW datagrams.
  94. --*/
  95. typedef struct _RAW_SOCKET {
  96. NET_SOCKET NetSocket;
  97. LIST_ENTRY ReceivedPacketList;
  98. PQUEUED_LOCK ReceiveLock;
  99. ULONG ReceiveBufferTotalSize;
  100. ULONG ReceiveBufferFreeSize;
  101. ULONG ReceiveTimeout;
  102. ULONG ReceiveMinimum;
  103. ULONG DroppedPacketCount;
  104. ULONG MaxPacketSize;
  105. ULONG ShutdownTypes;
  106. } RAW_SOCKET, *PRAW_SOCKET;
  107. /*++
  108. Structure Description:
  109. This structure defines a raw socket protocol received message.
  110. Members:
  111. ListEntry - Stores pointers to the next and previous packets.
  112. Address - Stores the network address where this data came from.
  113. DataBuffer - Stores a pointer to the buffer containing the actual data.
  114. Size - Stores the number of bytes in the data buffer.
  115. --*/
  116. typedef struct _RAW_RECEIVED_PACKET {
  117. LIST_ENTRY ListEntry;
  118. NETWORK_ADDRESS Address;
  119. PVOID DataBuffer;
  120. ULONG Size;
  121. } RAW_RECEIVED_PACKET, *PRAW_RECEIVED_PACKET;
  122. /*++
  123. Structure Description:
  124. This structure defines a raw socket option.
  125. Members:
  126. InformationType - Stores the information type for the socket option.
  127. Option - Stores the type-specific option identifier.
  128. Size - Stores the size of the option value, in bytes.
  129. SetAllowed - Stores a boolean indicating whether or not the option is
  130. allowed to be set.
  131. --*/
  132. typedef struct _RAW_SOCKET_OPTION {
  133. SOCKET_INFORMATION_TYPE InformationType;
  134. UINTN Option;
  135. UINTN Size;
  136. BOOL SetAllowed;
  137. } RAW_SOCKET_OPTION, *PRAW_SOCKET_OPTION;
  138. //
  139. // ----------------------------------------------- Internal Function Prototypes
  140. //
  141. KSTATUS
  142. NetpRawCreateSocket (
  143. PNET_PROTOCOL_ENTRY ProtocolEntry,
  144. PNET_NETWORK_ENTRY NetworkEntry,
  145. ULONG NetworkProtocol,
  146. PNET_SOCKET *NewSocket,
  147. ULONG Phase
  148. );
  149. VOID
  150. NetpRawDestroySocket (
  151. PNET_SOCKET Socket
  152. );
  153. KSTATUS
  154. NetpRawBindToAddress (
  155. PNET_SOCKET Socket,
  156. PNET_LINK Link,
  157. PNETWORK_ADDRESS Address
  158. );
  159. KSTATUS
  160. NetpRawListen (
  161. PNET_SOCKET Socket
  162. );
  163. KSTATUS
  164. NetpRawAccept (
  165. PNET_SOCKET Socket,
  166. PIO_HANDLE *NewConnectionSocket,
  167. PNETWORK_ADDRESS RemoteAddress
  168. );
  169. KSTATUS
  170. NetpRawConnect (
  171. PNET_SOCKET Socket,
  172. PNETWORK_ADDRESS Address
  173. );
  174. KSTATUS
  175. NetpRawClose (
  176. PNET_SOCKET Socket
  177. );
  178. KSTATUS
  179. NetpRawShutdown (
  180. PNET_SOCKET Socket,
  181. ULONG ShutdownType
  182. );
  183. KSTATUS
  184. NetpRawSend (
  185. BOOL FromKernelMode,
  186. PNET_SOCKET Socket,
  187. PSOCKET_IO_PARAMETERS Parameters,
  188. PIO_BUFFER IoBuffer
  189. );
  190. VOID
  191. NetpRawProcessReceivedData (
  192. PNET_RECEIVE_CONTEXT ReceiveContext
  193. );
  194. KSTATUS
  195. NetpRawProcessReceivedSocketData (
  196. PNET_SOCKET Socket,
  197. PNET_RECEIVE_CONTEXT ReceiveContext
  198. );
  199. KSTATUS
  200. NetpRawReceive (
  201. BOOL FromKernelMode,
  202. PNET_SOCKET Socket,
  203. PSOCKET_IO_PARAMETERS Parameters,
  204. PIO_BUFFER IoBuffer
  205. );
  206. KSTATUS
  207. NetpRawGetSetInformation (
  208. PNET_SOCKET Socket,
  209. SOCKET_INFORMATION_TYPE InformationType,
  210. UINTN SocketOption,
  211. PVOID Data,
  212. PUINTN DataSize,
  213. BOOL Set
  214. );
  215. KSTATUS
  216. NetpRawUserControl (
  217. PNET_SOCKET Socket,
  218. ULONG CodeNumber,
  219. BOOL FromKernelMode,
  220. PVOID ContextBuffer,
  221. UINTN ContextBufferSize
  222. );
  223. //
  224. // -------------------------------------------------------------------- Globals
  225. //
  226. NET_PROTOCOL_ENTRY NetRawProtocol = {
  227. {NULL, NULL},
  228. NetSocketRaw,
  229. SOCKET_INTERNET_PROTOCOL_RAW,
  230. RAW_DEFAULT_PROTOCOL_FLAGS,
  231. NULL,
  232. NULL,
  233. {{0}, {0}, {0}},
  234. {
  235. NetpRawCreateSocket,
  236. NetpRawDestroySocket,
  237. NetpRawBindToAddress,
  238. NetpRawListen,
  239. NetpRawAccept,
  240. NetpRawConnect,
  241. NetpRawClose,
  242. NetpRawShutdown,
  243. NetpRawSend,
  244. NetpRawProcessReceivedData,
  245. NetpRawProcessReceivedSocketData,
  246. NetpRawReceive,
  247. NetpRawGetSetInformation,
  248. NetpRawUserControl
  249. }
  250. };
  251. RAW_SOCKET_OPTION NetRawSocketOptions[] = {
  252. {
  253. SocketInformationBasic,
  254. SocketBasicOptionSendBufferSize,
  255. sizeof(ULONG),
  256. TRUE
  257. },
  258. {
  259. SocketInformationBasic,
  260. SocketBasicOptionSendMinimum,
  261. sizeof(ULONG),
  262. FALSE
  263. },
  264. {
  265. SocketInformationBasic,
  266. SocketBasicOptionReceiveBufferSize,
  267. sizeof(ULONG),
  268. TRUE
  269. },
  270. {
  271. SocketInformationBasic,
  272. SocketBasicOptionReceiveMinimum,
  273. sizeof(ULONG),
  274. TRUE
  275. },
  276. {
  277. SocketInformationBasic,
  278. SocketBasicOptionReceiveTimeout,
  279. sizeof(SOCKET_TIME),
  280. TRUE
  281. },
  282. };
  283. //
  284. // Store the number of raw sockets that could potentially receive a packet.
  285. //
  286. volatile UINTN NetRawSocketCount = 0;
  287. //
  288. // ------------------------------------------------------------------ Functions
  289. //
  290. VOID
  291. NetpRawInitialize (
  292. VOID
  293. )
  294. /*++
  295. Routine Description:
  296. This routine initializes support for raw sockets.
  297. Arguments:
  298. None.
  299. Return Value:
  300. None.
  301. --*/
  302. {
  303. KSTATUS Status;
  304. //
  305. // Register the raw socket handler with the core networking library. There
  306. // is no real "raw protocol", so this is a special protocol that gets to
  307. // filter packets from every protocol.
  308. //
  309. Status = NetRegisterProtocol(&NetRawProtocol, NULL);
  310. if (!KSUCCESS(Status)) {
  311. ASSERT(FALSE);
  312. }
  313. return;
  314. }
  315. KSTATUS
  316. NetpRawCreateSocket (
  317. PNET_PROTOCOL_ENTRY ProtocolEntry,
  318. PNET_NETWORK_ENTRY NetworkEntry,
  319. ULONG NetworkProtocol,
  320. PNET_SOCKET *NewSocket,
  321. ULONG Phase
  322. )
  323. /*++
  324. Routine Description:
  325. This routine allocates resources associated with a new socket. The protocol
  326. driver is responsible for allocating the structure (with additional length
  327. for any of its context). The core networking library will fill in the
  328. common header when this routine returns.
  329. Arguments:
  330. ProtocolEntry - Supplies a pointer to the protocol information.
  331. NetworkEntry - Supplies a pointer to the network information.
  332. NetworkProtocol - Supplies the raw protocol value for this socket used on
  333. the network. This value is network specific.
  334. NewSocket - Supplies a pointer where a pointer to a newly allocated
  335. socket structure will be returned. The caller is responsible for
  336. allocating the socket (and potentially a larger structure for its own
  337. context). The core network library will fill in the standard socket
  338. structure after this routine returns. In phase 1, this will contain
  339. a pointer to the socket allocated during phase 0.
  340. Phase - Supplies the socket creation phase. Phase 0 is the allocation phase
  341. and phase 1 is the advanced initialization phase, which is invoked
  342. after net core is done filling out common portions of the socket
  343. structure.
  344. Return Value:
  345. Status code.
  346. --*/
  347. {
  348. NETWORK_ADDRESS LocalAddress;
  349. PNET_SOCKET NetSocket;
  350. PNET_PACKET_SIZE_INFORMATION PacketSizeInformation;
  351. PRAW_SOCKET RawSocket;
  352. KSTATUS Status;
  353. ASSERT(ProtocolEntry->Type == NetSocketRaw);
  354. ASSERT(ProtocolEntry->ParentProtocolNumber == SOCKET_INTERNET_PROTOCOL_RAW);
  355. NetSocket = NULL;
  356. RawSocket = NULL;
  357. //
  358. // The thread must have permission to create raw sockets.
  359. //
  360. Status = PsCheckPermission(PERMISSION_NET_RAW);
  361. if (!KSUCCESS(Status)) {
  362. goto RawCreateSocketEnd;
  363. }
  364. //
  365. // Phase 0 allocates the socket and begins initialization.
  366. //
  367. if (Phase == 0) {
  368. RawSocket = MmAllocatePagedPool(sizeof(RAW_SOCKET),
  369. RAW_PROTOCOL_ALLOCATION_TAG);
  370. if (RawSocket == NULL) {
  371. Status = STATUS_INSUFFICIENT_RESOURCES;
  372. goto RawCreateSocketEnd;
  373. }
  374. RtlZeroMemory(RawSocket, sizeof(RAW_SOCKET));
  375. NetSocket = &(RawSocket->NetSocket);
  376. NetSocket->KernelSocket.Protocol = NetworkProtocol;
  377. NetSocket->KernelSocket.ReferenceCount = 1;
  378. INITIALIZE_LIST_HEAD(&(RawSocket->ReceivedPacketList));
  379. RawSocket->ReceiveTimeout = WAIT_TIME_INDEFINITE;
  380. RawSocket->ReceiveBufferTotalSize = RAW_DEFAULT_RECEIVE_BUFFER_SIZE;
  381. RawSocket->ReceiveBufferFreeSize = RawSocket->ReceiveBufferTotalSize;
  382. RawSocket->ReceiveMinimum = RAW_DEFAULT_RECEIVE_MINIMUM;
  383. RawSocket->MaxPacketSize = RAW_MAX_PACKET_SIZE;
  384. RawSocket->ReceiveLock = KeCreateQueuedLock();
  385. if (RawSocket->ReceiveLock == NULL) {
  386. Status = STATUS_INSUFFICIENT_RESOURCES;
  387. goto RawCreateSocketEnd;
  388. }
  389. //
  390. // Set some kernel socket fields. A raw socket needs to be bound to the
  391. // any address and made ready to receive as soon as create returns. To
  392. // avoid requiring common code to handle this, initialize the kernel
  393. // socket so that the bind routines can be invoked.
  394. //
  395. NetSocket->KernelSocket.IoState = IoCreateIoObjectState(FALSE, FALSE);
  396. if (NetSocket->KernelSocket.IoState == NULL) {
  397. Status = STATUS_INSUFFICIENT_RESOURCES;
  398. goto RawCreateSocketEnd;
  399. }
  400. NetSocket->KernelSocket.Domain = NetworkEntry->Domain;
  401. NetSocket->KernelSocket.Type = ProtocolEntry->Type;
  402. //
  403. // Give the lower layers a chance to initialize. Start the maximum
  404. // packet size at the largest possible value.
  405. //
  406. ASSERT(RAW_MAX_PACKET_SIZE == MAX_ULONG);
  407. PacketSizeInformation = &(NetSocket->PacketSizeInformation);
  408. PacketSizeInformation->MaxPacketSize = RAW_MAX_PACKET_SIZE;
  409. Status = NetworkEntry->Interface.InitializeSocket(ProtocolEntry,
  410. NetworkEntry,
  411. NetworkProtocol,
  412. NetSocket);
  413. if (!KSUCCESS(Status)) {
  414. goto RawCreateSocketEnd;
  415. }
  416. RtlAtomicAdd(&NetRawSocketCount, 1);
  417. Status = STATUS_SUCCESS;
  418. //
  419. // Phase 1 finishes raw specific initialization after netcore is done with
  420. // its initialization steps.
  421. //
  422. } else {
  423. ASSERT(Phase == 1);
  424. ASSERT(*NewSocket != NULL);
  425. ASSERT(RawSocket == NULL);
  426. NetSocket = *NewSocket;
  427. //
  428. // Perform the implicit bind to the any address.
  429. //
  430. RtlZeroMemory(&LocalAddress, sizeof(NETWORK_ADDRESS));
  431. LocalAddress.Domain = NetSocket->KernelSocket.Domain;
  432. Status = NetpRawBindToAddress(NetSocket, NULL, &LocalAddress);
  433. if (!KSUCCESS(Status)) {
  434. goto RawCreateSocketEnd;
  435. }
  436. }
  437. RawCreateSocketEnd:
  438. if (!KSUCCESS(Status)) {
  439. if (RawSocket != NULL) {
  440. if (RawSocket->ReceiveLock != NULL) {
  441. KeDestroyQueuedLock(RawSocket->ReceiveLock);
  442. }
  443. MmFreePagedPool(RawSocket);
  444. RawSocket = NULL;
  445. NetSocket = NULL;
  446. }
  447. }
  448. *NewSocket = NetSocket;
  449. return Status;
  450. }
  451. VOID
  452. NetpRawDestroySocket (
  453. PNET_SOCKET Socket
  454. )
  455. /*++
  456. Routine Description:
  457. This routine destroys resources associated with an open socket, officially
  458. marking the end of the kernel and core networking library's knowledge of
  459. this structure.
  460. Arguments:
  461. Socket - Supplies a pointer to the socket to destroy. The core networking
  462. library will have already destroyed any resources inside the common
  463. header, the protocol should not reach through any pointers inside the
  464. socket header except the protocol and network entries.
  465. Return Value:
  466. None. This routine is responsible for freeing the memory associated with
  467. the socket structure itself.
  468. --*/
  469. {
  470. PRAW_RECEIVED_PACKET Packet;
  471. PRAW_SOCKET RawSocket;
  472. RawSocket = (PRAW_SOCKET)Socket;
  473. //
  474. // Loop through and free any leftover packets.
  475. //
  476. KeAcquireQueuedLock(RawSocket->ReceiveLock);
  477. while (!LIST_EMPTY(&(RawSocket->ReceivedPacketList))) {
  478. Packet = LIST_VALUE(RawSocket->ReceivedPacketList.Next,
  479. RAW_RECEIVED_PACKET,
  480. ListEntry);
  481. LIST_REMOVE(&(Packet->ListEntry));
  482. RawSocket->ReceiveBufferFreeSize += Packet->Size;
  483. MmFreePagedPool(Packet);
  484. }
  485. ASSERT(RawSocket->ReceiveBufferFreeSize ==
  486. RawSocket->ReceiveBufferTotalSize);
  487. KeReleaseQueuedLock(RawSocket->ReceiveLock);
  488. if (Socket->Network->Interface.DestroySocket != NULL) {
  489. Socket->Network->Interface.DestroySocket(Socket);
  490. }
  491. KeDestroyQueuedLock(RawSocket->ReceiveLock);
  492. MmFreePagedPool(RawSocket);
  493. RtlAtomicAdd(&NetRawSocketCount, (UINTN)-1);
  494. return;
  495. }
  496. KSTATUS
  497. NetpRawBindToAddress (
  498. PNET_SOCKET Socket,
  499. PNET_LINK Link,
  500. PNETWORK_ADDRESS Address
  501. )
  502. /*++
  503. Routine Description:
  504. This routine binds the given socket to the specified network address.
  505. Usually this is a no-op for the protocol, it's simply responsible for
  506. passing the request down to the network layer.
  507. Arguments:
  508. Socket - Supplies a pointer to the socket to bind.
  509. Link - Supplies an optional pointer to a link to bind to.
  510. Address - Supplies a pointer to the address to bind the socket to.
  511. Return Value:
  512. Status code.
  513. --*/
  514. {
  515. ULONG Flags;
  516. ULONG OriginalPort;
  517. KSTATUS Status;
  518. //
  519. // Allow raw sockets to get bound multiple times, unless they are already
  520. // connected to a peer address. They get bound to the any address upon
  521. // creation.
  522. //
  523. if (Socket->RemoteAddress.Domain != NetDomainInvalid) {
  524. Status = STATUS_INVALID_PARAMETER;
  525. goto RawBindToAddressEnd;
  526. }
  527. //
  528. // The port doesn't make a difference on raw sockets. Set it to the
  529. // protocol value, which is storked in the kernel socket.
  530. //
  531. OriginalPort = Address->Port;
  532. Address->Port = Socket->KernelSocket.Protocol;
  533. //
  534. // Pass the request down to the network layer. Raw sockets have slightly
  535. // different bind behavior than other socket types. Indicate this with the
  536. // flags.
  537. //
  538. Flags = NET_SOCKET_BINDING_FLAG_ALLOW_REBIND |
  539. NET_SOCKET_BINDING_FLAG_ALLOW_UNBIND |
  540. NET_SOCKET_BINDING_FLAG_NO_PORT_ASSIGNMENT |
  541. NET_SOCKET_BINDING_FLAG_OVERWRITE_LOCAL |
  542. NET_SOCKET_BINDING_FLAG_SKIP_ADDRESS_VALIDATION;
  543. Status = Socket->Network->Interface.BindToAddress(Socket,
  544. Link,
  545. Address,
  546. Flags);
  547. Address->Port = OriginalPort;
  548. if (!KSUCCESS(Status)) {
  549. goto RawBindToAddressEnd;
  550. }
  551. //
  552. // Begin listening immediately, as there is no explicit listen step for raw
  553. // sockets.
  554. //
  555. Status = Socket->Network->Interface.Listen(Socket);
  556. if (!KSUCCESS(Status)) {
  557. goto RawBindToAddressEnd;
  558. }
  559. IoSetIoObjectState(Socket->KernelSocket.IoState, POLL_EVENT_OUT, TRUE);
  560. RawBindToAddressEnd:
  561. return Status;
  562. }
  563. KSTATUS
  564. NetpRawListen (
  565. PNET_SOCKET Socket
  566. )
  567. /*++
  568. Routine Description:
  569. This routine adds a bound socket to the list of listening sockets,
  570. officially allowing clients to attempt to connect to it.
  571. Arguments:
  572. Socket - Supplies a pointer to the socket to mark as listning.
  573. Return Value:
  574. Status code.
  575. --*/
  576. {
  577. return STATUS_NOT_SUPPORTED;
  578. }
  579. KSTATUS
  580. NetpRawAccept (
  581. PNET_SOCKET Socket,
  582. PIO_HANDLE *NewConnectionSocket,
  583. PNETWORK_ADDRESS RemoteAddress
  584. )
  585. /*++
  586. Routine Description:
  587. This routine accepts an incoming connection on a listening connection-based
  588. socket.
  589. Arguments:
  590. Socket - Supplies a pointer to the socket to accept a connection from.
  591. NewConnectionSocket - Supplies a pointer where a new socket will be
  592. returned that represents the accepted connection with the remote
  593. host.
  594. RemoteAddress - Supplies a pointer where the address of the connected
  595. remote host will be returned.
  596. Return Value:
  597. Status code.
  598. --*/
  599. {
  600. return STATUS_NOT_SUPPORTED;
  601. }
  602. KSTATUS
  603. NetpRawConnect (
  604. PNET_SOCKET Socket,
  605. PNETWORK_ADDRESS Address
  606. )
  607. /*++
  608. Routine Description:
  609. This routine attempts to make an outgoing connection to a server.
  610. Arguments:
  611. Socket - Supplies a pointer to the socket to use for the connection.
  612. Address - Supplies a pointer to the address to connect to.
  613. Return Value:
  614. Status code.
  615. --*/
  616. {
  617. ULONG OriginalPort;
  618. KSTATUS Status;
  619. //
  620. // Ports don't mean anything to raw sockets. Zero it out. Other
  621. // implementations seem to keep the port and return it for APIs like
  622. // getpeername(). This is confusing as a packet is never matched to a
  623. // socket based on the port. Setting it to zero also makes life easier when
  624. // searching for sockets during packet reception. The received packet has
  625. // no raw protocol port. If the socket were connected to some user defined
  626. // port, then the search compare routines would have to know to skip port
  627. // validation. Setting the port to zero allows the default compare routines
  628. // to be used.
  629. //
  630. OriginalPort = Address->Port;
  631. Address->Port = 0;
  632. //
  633. // Pass the request down to the network layer.
  634. //
  635. Status = Socket->Network->Interface.Connect(Socket, Address);
  636. Address->Port = OriginalPort;
  637. if (!KSUCCESS(Status)) {
  638. goto RawConnectEnd;
  639. }
  640. IoSetIoObjectState(Socket->KernelSocket.IoState, POLL_EVENT_OUT, TRUE);
  641. RawConnectEnd:
  642. return Status;
  643. }
  644. KSTATUS
  645. NetpRawClose (
  646. PNET_SOCKET Socket
  647. )
  648. /*++
  649. Routine Description:
  650. This routine closes a socket connection.
  651. Arguments:
  652. Socket - Supplies a pointer to the socket to shut down.
  653. Return Value:
  654. Status code.
  655. --*/
  656. {
  657. KSTATUS Status;
  658. //
  659. // Close it at the lower level and then release the reference taken on
  660. // create if the close was successful.
  661. //
  662. Status = Socket->Network->Interface.Close(Socket);
  663. if (!KSUCCESS(Status)) {
  664. goto RawCloseEnd;
  665. }
  666. IoSocketReleaseReference(&(Socket->KernelSocket));
  667. RawCloseEnd:
  668. return Status;
  669. }
  670. KSTATUS
  671. NetpRawShutdown (
  672. PNET_SOCKET Socket,
  673. ULONG ShutdownType
  674. )
  675. /*++
  676. Routine Description:
  677. This routine shuts down communication with a given socket.
  678. Arguments:
  679. Socket - Supplies a pointer to the socket.
  680. ShutdownType - Supplies the shutdown type to perform. See the
  681. SOCKET_SHUTDOWN_* definitions.
  682. Return Value:
  683. Status code.
  684. --*/
  685. {
  686. PRAW_SOCKET RawSocket;
  687. //
  688. // Shutdown is not supported unless the socket is connected.
  689. //
  690. if (Socket->RemoteAddress.Domain == NetDomainInvalid) {
  691. return STATUS_NOT_CONNECTED;
  692. }
  693. RawSocket = (PRAW_SOCKET)Socket;
  694. RtlAtomicOr32(&(RawSocket->ShutdownTypes), ShutdownType);
  695. //
  696. // Signal the read event if the read end was shut down.
  697. //
  698. if ((ShutdownType & SOCKET_SHUTDOWN_READ) != 0) {
  699. KeAcquireQueuedLock(RawSocket->ReceiveLock);
  700. IoSetIoObjectState(Socket->KernelSocket.IoState, POLL_EVENT_IN, TRUE);
  701. KeReleaseQueuedLock(RawSocket->ReceiveLock);
  702. }
  703. if ((ShutdownType & SOCKET_SHUTDOWN_WRITE) != 0) {
  704. IoSetIoObjectState(Socket->KernelSocket.IoState, POLL_EVENT_OUT, TRUE);
  705. }
  706. return STATUS_SUCCESS;
  707. }
  708. KSTATUS
  709. NetpRawSend (
  710. BOOL FromKernelMode,
  711. PNET_SOCKET Socket,
  712. PSOCKET_IO_PARAMETERS Parameters,
  713. PIO_BUFFER IoBuffer
  714. )
  715. /*++
  716. Routine Description:
  717. This routine sends the given data buffer through the network using a
  718. specific protocol.
  719. Arguments:
  720. FromKernelMode - Supplies a boolean indicating whether the request is
  721. coming from kernel mode (TRUE) or user mode (FALSE).
  722. Socket - Supplies a pointer to the socket to send the data to.
  723. Parameters - Supplies a pointer to the socket I/O parameters. This will
  724. always be a kernel mode pointer.
  725. IoBuffer - Supplies a pointer to the I/O buffer containing the data to
  726. send.
  727. Return Value:
  728. Status code.
  729. --*/
  730. {
  731. UINTN BytesComplete;
  732. PNETWORK_ADDRESS Destination;
  733. NETWORK_ADDRESS DestinationLocal;
  734. ULONG Flags;
  735. ULONG FooterSize;
  736. ULONG HeaderSize;
  737. PNET_LINK Link;
  738. NET_LINK_LOCAL_ADDRESS LinkInformation;
  739. PNET_SOCKET_LINK_OVERRIDE LinkOverride;
  740. NET_SOCKET_LINK_OVERRIDE LinkOverrideBuffer;
  741. PNET_PACKET_BUFFER Packet;
  742. NET_PACKET_LIST PacketList;
  743. PRAW_SOCKET RawSocket;
  744. UINTN Size;
  745. KSTATUS Status;
  746. BytesComplete = 0;
  747. Flags = Parameters->SocketIoFlags;
  748. Parameters->SocketIoFlags = 0;
  749. Link = NULL;
  750. LinkInformation.Link = NULL;
  751. LinkOverride = NULL;
  752. NET_INITIALIZE_PACKET_LIST(&PacketList);
  753. Size = Parameters->Size;
  754. RawSocket = (PRAW_SOCKET)Socket;
  755. Destination = Parameters->NetworkAddress;
  756. if ((Destination != NULL) && (FromKernelMode == FALSE)) {
  757. Status = MmCopyFromUserMode(&DestinationLocal,
  758. Destination,
  759. sizeof(NETWORK_ADDRESS));
  760. Destination = &DestinationLocal;
  761. if (!KSUCCESS(Status)) {
  762. goto RawSendEnd;
  763. }
  764. }
  765. if ((Destination == NULL) ||
  766. (Destination->Domain == NetDomainInvalid)) {
  767. if (Socket->RemoteAddress.Port == 0) {
  768. Status = STATUS_NOT_CONFIGURED;
  769. goto RawSendEnd;
  770. }
  771. Destination = &(Socket->RemoteAddress);
  772. } else if (Destination->Domain != Socket->KernelSocket.Domain) {
  773. Status = STATUS_DOMAIN_NOT_SUPPORTED;
  774. goto RawSendEnd;
  775. }
  776. //
  777. // Fail if the socket has already been closed for writing.
  778. //
  779. if ((RawSocket->ShutdownTypes & SOCKET_SHUTDOWN_WRITE) != 0) {
  780. if ((Flags & SOCKET_IO_NO_SIGNAL) != 0) {
  781. Status = STATUS_BROKEN_PIPE_SILENT;
  782. } else {
  783. Status = STATUS_BROKEN_PIPE;
  784. }
  785. goto RawSendEnd;
  786. }
  787. //
  788. // Fail if the socket's link went down.
  789. //
  790. if ((Socket->KernelSocket.IoState->Events & POLL_EVENT_DISCONNECTED) != 0) {
  791. Status = STATUS_NO_NETWORK_CONNECTION;
  792. goto RawSendEnd;
  793. }
  794. //
  795. // Fail if there's ancillary data.
  796. //
  797. if (Parameters->ControlDataSize != 0) {
  798. Status = STATUS_NOT_SUPPORTED;
  799. goto RawSendEnd;
  800. }
  801. //
  802. // If the socket has no link, then try to find a link that can service the
  803. // destination address.
  804. //
  805. if (Socket->Link == NULL) {
  806. Status = NetFindLinkForRemoteAddress(Destination, &LinkInformation);
  807. if (!KSUCCESS(Status)) {
  808. goto RawSendEnd;
  809. }
  810. //
  811. // Synchronously get the correct header, footer, and max packet sizes.
  812. //
  813. LinkOverride = &LinkOverrideBuffer;
  814. NetInitializeSocketLinkOverride(Socket, &LinkInformation, LinkOverride);
  815. }
  816. //
  817. // Set the necessary local variables based on whether the socket's link or
  818. // an override link will be used to send the data.
  819. //
  820. if (LinkOverride != NULL) {
  821. ASSERT(LinkOverride == &LinkOverrideBuffer);
  822. Link = LinkOverrideBuffer.LinkInformation.Link;
  823. HeaderSize = LinkOverrideBuffer.PacketSizeInformation.HeaderSize;
  824. FooterSize = LinkOverrideBuffer.PacketSizeInformation.FooterSize;
  825. } else {
  826. ASSERT(Socket->Link != NULL);
  827. Link = Socket->Link;
  828. HeaderSize = Socket->PacketSizeInformation.HeaderSize;
  829. FooterSize = Socket->PacketSizeInformation.FooterSize;
  830. }
  831. //
  832. // Allocate a buffer for the packet.
  833. //
  834. Status = NetAllocateBuffer(HeaderSize,
  835. Size,
  836. FooterSize,
  837. Link,
  838. 0,
  839. &Packet);
  840. if (!KSUCCESS(Status)) {
  841. goto RawSendEnd;
  842. }
  843. NET_ADD_PACKET_TO_LIST(Packet, &PacketList);
  844. //
  845. // Copy the packet data.
  846. //
  847. Status = MmCopyIoBufferData(IoBuffer,
  848. Packet->Buffer + Packet->DataOffset,
  849. BytesComplete,
  850. Size - BytesComplete,
  851. FALSE);
  852. if (!KSUCCESS(Status)) {
  853. goto RawSendEnd;
  854. }
  855. //
  856. // Send the datagram down to the network layer, which may have to send it
  857. // in fragments.
  858. //
  859. Status = Socket->Network->Interface.Send(Socket,
  860. Destination,
  861. LinkOverride,
  862. &PacketList);
  863. if (!KSUCCESS(Status)) {
  864. goto RawSendEnd;
  865. }
  866. Packet = NULL;
  867. BytesComplete = Size;
  868. RawSendEnd:
  869. Parameters->BytesCompleted = BytesComplete;
  870. if (!KSUCCESS(Status)) {
  871. NetDestroyBufferList(&PacketList);
  872. }
  873. if (LinkInformation.Link != NULL) {
  874. NetLinkReleaseReference(LinkInformation.Link);
  875. }
  876. if (LinkOverride == &(LinkOverrideBuffer)) {
  877. ASSERT(LinkOverrideBuffer.LinkInformation.Link != NULL);
  878. NetLinkReleaseReference(LinkOverrideBuffer.LinkInformation.Link);
  879. }
  880. return Status;
  881. }
  882. VOID
  883. NetpRawProcessReceivedData (
  884. PNET_RECEIVE_CONTEXT ReceiveContext
  885. )
  886. /*++
  887. Routine Description:
  888. This routine is called to process a received packet.
  889. Arguments:
  890. ReceiveContext - Supplies a pointer to the receive context that stores the
  891. link, packet, network, protocol, and source and destination addresses.
  892. Return Value:
  893. None. When the function returns, the memory associated with the packet may
  894. be reclaimed and reused.
  895. --*/
  896. {
  897. PNET_SOCKET PreviousSocket;
  898. PNET_SOCKET Socket;
  899. KSTATUS Status;
  900. ASSERT(KeGetRunLevel() == RunLevelLow);
  901. //
  902. // If no raw sockets are present, then immediately exit.
  903. //
  904. if (NetRawSocketCount == 0) {
  905. return;
  906. }
  907. //
  908. // Each raw sockets' local receive address was initialized with the port
  909. // set to the protocol number. Each raw socket's remote address was set to
  910. // 0 when it was fully bound. Initialize the receive context in this way
  911. // as well so that the ports will match any activated sockets.
  912. //
  913. ReceiveContext->Source->Port = 0;
  914. ReceiveContext->Destination->Port = ReceiveContext->ParentProtocolNumber;;
  915. //
  916. // Find all the sockets willing to take this packet.
  917. //
  918. Socket = NULL;
  919. PreviousSocket = NULL;
  920. do {
  921. Status = NetFindSocket(ReceiveContext, &Socket);
  922. if (!KSUCCESS(Status) && (Status != STATUS_MORE_PROCESSING_REQUIRED)) {
  923. break;
  924. }
  925. //
  926. // Pass the packet onto the socket for copying and safe keeping until
  927. // the data is read.
  928. //
  929. NetpRawProcessReceivedSocketData(Socket, ReceiveContext);
  930. //
  931. // Release the reference on the previous socket added by the find
  932. // socket call.
  933. //
  934. if (PreviousSocket != NULL) {
  935. IoSocketReleaseReference(&(PreviousSocket->KernelSocket));
  936. }
  937. PreviousSocket = Socket;
  938. } while (Status == STATUS_MORE_PROCESSING_REQUIRED);
  939. if (PreviousSocket != NULL) {
  940. IoSocketReleaseReference(&(PreviousSocket->KernelSocket));
  941. }
  942. ReceiveContext->Destination->Port = 0;
  943. return;
  944. }
  945. KSTATUS
  946. NetpRawProcessReceivedSocketData (
  947. PNET_SOCKET Socket,
  948. PNET_RECEIVE_CONTEXT ReceiveContext
  949. )
  950. /*++
  951. Routine Description:
  952. This routine is called for a particular socket to process a received packet
  953. that was sent to it.
  954. Arguments:
  955. Socket - Supplies a pointer to the socket that received the packet.
  956. ReceiveContext - Supplies a pointer to the receive context that stores the
  957. link, packet, network, protocol, and source and destination addresses.
  958. Return Value:
  959. Status code.
  960. --*/
  961. {
  962. ULONG AllocationSize;
  963. ULONG Length;
  964. PNET_PACKET_BUFFER Packet;
  965. PRAW_RECEIVED_PACKET RawPacket;
  966. PRAW_SOCKET RawSocket;
  967. KSTATUS Status;
  968. ASSERT(KeGetRunLevel() == RunLevelLow);
  969. ASSERT(Socket != NULL);
  970. RawSocket = (PRAW_SOCKET)Socket;
  971. Packet = ReceiveContext->Packet;
  972. Length = Packet->FooterOffset - Packet->DataOffset;
  973. //
  974. // Create a received packet entry for this data.
  975. //
  976. AllocationSize = sizeof(RAW_RECEIVED_PACKET) + Length;
  977. RawPacket = MmAllocatePagedPool(AllocationSize,
  978. RAW_PROTOCOL_ALLOCATION_TAG);
  979. if (RawPacket == NULL) {
  980. Status = STATUS_INSUFFICIENT_RESOURCES;
  981. goto ProcessReceivedKernelDataEnd;
  982. }
  983. RtlCopyMemory(&(RawPacket->Address),
  984. ReceiveContext->Source,
  985. sizeof(NETWORK_ADDRESS));
  986. RawPacket->DataBuffer = (PVOID)(RawPacket + 1);
  987. RawPacket->Size = Length;
  988. //
  989. // Copy the packet contents into the receive packet buffer.
  990. //
  991. RtlCopyMemory(RawPacket->DataBuffer,
  992. Packet->Buffer + Packet->DataOffset,
  993. Length);
  994. //
  995. // Work to insert the packet on the list of received packets.
  996. //
  997. KeAcquireQueuedLock(RawSocket->ReceiveLock);
  998. if (RawPacket->Size <= RawSocket->ReceiveBufferFreeSize) {
  999. INSERT_BEFORE(&(RawPacket->ListEntry),
  1000. &(RawSocket->ReceivedPacketList));
  1001. RawSocket->ReceiveBufferFreeSize -= RawPacket->Size;
  1002. ASSERT(RawSocket->ReceiveBufferFreeSize <
  1003. RawSocket->ReceiveBufferTotalSize);
  1004. //
  1005. // One packet is always enough to notify a waiting receiver.
  1006. //
  1007. IoSetIoObjectState(Socket->KernelSocket.IoState, POLL_EVENT_IN, TRUE);
  1008. RawPacket = NULL;
  1009. } else {
  1010. RawSocket->DroppedPacketCount += 1;
  1011. }
  1012. KeReleaseQueuedLock(RawSocket->ReceiveLock);
  1013. //
  1014. // If the packet wasn't nulled out, that's an indication it wasn't added to
  1015. // the list, so free it up.
  1016. //
  1017. if (RawPacket != NULL) {
  1018. MmFreePagedPool(RawPacket);
  1019. }
  1020. Status = STATUS_SUCCESS;
  1021. ProcessReceivedKernelDataEnd:
  1022. return Status;
  1023. }
  1024. KSTATUS
  1025. NetpRawReceive (
  1026. BOOL FromKernelMode,
  1027. PNET_SOCKET Socket,
  1028. PSOCKET_IO_PARAMETERS Parameters,
  1029. PIO_BUFFER IoBuffer
  1030. )
  1031. /*++
  1032. Routine Description:
  1033. This routine is called by the user to receive data from the socket on a
  1034. particular protocol.
  1035. Arguments:
  1036. FromKernelMode - Supplies a boolean indicating whether the request is
  1037. coming from kernel mode (TRUE) or user mode (FALSE).
  1038. Socket - Supplies a pointer to the socket to receive data from.
  1039. Parameters - Supplies a pointer to the socket I/O parameters.
  1040. IoBuffer - Supplies a pointer to the I/O buffer where the received data
  1041. will be returned.
  1042. Return Value:
  1043. STATUS_SUCCESS if any bytes were read.
  1044. STATUS_TIMEOUT if the request timed out.
  1045. STATUS_BUFFER_TOO_SMALL if the incoming datagram was too large for the
  1046. buffer. The remainder of the datagram is discarded in this case.
  1047. Other error codes on other failures.
  1048. --*/
  1049. {
  1050. UINTN BytesComplete;
  1051. ULONG CopySize;
  1052. ULONGLONG CurrentTime;
  1053. ULONGLONG EndTime;
  1054. ULONG Flags;
  1055. BOOL LockHeld;
  1056. PRAW_RECEIVED_PACKET Packet;
  1057. PLIST_ENTRY PacketEntry;
  1058. PRAW_SOCKET RawSocket;
  1059. ULONG ReturnedEvents;
  1060. ULONG ReturnSize;
  1061. UINTN Size;
  1062. KSTATUS Status;
  1063. ULONGLONG TimeCounterFrequency;
  1064. ULONG Timeout;
  1065. ULONG WaitTime;
  1066. ASSERT(KeGetRunLevel() == RunLevelLow);
  1067. BytesComplete = 0;
  1068. EndTime = 0;
  1069. LockHeld = FALSE;
  1070. Flags = Parameters->SocketIoFlags;
  1071. Parameters->SocketIoFlags = 0;
  1072. Size = Parameters->Size;
  1073. TimeCounterFrequency = 0;
  1074. Timeout = Parameters->TimeoutInMilliseconds;
  1075. RawSocket = (PRAW_SOCKET)Socket;
  1076. if ((Flags & SOCKET_IO_OUT_OF_BAND) != 0) {
  1077. Status = STATUS_NOT_SUPPORTED;
  1078. goto RawReceiveEnd;
  1079. }
  1080. //
  1081. // Fail if there's ancillary data.
  1082. //
  1083. if (Parameters->ControlDataSize != 0) {
  1084. Status = STATUS_NOT_SUPPORTED;
  1085. goto RawReceiveEnd;
  1086. }
  1087. //
  1088. // Set a timeout timer to give up on. The socket stores the maximum timeout.
  1089. //
  1090. if (Timeout > RawSocket->ReceiveTimeout) {
  1091. Timeout = RawSocket->ReceiveTimeout;
  1092. }
  1093. if ((Timeout != 0) && (Timeout != WAIT_TIME_INDEFINITE)) {
  1094. EndTime = KeGetRecentTimeCounter();
  1095. EndTime += KeConvertMicrosecondsToTimeTicks(
  1096. Timeout * MICROSECONDS_PER_MILLISECOND);
  1097. TimeCounterFrequency = HlQueryTimeCounterFrequency();
  1098. }
  1099. //
  1100. // Loop trying to get some data. This loop exits once one packet is read.
  1101. //
  1102. while (TRUE) {
  1103. //
  1104. // Wait for a packet to become available. Start by computing the wait
  1105. // time.
  1106. //
  1107. if (Timeout == 0) {
  1108. WaitTime = 0;
  1109. } else if (Timeout != WAIT_TIME_INDEFINITE) {
  1110. CurrentTime = KeGetRecentTimeCounter();
  1111. WaitTime = (EndTime - CurrentTime) * MILLISECONDS_PER_SECOND /
  1112. TimeCounterFrequency;
  1113. } else {
  1114. WaitTime = WAIT_TIME_INDEFINITE;
  1115. }
  1116. //
  1117. // Wait for something to maybe become available. If the wait fails due
  1118. // to a timeout, interruption, or something else, then fail out.
  1119. // Otherwise when the read event is signalled, there are at least one
  1120. // packet available.
  1121. //
  1122. Status = IoWaitForIoObjectState(Socket->KernelSocket.IoState,
  1123. POLL_EVENT_IN,
  1124. TRUE,
  1125. WaitTime,
  1126. &ReturnedEvents);
  1127. if (!KSUCCESS(Status)) {
  1128. goto RawReceiveEnd;
  1129. }
  1130. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  1131. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  1132. Status = STATUS_NO_NETWORK_CONNECTION;
  1133. } else {
  1134. Status = NET_SOCKET_GET_LAST_ERROR(Socket);
  1135. if (KSUCCESS(Status)) {
  1136. Status = STATUS_DEVICE_IO_ERROR;
  1137. }
  1138. }
  1139. goto RawReceiveEnd;
  1140. }
  1141. KeAcquireQueuedLock(RawSocket->ReceiveLock);
  1142. LockHeld = TRUE;
  1143. //
  1144. // Fail with EOF if the socket has already been closed for reading.
  1145. //
  1146. if ((RawSocket->ShutdownTypes & SOCKET_SHUTDOWN_READ) != 0) {
  1147. Status = STATUS_END_OF_FILE;
  1148. goto RawReceiveEnd;
  1149. }
  1150. //
  1151. // If another thread beat this one to the punch, try again.
  1152. //
  1153. if (LIST_EMPTY(&(RawSocket->ReceivedPacketList)) != FALSE) {
  1154. KeReleaseQueuedLock(RawSocket->ReceiveLock);
  1155. LockHeld = FALSE;
  1156. continue;
  1157. }
  1158. //
  1159. // This should be the first packet being read.
  1160. //
  1161. ASSERT(BytesComplete == 0);
  1162. PacketEntry = RawSocket->ReceivedPacketList.Next;
  1163. Packet = LIST_VALUE(PacketEntry, RAW_RECEIVED_PACKET, ListEntry);
  1164. ReturnSize = Packet->Size;
  1165. CopySize = ReturnSize;
  1166. if (CopySize > Size) {
  1167. Parameters->SocketIoFlags |= SOCKET_IO_DATA_TRUNCATED;
  1168. CopySize = Size;
  1169. //
  1170. // The real packet size is only returned to the user on truncation
  1171. // if the truncated flag was supplied to this routine. Default to
  1172. // returning the truncated size.
  1173. //
  1174. if ((Flags & SOCKET_IO_DATA_TRUNCATED) == 0) {
  1175. ReturnSize = CopySize;
  1176. }
  1177. }
  1178. Status = MmCopyIoBufferData(IoBuffer,
  1179. Packet->DataBuffer,
  1180. 0,
  1181. CopySize,
  1182. TRUE);
  1183. if (!KSUCCESS(Status)) {
  1184. goto RawReceiveEnd;
  1185. }
  1186. //
  1187. // Copy the packet address out to the caller if requested.
  1188. //
  1189. if (Parameters->NetworkAddress != NULL) {
  1190. if (FromKernelMode != FALSE) {
  1191. RtlCopyMemory(Parameters->NetworkAddress,
  1192. &(Packet->Address),
  1193. sizeof(NETWORK_ADDRESS));
  1194. } else {
  1195. Status = MmCopyToUserMode(Parameters->NetworkAddress,
  1196. &(Packet->Address),
  1197. sizeof(NETWORK_ADDRESS));
  1198. if (!KSUCCESS(Status)) {
  1199. goto RawReceiveEnd;
  1200. }
  1201. }
  1202. }
  1203. BytesComplete = ReturnSize;
  1204. //
  1205. // Remove the packet if not peeking.
  1206. //
  1207. if ((Flags & SOCKET_IO_PEEK) == 0) {
  1208. LIST_REMOVE(&(Packet->ListEntry));
  1209. RawSocket->ReceiveBufferFreeSize += Packet->Size;
  1210. //
  1211. // The total receive buffer size may have been decreased. Don't
  1212. // increment the free size above the total.
  1213. //
  1214. if (RawSocket->ReceiveBufferFreeSize >
  1215. RawSocket->ReceiveBufferTotalSize) {
  1216. RawSocket->ReceiveBufferFreeSize =
  1217. RawSocket->ReceiveBufferTotalSize;
  1218. }
  1219. MmFreePagedPool(Packet);
  1220. //
  1221. // Unsignal the IN event if there are no more packets.
  1222. //
  1223. if (LIST_EMPTY(&(RawSocket->ReceivedPacketList)) != FALSE) {
  1224. IoSetIoObjectState(Socket->KernelSocket.IoState,
  1225. POLL_EVENT_IN,
  1226. FALSE);
  1227. }
  1228. }
  1229. //
  1230. // Wait-all does not apply to raw sockets. Break out.
  1231. //
  1232. Status = STATUS_SUCCESS;
  1233. break;
  1234. }
  1235. RawReceiveEnd:
  1236. if (LockHeld != FALSE) {
  1237. KeReleaseQueuedLock(RawSocket->ReceiveLock);
  1238. }
  1239. Parameters->BytesCompleted = BytesComplete;
  1240. return Status;
  1241. }
  1242. KSTATUS
  1243. NetpRawGetSetInformation (
  1244. PNET_SOCKET Socket,
  1245. SOCKET_INFORMATION_TYPE InformationType,
  1246. UINTN Option,
  1247. PVOID Data,
  1248. PUINTN DataSize,
  1249. BOOL Set
  1250. )
  1251. /*++
  1252. Routine Description:
  1253. This routine gets or sets properties of the given socket.
  1254. Arguments:
  1255. Socket - Supplies a pointer to the socket to get or set information for.
  1256. InformationType - Supplies the socket information type category to which
  1257. specified option belongs.
  1258. Option - Supplies the option to get or set, which is specific to the
  1259. information type. The type of this value is generally
  1260. SOCKET_<information_type>_OPTION.
  1261. Data - Supplies a pointer to the data buffer where the data is either
  1262. returned for a get operation or given for a set operation.
  1263. DataSize - Supplies a pointer that on input constains the size of the data
  1264. buffer. On output, this contains the required size of the data buffer.
  1265. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  1266. a set operation (TRUE).
  1267. Return Value:
  1268. STATUS_SUCCESS on success.
  1269. STATUS_INVALID_PARAMETER if the information type is incorrect.
  1270. STATUS_BUFFER_TOO_SMALL if the data buffer is too small to receive the
  1271. requested option.
  1272. STATUS_NOT_SUPPORTED_BY_PROTOCOL if the socket option is not supported by
  1273. the socket.
  1274. STATUS_NOT_HANDLED if the protocol does not override the default behavior
  1275. for a basic socket option.
  1276. --*/
  1277. {
  1278. ULONG Count;
  1279. ULONG Index;
  1280. LONGLONG Milliseconds;
  1281. PRAW_SOCKET_OPTION RawOption;
  1282. PRAW_SOCKET RawSocket;
  1283. PNET_PACKET_SIZE_INFORMATION SizeInformation;
  1284. ULONG SizeOption;
  1285. PSOCKET_TIME SocketTime;
  1286. SOCKET_TIME SocketTimeBuffer;
  1287. PVOID Source;
  1288. KSTATUS Status;
  1289. RawSocket = (PRAW_SOCKET)Socket;
  1290. if ((InformationType != SocketInformationBasic) &&
  1291. (InformationType != SocketInformationUdp)) {
  1292. Status = STATUS_NOT_SUPPORTED;
  1293. goto RawGetSetInformationEnd;
  1294. }
  1295. //
  1296. // Search to see if the socket option is supported by the raw protocol.
  1297. //
  1298. Count = sizeof(NetRawSocketOptions) / sizeof(NetRawSocketOptions[0]);
  1299. for (Index = 0; Index < Count; Index += 1) {
  1300. RawOption = &(NetRawSocketOptions[Index]);
  1301. if ((RawOption->InformationType == InformationType) &&
  1302. (RawOption->Option == Option)) {
  1303. break;
  1304. }
  1305. }
  1306. if (Index == Count) {
  1307. if (InformationType == SocketInformationBasic) {
  1308. Status = STATUS_NOT_HANDLED;
  1309. } else {
  1310. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  1311. }
  1312. goto RawGetSetInformationEnd;
  1313. }
  1314. //
  1315. // Handle failure cases common to all options.
  1316. //
  1317. if (Set != FALSE) {
  1318. if (RawOption->SetAllowed == FALSE) {
  1319. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  1320. goto RawGetSetInformationEnd;
  1321. }
  1322. if (*DataSize < RawOption->Size) {
  1323. *DataSize = RawOption->Size;
  1324. Status = STATUS_BUFFER_TOO_SMALL;
  1325. goto RawGetSetInformationEnd;
  1326. }
  1327. }
  1328. //
  1329. // There are currently no raw protocol options.
  1330. //
  1331. ASSERT(InformationType != SocketInformationRaw);
  1332. //
  1333. // Parse the basic socket option, getting the information from the raw
  1334. // socket or setting the new state in the raw socket.
  1335. //
  1336. Source = NULL;
  1337. Status = STATUS_SUCCESS;
  1338. switch ((SOCKET_BASIC_OPTION)Option) {
  1339. case SocketBasicOptionSendBufferSize:
  1340. if (Set != FALSE) {
  1341. SizeOption = *((PULONG)Data);
  1342. if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  1343. SizeOption = SOCKET_OPTION_MAX_ULONG;
  1344. }
  1345. SizeInformation = &(Socket->PacketSizeInformation);
  1346. if (SizeOption > RAW_MAX_PACKET_SIZE) {
  1347. SizeOption = RAW_MAX_PACKET_SIZE;
  1348. } else if (SizeOption < SizeInformation->MaxPacketSize) {
  1349. SizeOption = SizeInformation->MaxPacketSize;
  1350. }
  1351. RawSocket->MaxPacketSize = SizeOption;
  1352. } else {
  1353. Source = &SizeOption;
  1354. SizeOption = RawSocket->MaxPacketSize;
  1355. }
  1356. break;
  1357. case SocketBasicOptionSendMinimum:
  1358. ASSERT(Set == FALSE);
  1359. Source = &SizeOption;
  1360. SizeOption = RAW_SEND_MINIMUM;
  1361. break;
  1362. case SocketBasicOptionReceiveBufferSize:
  1363. if (Set != FALSE) {
  1364. SizeOption = *((PULONG)Data);
  1365. if (SizeOption < RAW_MIN_RECEIVE_BUFFER_SIZE) {
  1366. SizeOption = RAW_MIN_RECEIVE_BUFFER_SIZE;
  1367. } else if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  1368. SizeOption = SOCKET_OPTION_MAX_ULONG;
  1369. }
  1370. //
  1371. // Set the receive buffer size and truncate the available free
  1372. // space if necessary. Do not remove any packets that have already
  1373. // been received. This is not meant to be a truncate call.
  1374. //
  1375. KeAcquireQueuedLock(RawSocket->ReceiveLock);
  1376. RawSocket->ReceiveBufferTotalSize = SizeOption;
  1377. if (RawSocket->ReceiveBufferFreeSize > SizeOption) {
  1378. RawSocket->ReceiveBufferFreeSize = SizeOption;
  1379. }
  1380. KeReleaseQueuedLock(RawSocket->ReceiveLock);
  1381. } else {
  1382. Source = &SizeOption;
  1383. SizeOption = RawSocket->ReceiveBufferTotalSize;
  1384. }
  1385. break;
  1386. case SocketBasicOptionReceiveMinimum:
  1387. if (Set != FALSE) {
  1388. SizeOption = *((PULONG)Data);
  1389. if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  1390. SizeOption = SOCKET_OPTION_MAX_ULONG;
  1391. }
  1392. RawSocket->ReceiveMinimum = SizeOption;
  1393. } else {
  1394. Source = &SizeOption;
  1395. SizeOption = RawSocket->ReceiveMinimum;
  1396. }
  1397. break;
  1398. case SocketBasicOptionReceiveTimeout:
  1399. if (Set != FALSE) {
  1400. SocketTime = (PSOCKET_TIME)Data;
  1401. if (SocketTime->Seconds < 0) {
  1402. Status = STATUS_DOMAIN_ERROR;
  1403. break;
  1404. }
  1405. Milliseconds = SocketTime->Seconds * MILLISECONDS_PER_SECOND;
  1406. if (Milliseconds < SocketTime->Seconds) {
  1407. Status = STATUS_DOMAIN_ERROR;
  1408. break;
  1409. }
  1410. Milliseconds += SocketTime->Microseconds /
  1411. MICROSECONDS_PER_MILLISECOND;
  1412. if ((Milliseconds < 0) || (Milliseconds > MAX_LONG)) {
  1413. Status = STATUS_DOMAIN_ERROR;
  1414. break;
  1415. }
  1416. RawSocket->ReceiveTimeout = (ULONG)(LONG)Milliseconds;
  1417. } else {
  1418. Source = &SocketTimeBuffer;
  1419. if (RawSocket->ReceiveTimeout == WAIT_TIME_INDEFINITE) {
  1420. SocketTimeBuffer.Seconds = 0;
  1421. SocketTimeBuffer.Microseconds = 0;
  1422. } else {
  1423. SocketTimeBuffer.Seconds = RawSocket->ReceiveTimeout /
  1424. MILLISECONDS_PER_SECOND;
  1425. SocketTimeBuffer.Microseconds = (RawSocket->ReceiveTimeout %
  1426. MILLISECONDS_PER_SECOND) *
  1427. MICROSECONDS_PER_MILLISECOND;
  1428. }
  1429. }
  1430. break;
  1431. default:
  1432. ASSERT(FALSE);
  1433. Status = STATUS_NOT_SUPPORTED;
  1434. break;
  1435. }
  1436. if (!KSUCCESS(Status)) {
  1437. goto RawGetSetInformationEnd;
  1438. }
  1439. //
  1440. // Truncate all copies for get requests down to the required size and only
  1441. // return the required size on set requests.
  1442. //
  1443. if (*DataSize > RawOption->Size) {
  1444. *DataSize = RawOption->Size;
  1445. }
  1446. //
  1447. // For get requests, copy the gathered information to the supplied data
  1448. // buffer.
  1449. //
  1450. if (Set == FALSE) {
  1451. ASSERT(Source != NULL);
  1452. RtlCopyMemory(Data, Source, *DataSize);
  1453. //
  1454. // If the copy truncated the data, report that the given buffer was too
  1455. // small. The caller can choose to ignore this if the truncated data is
  1456. // enough.
  1457. //
  1458. if (*DataSize < RawOption->Size) {
  1459. *DataSize = RawOption->Size;
  1460. Status = STATUS_BUFFER_TOO_SMALL;
  1461. goto RawGetSetInformationEnd;
  1462. }
  1463. }
  1464. RawGetSetInformationEnd:
  1465. return Status;
  1466. }
  1467. KSTATUS
  1468. NetpRawUserControl (
  1469. PNET_SOCKET Socket,
  1470. ULONG CodeNumber,
  1471. BOOL FromKernelMode,
  1472. PVOID ContextBuffer,
  1473. UINTN ContextBufferSize
  1474. )
  1475. /*++
  1476. Routine Description:
  1477. This routine handles user control requests destined for a socket.
  1478. Arguments:
  1479. Socket - Supplies a pointer to the socket.
  1480. CodeNumber - Supplies the minor code of the request.
  1481. FromKernelMode - Supplies a boolean indicating whether or not this request
  1482. (and the buffer associated with it) originates from user mode (FALSE)
  1483. or kernel mode (TRUE).
  1484. ContextBuffer - Supplies a pointer to the context buffer allocated by the
  1485. caller for the request.
  1486. ContextBufferSize - Supplies the size of the supplied context buffer.
  1487. Return Value:
  1488. Status code.
  1489. --*/
  1490. {
  1491. return STATUS_NOT_SUPPORTED;
  1492. }
  1493. //
  1494. // --------------------------------------------------------- Internal Functions
  1495. //