udp.c 53 KB

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