generic.c 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. generic.c
  5. Abstract:
  6. This module implements the generic netlink socket protocol.
  7. Author:
  8. Chris Stevens 9-Feb-2016
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. //
  16. // Protocol drivers are supposed to be able to stand on their own (ie be able to
  17. // be implemented outside the core net library). For the builtin ones, avoid
  18. // including netcore.h, but still redefine those functions that would otherwise
  19. // generate imports.
  20. //
  21. #define NET_API __DLLEXPORT
  22. #include <minoca/kernel/driver.h>
  23. #include <minoca/net/netdrv.h>
  24. #include <minoca/net/netlink.h>
  25. #include "generic.h"
  26. //
  27. // ---------------------------------------------------------------- Definitions
  28. //
  29. //
  30. // Define the maximum supported packet size of the generic netlink protocol,
  31. // including the message headers.
  32. //
  33. #define NETLINK_GENERIC_MAX_PACKET_SIZE \
  34. (NETLINK_MAX_PACKET_SIZE - sizeof(NETLINK_HEADER))
  35. //
  36. // Define the default size of the generic netlink's receive data buffer, in
  37. // bytes.
  38. //
  39. #define NETLINK_GENERIC_DEFAULT_RECEIVE_BUFFER_SIZE (256 * _1KB)
  40. //
  41. // Define the minimum receive buffer size.
  42. //
  43. #define NETLINK_GENERIC_MIN_RECEIVE_BUFFER_SIZE _2KB
  44. //
  45. // Define the default minimum number of bytes necessary for the generic netlink
  46. // socket to become readable.
  47. //
  48. #define NETLINK_GENERIC_DEFAULT_RECEIVE_MINIMUM 1
  49. //
  50. // Define the minmum number of bytes necessary for generic netlink sockets to
  51. // become writable. There is no minimum and bytes are immediately sent on the
  52. // wire.
  53. //
  54. #define NETLINK_GENERIC_SEND_MINIMUM 1
  55. //
  56. // ------------------------------------------------------ Data Type Definitions
  57. //
  58. /*++
  59. Structure Description:
  60. This structure defines a generic netlink socket.
  61. Members:
  62. NetlinkSocket - Stores the common netlink socket information.
  63. ReceivedPacketList - Stores the list of packets ready to be read by the
  64. user.
  65. ReceiveLock - Stores the lock that protects the received packets list,
  66. dropped packet count, and various receive buffer parameters. This lock
  67. must always be acquired at low level.
  68. ReceiveBufferTotalSize - Stores the total size of the receive buffer, in
  69. bytes. Packets that are received but will not fit in the buffer are
  70. discarded.
  71. ReceiveBufferFreeSize - Stores the receive buffer's free space, in bytes.
  72. Packets that are received but do not fit in the free space are
  73. discarded.
  74. ReceiveTimeout - Stores the maximum amount of time, in milliseconds, that
  75. the socket will wait when receiving data.
  76. ReceiveMinimum - Stores the minimum amount of bytes that must be available
  77. before the socket is made readable. This is ignored.
  78. DroppedPacketCount - Stores the number of packets that have been dropped
  79. because the receive queue was full.
  80. MaxPacketSize - Stores the maximum size of UDP datagrams.
  81. --*/
  82. typedef struct _NETLINK_GENERIC_SOCKET {
  83. NETLINK_SOCKET NetlinkSocket;
  84. LIST_ENTRY ReceivedPacketList;
  85. PQUEUED_LOCK ReceiveLock;
  86. ULONG ReceiveBufferTotalSize;
  87. ULONG ReceiveBufferFreeSize;
  88. ULONG ReceiveTimeout;
  89. ULONG ReceiveMinimum;
  90. ULONG DroppedPacketCount;
  91. UINTN MaxPacketSize;
  92. } NETLINK_GENERIC_SOCKET, *PNETLINK_GENERIC_SOCKET;
  93. /*++
  94. Structure Description:
  95. This structure defines a generic netlink received message.
  96. Members:
  97. ListEntry - Stores pointers to the next and previous packets.
  98. Address - Stores the network address where this data came from.
  99. NetPacket - Stores a pointer to the network packet buffer holding the data.
  100. --*/
  101. typedef struct _NETLINK_GENERIC_RECEIVED_PACKET {
  102. LIST_ENTRY ListEntry;
  103. NETWORK_ADDRESS Address;
  104. PNET_PACKET_BUFFER NetPacket;
  105. } NETLINK_GENERIC_RECEIVED_PACKET, *PNETLINK_GENERIC_RECEIVED_PACKET;
  106. /*++
  107. Structure Description:
  108. This structure defines a netlink generic socket option.
  109. Members:
  110. InformationType - Stores the information type for the socket option.
  111. Option - Stores the type-specific option identifier.
  112. Size - Stores the size of the option value, in bytes.
  113. SetAllowed - Stores a boolean indicating whether or not the option is
  114. allowed to be set.
  115. --*/
  116. typedef struct _NETLINK_GENERIC_SOCKET_OPTION {
  117. SOCKET_INFORMATION_TYPE InformationType;
  118. UINTN Option;
  119. UINTN Size;
  120. BOOL SetAllowed;
  121. } NETLINK_GENERIC_SOCKET_OPTION, *PNETLINK_GENERIC_SOCKET_OPTION;
  122. //
  123. // ----------------------------------------------- Internal Function Prototypes
  124. //
  125. KSTATUS
  126. NetlinkpGenericCreateSocket (
  127. PNET_PROTOCOL_ENTRY ProtocolEntry,
  128. PNET_NETWORK_ENTRY NetworkEntry,
  129. ULONG NetworkProtocol,
  130. PNET_SOCKET *NewSocket
  131. );
  132. VOID
  133. NetlinkpGenericDestroySocket (
  134. PNET_SOCKET Socket
  135. );
  136. KSTATUS
  137. NetlinkpGenericBindToAddress (
  138. PNET_SOCKET Socket,
  139. PNET_LINK Link,
  140. PNETWORK_ADDRESS Address
  141. );
  142. KSTATUS
  143. NetlinkpGenericListen (
  144. PNET_SOCKET Socket
  145. );
  146. KSTATUS
  147. NetlinkpGenericAccept (
  148. PNET_SOCKET Socket,
  149. PIO_HANDLE *NewConnectionSocket,
  150. PNETWORK_ADDRESS RemoteAddress
  151. );
  152. KSTATUS
  153. NetlinkpGenericConnect (
  154. PNET_SOCKET Socket,
  155. PNETWORK_ADDRESS Address
  156. );
  157. KSTATUS
  158. NetlinkpGenericClose (
  159. PNET_SOCKET Socket
  160. );
  161. KSTATUS
  162. NetlinkpGenericShutdown (
  163. PNET_SOCKET Socket,
  164. ULONG ShutdownType
  165. );
  166. KSTATUS
  167. NetlinkpGenericSend (
  168. BOOL FromKernelMode,
  169. PNET_SOCKET Socket,
  170. PSOCKET_IO_PARAMETERS Parameters,
  171. PIO_BUFFER IoBuffer
  172. );
  173. VOID
  174. NetlinkpGenericProcessReceivedData (
  175. PNET_LINK Link,
  176. PNET_PACKET_BUFFER Packet,
  177. PNETWORK_ADDRESS SourceAddress,
  178. PNETWORK_ADDRESS DestinationAddress,
  179. PNET_PROTOCOL_ENTRY ProtocolEntry
  180. );
  181. KSTATUS
  182. NetlinkpGenericProcessReceivedSocketData (
  183. PNET_LINK Link,
  184. PNET_SOCKET Socket,
  185. PNET_PACKET_BUFFER Packet,
  186. PNETWORK_ADDRESS SourceAddress,
  187. PNETWORK_ADDRESS DestinationAddress
  188. );
  189. KSTATUS
  190. NetlinkpGenericReceive (
  191. BOOL FromKernelMode,
  192. PNET_SOCKET Socket,
  193. PSOCKET_IO_PARAMETERS Parameters,
  194. PIO_BUFFER IoBuffer
  195. );
  196. KSTATUS
  197. NetlinkpGenericGetSetInformation (
  198. PNET_SOCKET Socket,
  199. SOCKET_INFORMATION_TYPE InformationType,
  200. UINTN SocketOption,
  201. PVOID Data,
  202. PUINTN DataSize,
  203. BOOL Set
  204. );
  205. KSTATUS
  206. NetlinkpGenericUserControl (
  207. PNET_SOCKET Socket,
  208. ULONG CodeNumber,
  209. BOOL FromKernelMode,
  210. PVOID ContextBuffer,
  211. UINTN ContextBufferSize
  212. );
  213. KSTATUS
  214. NetlinkpGenericJoinMulticastGroup (
  215. PNET_SOCKET Socket,
  216. ULONG GroupId
  217. );
  218. VOID
  219. NetlinkpGenericInsertReceivedPacket (
  220. PNETLINK_GENERIC_SOCKET Socket,
  221. PNETLINK_GENERIC_RECEIVED_PACKET Packet
  222. );
  223. KSTATUS
  224. NetlinkpGenericProcessReceivedKernelData (
  225. PNET_LINK Link,
  226. PNET_SOCKET Socket,
  227. PNET_PACKET_BUFFER Packet,
  228. PNETWORK_ADDRESS SourceAddress,
  229. PNETWORK_ADDRESS DestinationAddress
  230. );
  231. PNETLINK_GENERIC_FAMILY
  232. NetlinkpGenericLookupFamilyById (
  233. ULONG MessageType
  234. );
  235. COMPARISON_RESULT
  236. NetlinkpGenericCompareFamilies (
  237. PRED_BLACK_TREE Tree,
  238. PRED_BLACK_TREE_NODE FirstNode,
  239. PRED_BLACK_TREE_NODE SecondNode
  240. );
  241. VOID
  242. NetlinkpGenericDestroyFamily (
  243. PNETLINK_GENERIC_FAMILY Family
  244. );
  245. KSTATUS
  246. NetlinkpGenericAllocateFamilyId (
  247. PULONG FamilyId
  248. );
  249. KSTATUS
  250. NetlinkpGenericAllocateMulticastGroups (
  251. PNETLINK_GENERIC_FAMILY Family
  252. );
  253. VOID
  254. NetlinkpGenericFreeMulticastGroups (
  255. PNETLINK_GENERIC_FAMILY Family
  256. );
  257. KSTATUS
  258. NetlinkpGenericValidateMulticastGroup (
  259. ULONG GroupId,
  260. BOOL LockHeld
  261. );
  262. //
  263. // -------------------------------------------------------------------- Globals
  264. //
  265. NET_PROTOCOL_ENTRY NetlinkGenericProtocol = {
  266. {NULL, NULL},
  267. NetSocketDatagram,
  268. SOCKET_INTERNET_PROTOCOL_NETLINK_GENERIC,
  269. NULL,
  270. NULL,
  271. {{0}, {0}, {0}},
  272. {
  273. NetlinkpGenericCreateSocket,
  274. NetlinkpGenericDestroySocket,
  275. NetlinkpGenericBindToAddress,
  276. NetlinkpGenericListen,
  277. NetlinkpGenericAccept,
  278. NetlinkpGenericConnect,
  279. NetlinkpGenericClose,
  280. NetlinkpGenericShutdown,
  281. NetlinkpGenericSend,
  282. NetlinkpGenericProcessReceivedData,
  283. NetlinkpGenericProcessReceivedSocketData,
  284. NetlinkpGenericReceive,
  285. NetlinkpGenericGetSetInformation,
  286. NetlinkpGenericUserControl
  287. }
  288. };
  289. NETLINK_GENERIC_SOCKET_OPTION NetlinkGenericSocketOptions[] = {
  290. {
  291. SocketInformationBasic,
  292. SocketBasicOptionSendBufferSize,
  293. sizeof(ULONG),
  294. TRUE
  295. },
  296. {
  297. SocketInformationBasic,
  298. SocketBasicOptionSendMinimum,
  299. sizeof(ULONG),
  300. FALSE
  301. },
  302. {
  303. SocketInformationBasic,
  304. SocketBasicOptionReceiveBufferSize,
  305. sizeof(ULONG),
  306. TRUE
  307. },
  308. {
  309. SocketInformationBasic,
  310. SocketBasicOptionReceiveMinimum,
  311. sizeof(ULONG),
  312. TRUE
  313. },
  314. {
  315. SocketInformationBasic,
  316. SocketBasicOptionReceiveTimeout,
  317. sizeof(SOCKET_TIME),
  318. TRUE
  319. },
  320. };
  321. NETLINK_PROTOCOL_INTERFACE NetlinkGenericProtocolInterface = {
  322. NetlinkpGenericJoinMulticastGroup
  323. };
  324. PIO_HANDLE NetlinkGenericSocketHandle;
  325. PNET_SOCKET NetlinkGenericSocket;
  326. //
  327. // Store the lock and tree for storing the generic netlink families.
  328. //
  329. PSHARED_EXCLUSIVE_LOCK NetlinkGenericFamilyLock;
  330. RED_BLACK_TREE NetlinkGenericFamilyTree;
  331. //
  332. // Store the next generic family message type to allocate.
  333. //
  334. ULONG NetlinkGenericFamilyNextId = NETLINK_MESSAGE_TYPE_PROTOCOL_MINIMUM;
  335. //
  336. // Store a pointer to the multicast group bitmap and its size, in bytes.
  337. //
  338. PULONG NetlinkGenericMulticastBitmap = NULL;
  339. ULONG NetlinkGenericMulticastBitmapSize = 0;
  340. //
  341. // ------------------------------------------------------------------ Functions
  342. //
  343. NETLINK_API
  344. KSTATUS
  345. NetlinkGenericRegisterFamily (
  346. PNETLINK_GENERIC_FAMILY_PROPERTIES Properties,
  347. PNETLINK_GENERIC_FAMILY *Family
  348. )
  349. /*++
  350. Routine Description:
  351. This routine registers a generic netlink family with the generic netlink
  352. core. The core will route messages with a message type equal to the
  353. family's ID to the provided interface.
  354. Arguments:
  355. Properties - Supplies a pointer to the family properties. The netlink
  356. library will not reference this memory after the function returns, a
  357. copy will be made.
  358. Family - Supplies an optional pointer that receives a pointer to the
  359. registered family.
  360. Return Value:
  361. Status code.
  362. --*/
  363. {
  364. ULONG AllocationSize;
  365. UCHAR Command;
  366. ULONG CommandSize;
  367. PNETLINK_GENERIC_FAMILY FoundFamily;
  368. PRED_BLACK_TREE_NODE FoundNode;
  369. PNETLINK_GENERIC_MULTICAST_GROUP Group;
  370. ULONG Index;
  371. BOOL LockHeld;
  372. BOOL Match;
  373. ULONG MulticastSize;
  374. PNETLINK_GENERIC_FAMILY NewFamily;
  375. ULONG NewId;
  376. KSTATUS Status;
  377. LockHeld = FALSE;
  378. NewFamily = NULL;
  379. if (Properties->Version < NETLINK_GENERIC_FAMILY_PROPERTIES_VERSION) {
  380. Status = STATUS_VERSION_MISMATCH;
  381. goto RegisterFamilyEnd;
  382. }
  383. if ((Properties->CommandCount == 0) || (Properties->Commands == NULL)) {
  384. Status = STATUS_INVALID_PARAMETER;
  385. goto RegisterFamilyEnd;
  386. }
  387. if ((Properties->NameLength == 1) ||
  388. (Properties->NameLength > NETLINK_GENERIC_MAX_FAMILY_NAME_LENGTH)) {
  389. Status = STATUS_INVALID_PARAMETER;
  390. goto RegisterFamilyEnd;
  391. }
  392. if ((Properties->Id < NETLINK_MESSAGE_TYPE_PROTOCOL_MINIMUM) &&
  393. (Properties->Id != 0)) {
  394. Status = STATUS_INVALID_PARAMETER;
  395. goto RegisterFamilyEnd;
  396. }
  397. //
  398. // Allocate and initialize the new generic netlink family.
  399. //
  400. CommandSize = Properties->CommandCount * sizeof(NETLINK_GENERIC_COMMAND);
  401. MulticastSize = Properties->MulticastGroupCount *
  402. sizeof(NETLINK_GENERIC_MULTICAST_GROUP);
  403. AllocationSize = sizeof(NETLINK_GENERIC_FAMILY) +
  404. CommandSize +
  405. MulticastSize;
  406. NewFamily = MmAllocatePagedPool(AllocationSize,
  407. NETLINK_GENERIC_ALLOCATION_TAG);
  408. if (NewFamily == NULL) {
  409. Status = STATUS_INSUFFICIENT_RESOURCES;
  410. goto RegisterFamilyEnd;
  411. }
  412. RtlZeroMemory(NewFamily, sizeof(NETLINK_GENERIC_FAMILY));
  413. NewFamily->ReferenceCount = 1;
  414. RtlCopyMemory(&(NewFamily->Properties),
  415. Properties,
  416. sizeof(NETLINK_GENERIC_FAMILY_PROPERTIES));
  417. NewFamily->Properties.Commands = (PNETLINK_GENERIC_COMMAND)(NewFamily + 1);
  418. RtlCopyMemory(NewFamily->Properties.Commands,
  419. Properties->Commands,
  420. CommandSize);
  421. NewFamily->Properties.MulticastGroups = (PVOID)(NewFamily + 1) +
  422. CommandSize;
  423. RtlCopyMemory(NewFamily->Properties.MulticastGroups,
  424. Properties->MulticastGroups,
  425. MulticastSize);
  426. //
  427. // Acquire the family tree lock and attempt to insert this new family.
  428. //
  429. KeAcquireSharedExclusiveLockExclusive(NetlinkGenericFamilyLock);
  430. LockHeld = TRUE;
  431. //
  432. // Check to make sure the name is not a duplicate.
  433. //
  434. FoundNode = RtlRedBlackTreeGetLowestNode(&NetlinkGenericFamilyTree);
  435. while (FoundNode != NULL) {
  436. FoundFamily = RED_BLACK_TREE_VALUE(FoundNode,
  437. NETLINK_GENERIC_FAMILY,
  438. TreeNode);
  439. Match = RtlAreStringsEqual(FoundFamily->Properties.Name,
  440. NewFamily->Properties.Name,
  441. NETLINK_GENERIC_MAX_FAMILY_NAME_LENGTH);
  442. if (Match != FALSE) {
  443. Status = STATUS_DUPLICATE_ENTRY;
  444. goto RegisterFamilyEnd;
  445. }
  446. FoundNode = RtlRedBlackTreeGetNextNode(&NetlinkGenericFamilyTree,
  447. FALSE,
  448. FoundNode);
  449. }
  450. //
  451. // If the message type is zero, then one needs to be dynamically allocated.
  452. //
  453. if (NewFamily->Properties.Id == 0) {
  454. Status = NetlinkpGenericAllocateFamilyId(&NewId);
  455. if (!KSUCCESS(Status)) {
  456. goto RegisterFamilyEnd;
  457. }
  458. NewFamily->Properties.Id = NewId;
  459. //
  460. // Otherwise make sure the provided message type is not already in use.
  461. //
  462. } else {
  463. FoundNode = RtlRedBlackTreeSearch(&NetlinkGenericFamilyTree,
  464. &(NewFamily->TreeNode));
  465. if (FoundNode != NULL) {
  466. Status = STATUS_DUPLICATE_ENTRY;
  467. goto RegisterFamilyEnd;
  468. }
  469. }
  470. //
  471. // If the family has multicast groups, allocate a region.
  472. //
  473. if (NewFamily->Properties.MulticastGroupCount != 0) {
  474. Status = NetlinkpGenericAllocateMulticastGroups(NewFamily);
  475. if (!KSUCCESS(Status)) {
  476. goto RegisterFamilyEnd;
  477. }
  478. }
  479. //
  480. // Insert the new family into the tree.
  481. //
  482. RtlRedBlackTreeInsert(&NetlinkGenericFamilyTree, &(NewFamily->TreeNode));
  483. KeReleaseSharedExclusiveLockExclusive(NetlinkGenericFamilyLock);
  484. LockHeld = FALSE;
  485. Status = STATUS_SUCCESS;
  486. //
  487. // Blast out some notifications.
  488. //
  489. Command = NETLINK_CONTROL_COMMAND_NEW_FAMILY;
  490. NetlinkpGenericControlSendNotification(NewFamily, Command, NULL);
  491. for (Index = 0;
  492. Index < NewFamily->Properties.MulticastGroupCount;
  493. Index += 1) {
  494. Command = NETLINK_CONTROL_COMMAND_NEW_MULTICAST_GROUP;
  495. Group = &(NewFamily->Properties.MulticastGroups[Index]);
  496. NetlinkpGenericControlSendNotification(NewFamily, Command, Group);
  497. }
  498. RegisterFamilyEnd:
  499. if (LockHeld != FALSE) {
  500. KeReleaseSharedExclusiveLockExclusive(NetlinkGenericFamilyLock);
  501. }
  502. if (!KSUCCESS(Status)) {
  503. if (NewFamily != INVALID_HANDLE) {
  504. NetlinkpGenericFamilyReleaseReference(NewFamily);
  505. NewFamily = INVALID_HANDLE;
  506. }
  507. }
  508. if (Family != NULL) {
  509. *Family = NewFamily;
  510. }
  511. return Status;
  512. }
  513. NETLINK_API
  514. VOID
  515. NetlinkGenericUnregisterFamily (
  516. PNETLINK_GENERIC_FAMILY Family
  517. )
  518. /*++
  519. Routine Description:
  520. This routine unregisters the given generic netlink family.
  521. Arguments:
  522. Family - Supplies a pointer to the generic netlink family to unregister.
  523. Return Value:
  524. None.
  525. --*/
  526. {
  527. UCHAR Command;
  528. PNETLINK_GENERIC_FAMILY FoundFamily;
  529. PRED_BLACK_TREE_NODE FoundNode;
  530. BOOL LockHeld;
  531. KeAcquireSharedExclusiveLockExclusive(NetlinkGenericFamilyLock);
  532. LockHeld = TRUE;
  533. FoundNode = RtlRedBlackTreeSearch(&NetlinkGenericFamilyTree,
  534. &(Family->TreeNode));
  535. if (FoundNode == NULL) {
  536. goto UnregisterFamilyEnd;
  537. }
  538. FoundFamily = RED_BLACK_TREE_VALUE(FoundNode,
  539. NETLINK_GENERIC_FAMILY,
  540. TreeNode);
  541. if (FoundFamily != Family) {
  542. goto UnregisterFamilyEnd;
  543. }
  544. RtlRedBlackTreeRemove(&NetlinkGenericFamilyTree, &(Family->TreeNode));
  545. //
  546. // If the family had allocated multicast groups, then release them now.
  547. //
  548. if ((Family->Properties.MulticastGroupCount != 0) &&
  549. (Family->MulticastGroupOffset != 0)) {
  550. NetlinkpGenericFreeMulticastGroups(Family);
  551. }
  552. KeReleaseSharedExclusiveLockExclusive(NetlinkGenericFamilyLock);
  553. LockHeld = FALSE;
  554. //
  555. // Before releasing the last reference, make sure the family is not in the
  556. // middle of receiving a packet. If it is, netcore could be able to call
  557. // into the driver that is unregistering the family. It would be bad for
  558. // that driver to disappear.
  559. //
  560. while (Family->ReferenceCount > 1) {
  561. KeYield();
  562. }
  563. Command = NETLINK_CONTROL_COMMAND_DELETE_FAMILY;
  564. NetlinkpGenericControlSendNotification(Family, Command, NULL);
  565. NetlinkpGenericFamilyReleaseReference(Family);
  566. UnregisterFamilyEnd:
  567. if (LockHeld != FALSE) {
  568. KeReleaseSharedExclusiveLockExclusive(NetlinkGenericFamilyLock);
  569. }
  570. return;
  571. }
  572. NETLINK_API
  573. KSTATUS
  574. NetlinkGenericSendCommand (
  575. PNETLINK_GENERIC_FAMILY Family,
  576. PNET_PACKET_BUFFER Packet,
  577. PNETWORK_ADDRESS DestinationAddress
  578. )
  579. /*++
  580. Routine Description:
  581. This routine sends a generic netlink command. The generic header should
  582. already be filled out.
  583. Arguments:
  584. Family - Supplies a pointer to the generic netlink family sending the
  585. command.
  586. Packet - Supplies a pointer to the network packet to be sent.
  587. DestinationAddress - Supplies a pointer to the destination address to which
  588. the command will be sent.
  589. Return Value:
  590. Status code.
  591. --*/
  592. {
  593. KSTATUS Status;
  594. Status = NetlinkSendMessage(NetlinkGenericSocket,
  595. Packet,
  596. DestinationAddress);
  597. return Status;
  598. }
  599. NETLINK_API
  600. KSTATUS
  601. NetlinkGenericSendMulticastCommand (
  602. PNETLINK_GENERIC_FAMILY Family,
  603. PNET_PACKET_BUFFER Packet,
  604. ULONG GroupId
  605. )
  606. /*++
  607. Routine Description:
  608. This routine multicasts the given command packet to the specified group.
  609. The packet should already store the completed command, ready to send.
  610. Arguments:
  611. Family - Supplies a pointer to the generic netlink family sending the
  612. multicast command.
  613. Packet - Supplies a pointer to the network packet to be sent.
  614. GroupId - Supplies the family's multicast group ID over which to send the
  615. command.
  616. Return Value:
  617. Status code.
  618. --*/
  619. {
  620. PNETWORK_ADDRESS Destination;
  621. NETLINK_ADDRESS NetlinkDestination;
  622. //
  623. // The destination is based on the group ID, which must be adjusted by the
  624. // offset allocated when the family as registered. The caller does not know
  625. // about this offset.
  626. //
  627. NetlinkDestination.Domain = NetDomainNetlink;
  628. NetlinkDestination.Port = 0;
  629. NetlinkDestination.Group = Family->MulticastGroupOffset + GroupId;
  630. Destination = (PNETWORK_ADDRESS)&NetlinkDestination;
  631. return NetlinkGenericSendCommand(Family, Packet, Destination);
  632. }
  633. NETLINK_API
  634. KSTATUS
  635. NetlinkGenericAppendHeaders (
  636. PNETLINK_GENERIC_FAMILY Family,
  637. PNET_PACKET_BUFFER Packet,
  638. ULONG Length,
  639. ULONG SequenceNumber,
  640. USHORT Flags,
  641. UCHAR Command,
  642. UCHAR Version
  643. )
  644. /*++
  645. Routine Description:
  646. This routine appends the base and generic netlink headers to the given
  647. packet, validating that there is enough space remaining in the buffer and
  648. moving the data offset forward to the first byte after the headers once
  649. they have been added.
  650. Arguments:
  651. Family - Supplies a pointer to the netlink generic family to which the
  652. packet belongs.
  653. Packet - Supplies a pointer to the network packet to which the headers will
  654. be appended.
  655. Length - Supplies the length of the generic command payload, not including
  656. any headers.
  657. SequenceNumber - Supplies the desired sequence number for the netlink
  658. message.
  659. Flags - Supplies a bitmask of netlink message flags to be set. See
  660. NETLINK_HEADER_FLAG_* for definitions.
  661. Command - Supplies the generic netlink command to bet set in the header.
  662. Version - Supplies the version number of the command.
  663. Return Value:
  664. Status code.
  665. --*/
  666. {
  667. PNETLINK_GENERIC_HEADER Header;
  668. ULONG PacketLength;
  669. KSTATUS Status;
  670. Length += NETLINK_GENERIC_HEADER_LENGTH;
  671. Status = NetlinkAppendHeader(NetlinkGenericSocket,
  672. Packet,
  673. Length,
  674. SequenceNumber,
  675. Family->Properties.Id,
  676. Flags);
  677. if (!KSUCCESS(Status)) {
  678. goto AppendHeadersEnd;
  679. }
  680. PacketLength = Packet->FooterOffset - Packet->DataOffset;
  681. if (PacketLength < Length) {
  682. Status = STATUS_BUFFER_TOO_SMALL;
  683. goto AppendHeadersEnd;
  684. }
  685. Header = Packet->Buffer + Packet->DataOffset;
  686. Header->Command = Command;
  687. Header->Version = Version;
  688. Packet->DataOffset += NETLINK_GENERIC_HEADER_LENGTH;
  689. Header->Reserved = 0;
  690. Status = STATUS_SUCCESS;
  691. AppendHeadersEnd:
  692. return Status;
  693. }
  694. VOID
  695. NetpNetlinkGenericInitialize (
  696. ULONG Phase
  697. )
  698. /*++
  699. Routine Description:
  700. This routine initializes support for generic netlink sockets.
  701. Arguments:
  702. Phase - Supplies the phase of the initialization. Phase 0 happens before
  703. the networking core registers with the kernel, meaning sockets cannot
  704. be created. Phase 1 happens after the networking core has registered
  705. with the kernel allowing socket creation.
  706. Return Value:
  707. None.
  708. --*/
  709. {
  710. NETLINK_ADDRESS Address;
  711. KSTATUS Status;
  712. //
  713. // In phase 0, register the generic netlink socket handlers with the core
  714. // networking library so that it is ready to go when netcore registers with
  715. // the kernel.
  716. //
  717. if (Phase == 0) {
  718. NetlinkGenericFamilyLock = KeCreateSharedExclusiveLock();
  719. if (NetlinkGenericFamilyLock == NULL) {
  720. Status = STATUS_INSUFFICIENT_RESOURCES;
  721. goto InitializeEnd;
  722. }
  723. RtlRedBlackTreeInitialize(&NetlinkGenericFamilyTree,
  724. 0,
  725. NetlinkpGenericCompareFamilies);
  726. Status = NetRegisterProtocol(&NetlinkGenericProtocol, NULL);
  727. if (!KSUCCESS(Status)) {
  728. goto InitializeEnd;
  729. }
  730. //
  731. // In phase 1, create netcore's kernel-side generic netlink socket.
  732. //
  733. } else {
  734. ASSERT(Phase == 1);
  735. Status = IoSocketCreate(NetDomainNetlink,
  736. NetSocketDatagram,
  737. SOCKET_INTERNET_PROTOCOL_NETLINK_GENERIC,
  738. 0,
  739. &NetlinkGenericSocketHandle);
  740. if (!KSUCCESS(Status)) {
  741. goto InitializeEnd;
  742. }
  743. Status = IoGetSocketFromHandle(NetlinkGenericSocketHandle,
  744. (PVOID)&NetlinkGenericSocket);
  745. if (!KSUCCESS(Status)) {
  746. goto InitializeEnd;
  747. }
  748. //
  749. // Add the kernel flag and bind it to port 0.
  750. //
  751. RtlAtomicOr32(&(NetlinkGenericSocket->Flags), NET_SOCKET_FLAG_KERNEL);
  752. RtlZeroMemory(&Address, sizeof(NETLINK_ADDRESS));
  753. Address.Domain = NetDomainNetlink;
  754. Status = IoSocketBindToAddress(TRUE,
  755. NetlinkGenericSocketHandle,
  756. NULL,
  757. &(Address.NetworkAddress),
  758. NULL,
  759. 0);
  760. if (!KSUCCESS(Status)) {
  761. goto InitializeEnd;
  762. }
  763. NetlinkpGenericControlInitialize();
  764. }
  765. InitializeEnd:
  766. ASSERT(KSUCCESS(Status));
  767. return;
  768. }
  769. KSTATUS
  770. NetlinkpGenericCreateSocket (
  771. PNET_PROTOCOL_ENTRY ProtocolEntry,
  772. PNET_NETWORK_ENTRY NetworkEntry,
  773. ULONG NetworkProtocol,
  774. PNET_SOCKET *NewSocket
  775. )
  776. /*++
  777. Routine Description:
  778. This routine allocates resources associated with a new socket. The protocol
  779. driver is responsible for allocating the structure (with additional length
  780. for any of its context). The core networking library will fill in the
  781. common header when this routine returns.
  782. Arguments:
  783. ProtocolEntry - Supplies a pointer to the protocol information.
  784. NetworkEntry - Supplies a pointer to the network information.
  785. NetworkProtocol - Supplies the raw protocol value for this socket used on
  786. the network. This value is network specific.
  787. NewSocket - Supplies a pointer where a pointer to a newly allocated
  788. socket structure will be returned. The caller is responsible for
  789. allocating the socket (and potentially a larger structure for its own
  790. context). The core network library will fill in the standard socket
  791. structure after this routine returns.
  792. Return Value:
  793. Status code.
  794. --*/
  795. {
  796. PNETLINK_GENERIC_SOCKET GenericSocket;
  797. PNET_NETWORK_INITIALIZE_SOCKET InitializeSocket;
  798. ULONG MaxPacketSize;
  799. PNET_SOCKET NetSocket;
  800. PNET_PACKET_SIZE_INFORMATION PacketSizeInformation;
  801. KSTATUS Status;
  802. ASSERT(ProtocolEntry->Type == NetSocketDatagram);
  803. ASSERT(NetworkProtocol == ProtocolEntry->ParentProtocolNumber);
  804. ASSERT(NetworkProtocol == SOCKET_INTERNET_PROTOCOL_NETLINK_GENERIC);
  805. NetSocket = NULL;
  806. GenericSocket = MmAllocatePagedPool(sizeof(NETLINK_GENERIC_SOCKET),
  807. NETLINK_GENERIC_ALLOCATION_TAG);
  808. if (GenericSocket == NULL) {
  809. Status = STATUS_INSUFFICIENT_RESOURCES;
  810. goto GenericCreateSocketEnd;
  811. }
  812. RtlZeroMemory(GenericSocket, sizeof(NETLINK_GENERIC_SOCKET));
  813. NetSocket = &(GenericSocket->NetlinkSocket.NetSocket);
  814. NetSocket->KernelSocket.Protocol = NetworkProtocol;
  815. NetSocket->KernelSocket.ReferenceCount = 1;
  816. RtlCopyMemory(&(GenericSocket->NetlinkSocket.ProtocolInterface),
  817. &NetlinkGenericProtocolInterface,
  818. sizeof(NETLINK_PROTOCOL_INTERFACE));
  819. INITIALIZE_LIST_HEAD(&(GenericSocket->ReceivedPacketList));
  820. GenericSocket->ReceiveTimeout = WAIT_TIME_INDEFINITE;
  821. GenericSocket->ReceiveBufferTotalSize =
  822. NETLINK_GENERIC_DEFAULT_RECEIVE_BUFFER_SIZE;
  823. GenericSocket->ReceiveBufferFreeSize =
  824. GenericSocket->ReceiveBufferTotalSize;
  825. GenericSocket->ReceiveMinimum = NETLINK_GENERIC_DEFAULT_RECEIVE_MINIMUM;
  826. GenericSocket->MaxPacketSize = NETLINK_GENERIC_MAX_PACKET_SIZE;
  827. GenericSocket->ReceiveLock = KeCreateQueuedLock();
  828. if (GenericSocket->ReceiveLock == NULL) {
  829. Status = STATUS_INSUFFICIENT_RESOURCES;
  830. goto GenericCreateSocketEnd;
  831. }
  832. //
  833. // Give the lower layers a chance to initialize. Start the maximum packet
  834. // size at the largest possible value.
  835. //
  836. PacketSizeInformation = &(NetSocket->PacketSizeInformation);
  837. PacketSizeInformation->MaxPacketSize = MAX_ULONG;
  838. InitializeSocket = NetworkEntry->Interface.InitializeSocket;
  839. Status = InitializeSocket(ProtocolEntry,
  840. NetworkEntry,
  841. NetworkProtocol,
  842. NetSocket);
  843. if (!KSUCCESS(Status)) {
  844. goto GenericCreateSocketEnd;
  845. }
  846. //
  847. // If the max packet size is greater than what is allowed for a generic
  848. // netlink packet plus all the previous headers and footers, then truncate
  849. // the max packet size. Note that there is no additional header for generic
  850. // netlink packets.
  851. //
  852. MaxPacketSize = PacketSizeInformation->HeaderSize +
  853. NETLINK_GENERIC_MAX_PACKET_SIZE +
  854. PacketSizeInformation->FooterSize;
  855. if (PacketSizeInformation->MaxPacketSize > MaxPacketSize) {
  856. PacketSizeInformation->MaxPacketSize = MaxPacketSize;
  857. }
  858. PacketSizeInformation->HeaderSize += NETLINK_GENERIC_HEADER_LENGTH;
  859. Status = STATUS_SUCCESS;
  860. GenericCreateSocketEnd:
  861. if (!KSUCCESS(Status)) {
  862. if (GenericSocket != NULL) {
  863. if (GenericSocket->ReceiveLock != NULL) {
  864. KeDestroyQueuedLock(GenericSocket->ReceiveLock);
  865. }
  866. MmFreePagedPool(GenericSocket);
  867. GenericSocket = NULL;
  868. NetSocket = NULL;
  869. }
  870. }
  871. *NewSocket = NetSocket;
  872. return Status;
  873. }
  874. VOID
  875. NetlinkpGenericDestroySocket (
  876. PNET_SOCKET Socket
  877. )
  878. /*++
  879. Routine Description:
  880. This routine destroys resources associated with an open socket, officially
  881. marking the end of the kernel and core networking library's knowledge of
  882. this structure.
  883. Arguments:
  884. Socket - Supplies a pointer to the socket to destroy. The core networking
  885. library will have already destroyed any resources inside the common
  886. header, the protocol should not reach through any pointers inside the
  887. socket header except the protocol and network entries.
  888. Return Value:
  889. None. This routine is responsible for freeing the memory associated with
  890. the socket structure itself.
  891. --*/
  892. {
  893. PNETLINK_GENERIC_SOCKET GenericSocket;
  894. PNETLINK_GENERIC_RECEIVED_PACKET Packet;
  895. GenericSocket = (PNETLINK_GENERIC_SOCKET)Socket;
  896. //
  897. // Loop through and free any leftover packets.
  898. //
  899. KeAcquireQueuedLock(GenericSocket->ReceiveLock);
  900. while (!LIST_EMPTY(&(GenericSocket->ReceivedPacketList))) {
  901. Packet = LIST_VALUE(GenericSocket->ReceivedPacketList.Next,
  902. NETLINK_GENERIC_RECEIVED_PACKET,
  903. ListEntry);
  904. LIST_REMOVE(&(Packet->ListEntry));
  905. GenericSocket->ReceiveBufferFreeSize += Packet->NetPacket->DataSize;
  906. NetFreeBuffer(Packet->NetPacket);
  907. MmFreePagedPool(Packet);
  908. }
  909. ASSERT(GenericSocket->ReceiveBufferFreeSize ==
  910. GenericSocket->ReceiveBufferTotalSize);
  911. KeReleaseQueuedLock(GenericSocket->ReceiveLock);
  912. KeDestroyQueuedLock(GenericSocket->ReceiveLock);
  913. MmFreePagedPool(GenericSocket);
  914. return;
  915. }
  916. KSTATUS
  917. NetlinkpGenericBindToAddress (
  918. PNET_SOCKET Socket,
  919. PNET_LINK Link,
  920. PNETWORK_ADDRESS Address
  921. )
  922. /*++
  923. Routine Description:
  924. This routine binds the given socket to the specified network address.
  925. Usually this is a no-op for the protocol, it's simply responsible for
  926. passing the request down to the network layer.
  927. Arguments:
  928. Socket - Supplies a pointer to the socket to bind.
  929. Link - Supplies an optional pointer to a link to bind to.
  930. Address - Supplies a pointer to the address to bind the socket to.
  931. Return Value:
  932. Status code.
  933. --*/
  934. {
  935. BOOL LockHeld;
  936. KSTATUS Status;
  937. LockHeld = FALSE;
  938. //
  939. // Netlink sockets are allowed to be rebound to different multicast groups.
  940. //
  941. if ((Socket->LocalAddress.Domain != NetDomainInvalid) &&
  942. (Socket->LocalAddress.Port != Address->Port)) {
  943. Status = STATUS_INVALID_PARAMETER;
  944. goto GenericBindToAddressEnd;
  945. }
  946. //
  947. // Only netlink addresses are supported.
  948. //
  949. if (Address->Domain != NetDomainNetlink) {
  950. Status = STATUS_NOT_SUPPORTED;
  951. goto GenericBindToAddressEnd;
  952. }
  953. //
  954. // Pass the request down to the network layer.
  955. //
  956. Status = Socket->Network->Interface.BindToAddress(Socket, Link, Address);
  957. if (!KSUCCESS(Status)) {
  958. goto GenericBindToAddressEnd;
  959. }
  960. //
  961. // Begin listening immediately, as there is no explicit listen step for
  962. // generic netlink sockets.
  963. //
  964. Status = Socket->Network->Interface.Listen(Socket);
  965. if (!KSUCCESS(Status)) {
  966. goto GenericBindToAddressEnd;
  967. }
  968. IoSetIoObjectState(Socket->KernelSocket.IoState, POLL_EVENT_OUT, TRUE);
  969. GenericBindToAddressEnd:
  970. if (LockHeld != FALSE) {
  971. KeReleaseSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  972. }
  973. return Status;
  974. }
  975. KSTATUS
  976. NetlinkpGenericListen (
  977. PNET_SOCKET Socket
  978. )
  979. /*++
  980. Routine Description:
  981. This routine adds a bound socket to the list of listening sockets,
  982. officially allowing clients to attempt to connect to it.
  983. Arguments:
  984. Socket - Supplies a pointer to the socket to mark as listning.
  985. Return Value:
  986. Status code.
  987. --*/
  988. {
  989. return STATUS_NOT_SUPPORTED;
  990. }
  991. KSTATUS
  992. NetlinkpGenericAccept (
  993. PNET_SOCKET Socket,
  994. PIO_HANDLE *NewConnectionSocket,
  995. PNETWORK_ADDRESS RemoteAddress
  996. )
  997. /*++
  998. Routine Description:
  999. This routine accepts an incoming connection on a listening connection-based
  1000. socket.
  1001. Arguments:
  1002. Socket - Supplies a pointer to the socket to accept a connection from.
  1003. NewConnectionSocket - Supplies a pointer where a new socket will be
  1004. returned that represents the accepted connection with the remote
  1005. host.
  1006. RemoteAddress - Supplies a pointer where the address of the connected
  1007. remote host will be returned.
  1008. Return Value:
  1009. Status code.
  1010. --*/
  1011. {
  1012. return STATUS_NOT_SUPPORTED;
  1013. }
  1014. KSTATUS
  1015. NetlinkpGenericConnect (
  1016. PNET_SOCKET Socket,
  1017. PNETWORK_ADDRESS Address
  1018. )
  1019. /*++
  1020. Routine Description:
  1021. This routine attempts to make an outgoing connection to a server.
  1022. Arguments:
  1023. Socket - Supplies a pointer to the socket to use for the connection.
  1024. Address - Supplies a pointer to the address to connect to.
  1025. Return Value:
  1026. Status code.
  1027. --*/
  1028. {
  1029. ULONG GroupId;
  1030. PNETLINK_ADDRESS NetlinkAddress;
  1031. KSTATUS Status;
  1032. //
  1033. // If there is a request to connect to a multicast group, then validate it.
  1034. //
  1035. NetlinkAddress = (PNETLINK_ADDRESS)Address;
  1036. if (NetlinkAddress->Group != 0) {
  1037. GroupId = NetlinkAddress->Group;
  1038. Status = NetlinkpGenericValidateMulticastGroup(GroupId, FALSE);
  1039. if (!KSUCCESS(Status)) {
  1040. goto GenericConnectEnd;
  1041. }
  1042. }
  1043. //
  1044. // Pass the request down to the network layer.
  1045. //
  1046. Status = Socket->Network->Interface.Connect(Socket, Address);
  1047. if (!KSUCCESS(Status)) {
  1048. goto GenericConnectEnd;
  1049. }
  1050. IoSetIoObjectState(Socket->KernelSocket.IoState, POLL_EVENT_OUT, TRUE);
  1051. GenericConnectEnd:
  1052. return Status;
  1053. }
  1054. KSTATUS
  1055. NetlinkpGenericClose (
  1056. PNET_SOCKET Socket
  1057. )
  1058. /*++
  1059. Routine Description:
  1060. This routine closes a socket connection.
  1061. Arguments:
  1062. Socket - Supplies a pointer to the socket to shut down.
  1063. Return Value:
  1064. Status code.
  1065. --*/
  1066. {
  1067. KSTATUS Status;
  1068. //
  1069. // Close it at the lower level and then release the reference taken on
  1070. // create if the close was successful.
  1071. //
  1072. Status = Socket->Network->Interface.Close(Socket);
  1073. if (!KSUCCESS(Status)) {
  1074. goto GenericCloseEnd;
  1075. }
  1076. IoSocketReleaseReference(&(Socket->KernelSocket));
  1077. GenericCloseEnd:
  1078. return Status;
  1079. }
  1080. KSTATUS
  1081. NetlinkpGenericShutdown (
  1082. PNET_SOCKET Socket,
  1083. ULONG ShutdownType
  1084. )
  1085. /*++
  1086. Routine Description:
  1087. This routine shuts down communication with a given socket.
  1088. Arguments:
  1089. Socket - Supplies a pointer to the socket.
  1090. ShutdownType - Supplies the shutdown type to perform. See the
  1091. SOCKET_SHUTDOWN_* definitions.
  1092. Return Value:
  1093. Status code.
  1094. --*/
  1095. {
  1096. return STATUS_NOT_SUPPORTED;
  1097. }
  1098. KSTATUS
  1099. NetlinkpGenericSend (
  1100. BOOL FromKernelMode,
  1101. PNET_SOCKET Socket,
  1102. PSOCKET_IO_PARAMETERS Parameters,
  1103. PIO_BUFFER IoBuffer
  1104. )
  1105. /*++
  1106. Routine Description:
  1107. This routine sends the given data buffer through the network using a
  1108. specific protocol.
  1109. Arguments:
  1110. FromKernelMode - Supplies a boolean indicating whether the request is
  1111. coming from kernel mode (TRUE) or user mode (FALSE).
  1112. Socket - Supplies a pointer to the socket to send the data to.
  1113. Parameters - Supplies a pointer to the socket I/O parameters. This will
  1114. always be a kernel mode pointer.
  1115. IoBuffer - Supplies a pointer to the I/O buffer containing the data to
  1116. send.
  1117. Return Value:
  1118. Status code.
  1119. --*/
  1120. {
  1121. UINTN BytesComplete;
  1122. PNETWORK_ADDRESS Destination;
  1123. NETWORK_ADDRESS DestinationLocal;
  1124. PNETLINK_GENERIC_SOCKET GenericSocket;
  1125. NETWORK_ADDRESS LocalAddress;
  1126. PNET_PACKET_BUFFER Packet;
  1127. NET_PACKET_LIST PacketList;
  1128. UINTN Size;
  1129. KSTATUS Status;
  1130. ASSERT(Socket->PacketSizeInformation.MaxPacketSize >
  1131. sizeof(NETLINK_HEADER));
  1132. BytesComplete = 0;
  1133. NET_INITIALIZE_PACKET_LIST(&PacketList);
  1134. Size = Parameters->Size;
  1135. GenericSocket = (PNETLINK_GENERIC_SOCKET)Socket;
  1136. Parameters->SocketIoFlags = 0;
  1137. Destination = Parameters->NetworkAddress;
  1138. if ((Destination != NULL) && (FromKernelMode == FALSE)) {
  1139. Status = MmCopyFromUserMode(&DestinationLocal,
  1140. Destination,
  1141. sizeof(NETWORK_ADDRESS));
  1142. Destination = &DestinationLocal;
  1143. if (!KSUCCESS(Status)) {
  1144. goto GenericSendEnd;
  1145. }
  1146. }
  1147. if ((Destination == NULL) ||
  1148. (Destination->Domain == NetDomainInvalid)) {
  1149. if (Socket->BindingType != SocketFullyBound) {
  1150. Status = STATUS_NOT_CONFIGURED;
  1151. goto GenericSendEnd;
  1152. }
  1153. Destination = &(Socket->RemoteAddress);
  1154. }
  1155. //
  1156. // Fail if there's ancillary data.
  1157. //
  1158. if (Parameters->ControlDataSize != 0) {
  1159. Status = STATUS_NOT_SUPPORTED;
  1160. goto GenericSendEnd;
  1161. }
  1162. //
  1163. // If the size is greater than the generic netlink socket's maximum packet
  1164. // size, fail.
  1165. //
  1166. if (Size > GenericSocket->MaxPacketSize) {
  1167. Status = STATUS_MESSAGE_TOO_LONG;
  1168. goto GenericSendEnd;
  1169. }
  1170. //
  1171. // If the socket is not yet bound, then at least try to bind it to a local
  1172. // port. This bind attempt may race with another bind attempt, but leave it
  1173. // to the socket owner to synchronize bind and send.
  1174. //
  1175. if (Socket->BindingType == SocketBindingInvalid) {
  1176. RtlZeroMemory(&LocalAddress, sizeof(NETWORK_ADDRESS));
  1177. LocalAddress.Domain = Socket->Network->Domain;
  1178. Status = NetlinkpGenericBindToAddress(Socket, NULL, &LocalAddress);
  1179. if (!KSUCCESS(Status)) {
  1180. goto GenericSendEnd;
  1181. }
  1182. }
  1183. //
  1184. // Allocate a buffer for the packet.
  1185. //
  1186. Status = NetAllocateBuffer(0,
  1187. Size,
  1188. 0,
  1189. NULL,
  1190. 0,
  1191. &Packet);
  1192. if (!KSUCCESS(Status)) {
  1193. goto GenericSendEnd;
  1194. }
  1195. NET_ADD_PACKET_TO_LIST(Packet, &PacketList);
  1196. //
  1197. // Copy the data to the packet's buffer.
  1198. //
  1199. Status = MmCopyIoBufferData(IoBuffer,
  1200. Packet->Buffer + Packet->DataOffset,
  1201. BytesComplete,
  1202. Size - BytesComplete,
  1203. FALSE);
  1204. if (!KSUCCESS(Status)) {
  1205. goto GenericSendEnd;
  1206. }
  1207. //
  1208. // Send the packet down to the network layer.
  1209. //
  1210. Status = Socket->Network->Interface.Send(Socket,
  1211. Destination,
  1212. NULL,
  1213. &PacketList);
  1214. if (!KSUCCESS(Status)) {
  1215. goto GenericSendEnd;
  1216. }
  1217. Packet = NULL;
  1218. BytesComplete = Size;
  1219. GenericSendEnd:
  1220. Parameters->Size = BytesComplete;
  1221. if (!KSUCCESS(Status)) {
  1222. NetDestroyBufferList(&PacketList);
  1223. }
  1224. return Status;
  1225. }
  1226. VOID
  1227. NetlinkpGenericProcessReceivedData (
  1228. PNET_LINK Link,
  1229. PNET_PACKET_BUFFER Packet,
  1230. PNETWORK_ADDRESS SourceAddress,
  1231. PNETWORK_ADDRESS DestinationAddress,
  1232. PNET_PROTOCOL_ENTRY ProtocolEntry
  1233. )
  1234. /*++
  1235. Routine Description:
  1236. This routine is called to process a received packet.
  1237. Arguments:
  1238. Link - Supplies a pointer to the link that received the packet.
  1239. Packet - Supplies a pointer to a structure describing the incoming packet.
  1240. This structure may be used as a scratch space while this routine
  1241. executes and the packet travels up the stack, but will not be accessed
  1242. after this routine returns.
  1243. SourceAddress - Supplies a pointer to the source (remote) address that the
  1244. packet originated from. This memory will not be referenced once the
  1245. function returns, it can be stack allocated.
  1246. DestinationAddress - Supplies a pointer to the destination (local) address
  1247. that the packet is heading to. This memory will not be referenced once
  1248. the function returns, it can be stack allocated.
  1249. ProtocolEntry - Supplies a pointer to this protocol's protocol entry.
  1250. Return Value:
  1251. None.
  1252. --*/
  1253. {
  1254. ASSERT(FALSE);
  1255. return;
  1256. }
  1257. KSTATUS
  1258. NetlinkpGenericProcessReceivedSocketData (
  1259. PNET_LINK Link,
  1260. PNET_SOCKET Socket,
  1261. PNET_PACKET_BUFFER Packet,
  1262. PNETWORK_ADDRESS SourceAddress,
  1263. PNETWORK_ADDRESS DestinationAddress
  1264. )
  1265. /*++
  1266. Routine Description:
  1267. This routine is called for a particular socket to process a received packet
  1268. that was sent to it.
  1269. Arguments:
  1270. Link - Supplies a pointer to the network link that received the packet.
  1271. Socket - Supplies a pointer to the socket that received the packet.
  1272. Packet - Supplies a pointer to a structure describing the incoming packet.
  1273. Use of this structure depends on its packet flags and the socket type.
  1274. If it is a multicast packet or it was sent to a kernel socket, then it
  1275. must not be modified. Otherwise this routine is responsible for the
  1276. destruction of the packet.
  1277. SourceAddress - Supplies a pointer to the source (remote) address that the
  1278. packet originated from. This memory will not be referenced once the
  1279. function returns, it can be stack allocated.
  1280. DestinationAddress - Supplies a pointer to the destination (local) address
  1281. that the packet is heading to. This memory will not be referenced once
  1282. the function returns, it can be stack allocated.
  1283. Return Value:
  1284. Status code.
  1285. --*/
  1286. {
  1287. ULONG AllocationSize;
  1288. PNETLINK_GENERIC_SOCKET GenericSocket;
  1289. PNET_PACKET_BUFFER PacketCopy;
  1290. ULONG PacketLength;
  1291. PNETLINK_GENERIC_RECEIVED_PACKET ReceivePacket;
  1292. KSTATUS Status;
  1293. ASSERT(KeGetRunLevel() == RunLevelLow);
  1294. PacketCopy = NULL;
  1295. GenericSocket = (PNETLINK_GENERIC_SOCKET)Socket;
  1296. //
  1297. // If this is a kernel socket is on the receiving end, then route the
  1298. // packet directly to the kernel component.
  1299. //
  1300. if ((Socket->Flags & NET_SOCKET_FLAG_KERNEL) != 0) {
  1301. Status = NetlinkpGenericProcessReceivedKernelData(Link,
  1302. Socket,
  1303. Packet,
  1304. SourceAddress,
  1305. DestinationAddress);
  1306. return Status;
  1307. }
  1308. //
  1309. // Create a received packet entry for this data. This routine is invoked by
  1310. // the network core on multicast packets. Create a copy of the network
  1311. // packet as it may need to be sent to multiple sockets, no single socket
  1312. // can own it.
  1313. //
  1314. AllocationSize = sizeof(NETLINK_GENERIC_RECEIVED_PACKET);
  1315. ReceivePacket = MmAllocatePagedPool(AllocationSize,
  1316. NETLINK_GENERIC_ALLOCATION_TAG);
  1317. if (ReceivePacket == NULL) {
  1318. Status = STATUS_INSUFFICIENT_RESOURCES;
  1319. goto ProcessReceivedSocketDataEnd;
  1320. }
  1321. RtlCopyMemory(&(ReceivePacket->Address),
  1322. SourceAddress,
  1323. sizeof(NETWORK_ADDRESS));
  1324. //
  1325. // If the original packet is a multicast packet, then its services are
  1326. // needed again by another socket. Make a copy and save that.
  1327. //
  1328. if ((Packet->Flags & NET_PACKET_FLAG_MULTICAST) != 0) {
  1329. PacketLength = Packet->FooterOffset - Packet->DataOffset;
  1330. Status = NetAllocateBuffer(0, PacketLength, 0, NULL, 0, &PacketCopy);
  1331. if (!KSUCCESS(Status)) {
  1332. goto ProcessReceivedSocketDataEnd;
  1333. }
  1334. RtlCopyMemory(PacketCopy->Buffer + PacketCopy->DataOffset,
  1335. Packet->Buffer + Packet->DataOffset,
  1336. PacketLength);
  1337. ReceivePacket->NetPacket = PacketCopy;
  1338. //
  1339. // Otherwise set the packet directly in the generic receive packet.
  1340. //
  1341. } else {
  1342. ReceivePacket->NetPacket = Packet;
  1343. }
  1344. //
  1345. // Work to insert the packet on the list of received packets.
  1346. //
  1347. NetlinkpGenericInsertReceivedPacket(GenericSocket, ReceivePacket);
  1348. ProcessReceivedSocketDataEnd:
  1349. if (!KSUCCESS(Status)) {
  1350. if (ReceivePacket != NULL) {
  1351. MmFreePagedPool(ReceivePacket);
  1352. }
  1353. if (PacketCopy != NULL) {
  1354. NetFreeBuffer(PacketCopy);
  1355. }
  1356. if ((Packet->Flags & NET_PACKET_FLAG_MULTICAST) == 0) {
  1357. NetFreeBuffer(Packet);
  1358. }
  1359. }
  1360. return Status;
  1361. }
  1362. KSTATUS
  1363. NetlinkpGenericReceive (
  1364. BOOL FromKernelMode,
  1365. PNET_SOCKET Socket,
  1366. PSOCKET_IO_PARAMETERS Parameters,
  1367. PIO_BUFFER IoBuffer
  1368. )
  1369. /*++
  1370. Routine Description:
  1371. This routine is called by the user to receive data from the socket on a
  1372. particular protocol.
  1373. Arguments:
  1374. FromKernelMode - Supplies a boolean indicating whether the request is
  1375. coming from kernel mode (TRUE) or user mode (FALSE).
  1376. Socket - Supplies a pointer to the socket to receive data from.
  1377. Parameters - Supplies a pointer to the socket I/O parameters.
  1378. IoBuffer - Supplies a pointer to the I/O buffer where the received data
  1379. will be returned.
  1380. Return Value:
  1381. STATUS_SUCCESS if any bytes were read.
  1382. STATUS_TIMEOUT if the request timed out.
  1383. STATUS_BUFFER_TOO_SMALL if the incoming datagram was too large for the
  1384. buffer. The remainder of the datagram is discarded in this case.
  1385. Other error codes on other failures.
  1386. --*/
  1387. {
  1388. PVOID Buffer;
  1389. UINTN BytesComplete;
  1390. ULONG CopySize;
  1391. ULONGLONG CurrentTime;
  1392. ULONGLONG EndTime;
  1393. ULONG Flags;
  1394. PNETLINK_GENERIC_SOCKET GenericSocket;
  1395. BOOL LockHeld;
  1396. PNETLINK_GENERIC_RECEIVED_PACKET Packet;
  1397. PLIST_ENTRY PacketEntry;
  1398. ULONG PacketSize;
  1399. ULONG ReturnedEvents;
  1400. ULONG ReturnSize;
  1401. UINTN Size;
  1402. KSTATUS Status;
  1403. ULONGLONG TimeCounterFrequency;
  1404. ULONG Timeout;
  1405. ULONG WaitTime;
  1406. ASSERT(KeGetRunLevel() == RunLevelLow);
  1407. BytesComplete = 0;
  1408. EndTime = 0;
  1409. LockHeld = FALSE;
  1410. Flags = Parameters->SocketIoFlags;
  1411. Parameters->SocketIoFlags = 0;
  1412. if ((Flags & SOCKET_IO_OUT_OF_BAND) != 0) {
  1413. Status = STATUS_NOT_SUPPORTED;
  1414. goto GenericReceiveEnd;
  1415. }
  1416. //
  1417. // Fail if there's ancillary data.
  1418. //
  1419. if (Parameters->ControlDataSize != 0) {
  1420. Status = STATUS_NOT_SUPPORTED;
  1421. goto GenericReceiveEnd;
  1422. }
  1423. Packet = NULL;
  1424. Size = Parameters->Size;
  1425. TimeCounterFrequency = 0;
  1426. Timeout = Parameters->TimeoutInMilliseconds;
  1427. GenericSocket = (PNETLINK_GENERIC_SOCKET)Socket;
  1428. //
  1429. // Set a timeout timer to give up on. The socket stores the maximum timeout.
  1430. //
  1431. if (Timeout > GenericSocket->ReceiveTimeout) {
  1432. Timeout = GenericSocket->ReceiveTimeout;
  1433. }
  1434. if ((Timeout != 0) && (Timeout != WAIT_TIME_INDEFINITE)) {
  1435. EndTime = KeGetRecentTimeCounter();
  1436. EndTime += KeConvertMicrosecondsToTimeTicks(
  1437. Timeout * MICROSECONDS_PER_MILLISECOND);
  1438. TimeCounterFrequency = HlQueryTimeCounterFrequency();
  1439. }
  1440. //
  1441. // Loop trying to get some data. This loop exits once one packet is read.
  1442. //
  1443. while (TRUE) {
  1444. //
  1445. // Wait for a packet to become available. Start by computing the wait
  1446. // time.
  1447. //
  1448. if (Timeout == 0) {
  1449. WaitTime = 0;
  1450. } else if (Timeout != WAIT_TIME_INDEFINITE) {
  1451. CurrentTime = KeGetRecentTimeCounter();
  1452. WaitTime = (EndTime - CurrentTime) * MILLISECONDS_PER_SECOND /
  1453. TimeCounterFrequency;
  1454. } else {
  1455. WaitTime = WAIT_TIME_INDEFINITE;
  1456. }
  1457. //
  1458. // Wait for something to maybe become available. If the wait fails due
  1459. // to a timeout, interruption, or something else, then fail out.
  1460. // Otherwise when the read event is signalled, there is at least one
  1461. // packet to receive.
  1462. //
  1463. Status = IoWaitForIoObjectState(Socket->KernelSocket.IoState,
  1464. POLL_EVENT_IN,
  1465. TRUE,
  1466. WaitTime,
  1467. &ReturnedEvents);
  1468. if (!KSUCCESS(Status)) {
  1469. goto GenericReceiveEnd;
  1470. }
  1471. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  1472. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  1473. Status = STATUS_NO_NETWORK_CONNECTION;
  1474. } else {
  1475. Status = NET_SOCKET_GET_LAST_ERROR(Socket);
  1476. if (KSUCCESS(Status)) {
  1477. Status = STATUS_DEVICE_IO_ERROR;
  1478. }
  1479. }
  1480. goto GenericReceiveEnd;
  1481. }
  1482. KeAcquireQueuedLock(GenericSocket->ReceiveLock);
  1483. LockHeld = TRUE;
  1484. //
  1485. // If another thread beat this one to the punch, try again.
  1486. //
  1487. if (LIST_EMPTY(&(GenericSocket->ReceivedPacketList)) != FALSE) {
  1488. KeReleaseQueuedLock(GenericSocket->ReceiveLock);
  1489. LockHeld = FALSE;
  1490. continue;
  1491. }
  1492. //
  1493. // This should be the first packet being read.
  1494. //
  1495. ASSERT(BytesComplete == 0);
  1496. PacketEntry = GenericSocket->ReceivedPacketList.Next;
  1497. Packet = LIST_VALUE(PacketEntry,
  1498. NETLINK_GENERIC_RECEIVED_PACKET,
  1499. ListEntry);
  1500. PacketSize = Packet->NetPacket->FooterOffset -
  1501. Packet->NetPacket->DataOffset;
  1502. ReturnSize = PacketSize;
  1503. CopySize = ReturnSize;
  1504. if (CopySize > Size) {
  1505. Parameters->SocketIoFlags |= SOCKET_IO_DATA_TRUNCATED;
  1506. CopySize = Size;
  1507. //
  1508. // The real packet size is only returned to the user on truncation
  1509. // if the truncated flag was supplied to this routine. Default to
  1510. // returning the truncated size.
  1511. //
  1512. if ((Flags & SOCKET_IO_DATA_TRUNCATED) == 0) {
  1513. ReturnSize = CopySize;
  1514. }
  1515. }
  1516. Buffer = Packet->NetPacket->Buffer + Packet->NetPacket->DataOffset;
  1517. Status = MmCopyIoBufferData(IoBuffer,
  1518. Buffer,
  1519. 0,
  1520. CopySize,
  1521. TRUE);
  1522. if (!KSUCCESS(Status)) {
  1523. goto GenericReceiveEnd;
  1524. }
  1525. //
  1526. // Copy the packet address out to the caller if requested.
  1527. //
  1528. if (Parameters->NetworkAddress != NULL) {
  1529. if (FromKernelMode != FALSE) {
  1530. RtlCopyMemory(Parameters->NetworkAddress,
  1531. &(Packet->Address),
  1532. sizeof(NETWORK_ADDRESS));
  1533. } else {
  1534. Status = MmCopyToUserMode(Parameters->NetworkAddress,
  1535. &(Packet->Address),
  1536. sizeof(NETWORK_ADDRESS));
  1537. if (!KSUCCESS(Status)) {
  1538. goto GenericReceiveEnd;
  1539. }
  1540. }
  1541. }
  1542. BytesComplete = ReturnSize;
  1543. //
  1544. // Remove the packet if not peeking.
  1545. //
  1546. if ((Flags & SOCKET_IO_PEEK) == 0) {
  1547. LIST_REMOVE(&(Packet->ListEntry));
  1548. GenericSocket->ReceiveBufferFreeSize += PacketSize;
  1549. //
  1550. // The total receive buffer size may have been decreased. Don't
  1551. // increment the free size above the total.
  1552. //
  1553. if (GenericSocket->ReceiveBufferFreeSize >
  1554. GenericSocket->ReceiveBufferTotalSize) {
  1555. GenericSocket->ReceiveBufferFreeSize =
  1556. GenericSocket->ReceiveBufferTotalSize;
  1557. }
  1558. MmFreePagedPool(Packet);
  1559. //
  1560. // Unsignal the IN event if there are no more packets.
  1561. //
  1562. if (LIST_EMPTY(&(GenericSocket->ReceivedPacketList)) != FALSE) {
  1563. IoSetIoObjectState(Socket->KernelSocket.IoState,
  1564. POLL_EVENT_IN,
  1565. FALSE);
  1566. }
  1567. }
  1568. //
  1569. // Wait-all does not apply to netlink sockets. Break out.
  1570. //
  1571. Status = STATUS_SUCCESS;
  1572. break;
  1573. }
  1574. GenericReceiveEnd:
  1575. if (LockHeld != FALSE) {
  1576. KeReleaseQueuedLock(GenericSocket->ReceiveLock);
  1577. }
  1578. Parameters->Size = BytesComplete;
  1579. return Status;
  1580. }
  1581. KSTATUS
  1582. NetlinkpGenericGetSetInformation (
  1583. PNET_SOCKET Socket,
  1584. SOCKET_INFORMATION_TYPE InformationType,
  1585. UINTN Option,
  1586. PVOID Data,
  1587. PUINTN DataSize,
  1588. BOOL Set
  1589. )
  1590. /*++
  1591. Routine Description:
  1592. This routine gets or sets properties of the given socket.
  1593. Arguments:
  1594. Socket - Supplies a pointer to the socket to get or set information for.
  1595. InformationType - Supplies the socket information type category to which
  1596. specified option belongs.
  1597. Option - Supplies the option to get or set, which is specific to the
  1598. information type. The type of this value is generally
  1599. SOCKET_<information_type>_OPTION.
  1600. Data - Supplies a pointer to the data buffer where the data is either
  1601. returned for a get operation or given for a set operation.
  1602. DataSize - Supplies a pointer that on input constains the size of the data
  1603. buffer. On output, this contains the required size of the data buffer.
  1604. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  1605. a set operation (TRUE).
  1606. Return Value:
  1607. STATUS_SUCCESS on success.
  1608. STATUS_INVALID_PARAMETER if the information type is incorrect.
  1609. STATUS_BUFFER_TOO_SMALL if the data buffer is too small to receive the
  1610. requested option.
  1611. STATUS_NOT_SUPPORTED_BY_PROTOCOL if the socket option is not supported by
  1612. the socket.
  1613. STATUS_NOT_HANDLED if the protocol does not override the default behavior
  1614. for a basic socket option.
  1615. --*/
  1616. {
  1617. ULONG Count;
  1618. PNETLINK_GENERIC_SOCKET_OPTION GenericOption;
  1619. PNETLINK_GENERIC_SOCKET GenericSocket;
  1620. ULONG Index;
  1621. LONGLONG Milliseconds;
  1622. PNET_PACKET_SIZE_INFORMATION SizeInformation;
  1623. ULONG SizeOption;
  1624. PSOCKET_TIME SocketTime;
  1625. SOCKET_TIME SocketTimeBuffer;
  1626. PVOID Source;
  1627. KSTATUS Status;
  1628. GenericSocket = (PNETLINK_GENERIC_SOCKET)Socket;
  1629. if ((InformationType != SocketInformationBasic) &&
  1630. (InformationType != SocketInformationNetlinkGeneric)) {
  1631. Status = STATUS_NOT_SUPPORTED;
  1632. goto GenericGetSetInformationEnd;
  1633. }
  1634. //
  1635. // Search to see if the socket option is supported by the netlink generic
  1636. // protocol.
  1637. //
  1638. Count = sizeof(NetlinkGenericSocketOptions) /
  1639. sizeof(NetlinkGenericSocketOptions[0]);
  1640. for (Index = 0; Index < Count; Index += 1) {
  1641. GenericOption = &(NetlinkGenericSocketOptions[Index]);
  1642. if ((GenericOption->InformationType == InformationType) &&
  1643. (GenericOption->Option == Option)) {
  1644. break;
  1645. }
  1646. }
  1647. if (Index == Count) {
  1648. if (InformationType == SocketInformationBasic) {
  1649. Status = STATUS_NOT_HANDLED;
  1650. } else {
  1651. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  1652. }
  1653. goto GenericGetSetInformationEnd;
  1654. }
  1655. //
  1656. // Handle failure cases common to all options.
  1657. //
  1658. if (Set != FALSE) {
  1659. if (GenericOption->SetAllowed == FALSE) {
  1660. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  1661. goto GenericGetSetInformationEnd;
  1662. }
  1663. if (*DataSize < GenericOption->Size) {
  1664. *DataSize = GenericOption->Size;
  1665. Status = STATUS_BUFFER_TOO_SMALL;
  1666. goto GenericGetSetInformationEnd;
  1667. }
  1668. }
  1669. //
  1670. // There are currently no netlink generic protocol options.
  1671. //
  1672. ASSERT(InformationType != SocketInformationNetlinkGeneric);
  1673. //
  1674. // Parse the basic socket option, getting the information from the generic
  1675. // socket or setting the new state in the generic socket.
  1676. //
  1677. Source = NULL;
  1678. Status = STATUS_SUCCESS;
  1679. switch ((SOCKET_BASIC_OPTION)Option) {
  1680. case SocketBasicOptionSendBufferSize:
  1681. if (Set != FALSE) {
  1682. SizeOption = *((PULONG)Data);
  1683. if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  1684. SizeOption = SOCKET_OPTION_MAX_ULONG;
  1685. }
  1686. SizeInformation = &(Socket->PacketSizeInformation);
  1687. if (SizeOption > NETLINK_GENERIC_MAX_PACKET_SIZE) {
  1688. SizeOption = NETLINK_GENERIC_MAX_PACKET_SIZE;
  1689. } else if (SizeOption < SizeInformation->MaxPacketSize) {
  1690. SizeOption = SizeInformation->MaxPacketSize;
  1691. }
  1692. GenericSocket->MaxPacketSize = SizeOption;
  1693. } else {
  1694. Source = &SizeOption;
  1695. SizeOption = GenericSocket->MaxPacketSize;
  1696. }
  1697. break;
  1698. case SocketBasicOptionSendMinimum:
  1699. ASSERT(Set == FALSE);
  1700. SizeOption = NETLINK_GENERIC_SEND_MINIMUM;
  1701. Source = &SizeOption;
  1702. break;
  1703. case SocketBasicOptionReceiveBufferSize:
  1704. if (Set != FALSE) {
  1705. SizeOption = *((PULONG)Data);
  1706. if (SizeOption < NETLINK_GENERIC_MIN_RECEIVE_BUFFER_SIZE) {
  1707. SizeOption = NETLINK_GENERIC_MIN_RECEIVE_BUFFER_SIZE;
  1708. } else if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  1709. SizeOption = SOCKET_OPTION_MAX_ULONG;
  1710. }
  1711. //
  1712. // Set the receive buffer size and truncate the available free
  1713. // space if necessary. Do not remove any packets that have already
  1714. // been received. This is not meant to be a truncate call.
  1715. //
  1716. KeAcquireQueuedLock(GenericSocket->ReceiveLock);
  1717. GenericSocket->ReceiveBufferTotalSize = SizeOption;
  1718. if (GenericSocket->ReceiveBufferFreeSize > SizeOption) {
  1719. GenericSocket->ReceiveBufferFreeSize = SizeOption;
  1720. }
  1721. KeReleaseQueuedLock(GenericSocket->ReceiveLock);
  1722. } else {
  1723. SizeOption = GenericSocket->ReceiveBufferTotalSize;
  1724. Source = &SizeOption;
  1725. }
  1726. break;
  1727. case SocketBasicOptionReceiveMinimum:
  1728. if (Set != FALSE) {
  1729. SizeOption = *((PULONG)Data);
  1730. if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  1731. SizeOption = SOCKET_OPTION_MAX_ULONG;
  1732. }
  1733. GenericSocket->ReceiveMinimum = SizeOption;
  1734. } else {
  1735. SizeOption = GenericSocket->ReceiveMinimum;
  1736. Source = &SizeOption;
  1737. }
  1738. break;
  1739. case SocketBasicOptionReceiveTimeout:
  1740. if (Set != FALSE) {
  1741. SocketTime = (PSOCKET_TIME)Data;
  1742. if (SocketTime->Seconds < 0) {
  1743. Status = STATUS_DOMAIN_ERROR;
  1744. break;
  1745. }
  1746. Milliseconds = SocketTime->Seconds * MILLISECONDS_PER_SECOND;
  1747. if (Milliseconds < SocketTime->Seconds) {
  1748. Status = STATUS_DOMAIN_ERROR;
  1749. break;
  1750. }
  1751. Milliseconds += SocketTime->Microseconds /
  1752. MICROSECONDS_PER_MILLISECOND;
  1753. if ((Milliseconds < 0) || (Milliseconds > MAX_LONG)) {
  1754. Status = STATUS_DOMAIN_ERROR;
  1755. break;
  1756. }
  1757. GenericSocket->ReceiveTimeout = (ULONG)(LONG)Milliseconds;
  1758. } else {
  1759. Source = &SocketTimeBuffer;
  1760. if (GenericSocket->ReceiveTimeout == WAIT_TIME_INDEFINITE) {
  1761. SocketTimeBuffer.Seconds = 0;
  1762. SocketTimeBuffer.Microseconds = 0;
  1763. } else {
  1764. SocketTimeBuffer.Seconds = GenericSocket->ReceiveTimeout /
  1765. MILLISECONDS_PER_SECOND;
  1766. SocketTimeBuffer.Microseconds = (GenericSocket->ReceiveTimeout %
  1767. MILLISECONDS_PER_SECOND) *
  1768. MICROSECONDS_PER_MILLISECOND;
  1769. }
  1770. }
  1771. break;
  1772. default:
  1773. ASSERT(FALSE);
  1774. Status = STATUS_NOT_HANDLED;
  1775. break;
  1776. }
  1777. if (!KSUCCESS(Status)) {
  1778. goto GenericGetSetInformationEnd;
  1779. }
  1780. //
  1781. // Truncate all copies for get requests down to the required size and only
  1782. // return the required size on set requests.
  1783. //
  1784. if (*DataSize > GenericOption->Size) {
  1785. *DataSize = GenericOption->Size;
  1786. }
  1787. //
  1788. // For get requests, copy the gathered information to the supplied data
  1789. // buffer.
  1790. //
  1791. if (Set == FALSE) {
  1792. ASSERT(Source != NULL);
  1793. RtlCopyMemory(Data, Source, *DataSize);
  1794. //
  1795. // If the copy truncated the data, report that the given buffer was too
  1796. // small. The caller can choose to ignore this if the truncated data is
  1797. // enough.
  1798. //
  1799. if (*DataSize < GenericOption->Size) {
  1800. *DataSize = GenericOption->Size;
  1801. Status = STATUS_BUFFER_TOO_SMALL;
  1802. goto GenericGetSetInformationEnd;
  1803. }
  1804. }
  1805. GenericGetSetInformationEnd:
  1806. return Status;
  1807. }
  1808. KSTATUS
  1809. NetlinkpGenericUserControl (
  1810. PNET_SOCKET Socket,
  1811. ULONG CodeNumber,
  1812. BOOL FromKernelMode,
  1813. PVOID ContextBuffer,
  1814. UINTN ContextBufferSize
  1815. )
  1816. /*++
  1817. Routine Description:
  1818. This routine handles user control requests destined for a socket.
  1819. Arguments:
  1820. Socket - Supplies a pointer to the socket.
  1821. CodeNumber - Supplies the minor code of the request.
  1822. FromKernelMode - Supplies a boolean indicating whether or not this request
  1823. (and the buffer associated with it) originates from user mode (FALSE)
  1824. or kernel mode (TRUE).
  1825. ContextBuffer - Supplies a pointer to the context buffer allocated by the
  1826. caller for the request.
  1827. ContextBufferSize - Supplies the size of the supplied context buffer.
  1828. Return Value:
  1829. Status code.
  1830. --*/
  1831. {
  1832. return STATUS_NOT_SUPPORTED;
  1833. }
  1834. KSTATUS
  1835. NetlinkpGenericJoinMulticastGroup (
  1836. PNET_SOCKET Socket,
  1837. ULONG GroupId
  1838. )
  1839. /*++
  1840. Routine Description:
  1841. This routine attempts to join the given multicast group by validating the
  1842. group ID for the protocol and then joining the multicast group.
  1843. Arguments:
  1844. Socket - Supplies a pointer to the network socket requesting to join a
  1845. multicast group.
  1846. GroupId - Supplies the ID of the multicast group to join.
  1847. Return Value:
  1848. Status code.
  1849. --*/
  1850. {
  1851. KSTATUS Status;
  1852. //
  1853. // With the family lock held to prevent family's from unregistering,
  1854. // validate the multicast group and then attempt to join it. This must be
  1855. // done with the lock held or else a family could leave after validation
  1856. // and then the socket would miss being removed from the multicast group it
  1857. // is about to join.
  1858. //
  1859. KeAcquireSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  1860. Status = NetlinkpGenericValidateMulticastGroup(GroupId, TRUE);
  1861. if (!KSUCCESS(Status)) {
  1862. goto JoinMulticastGroupEnd;
  1863. }
  1864. Status = NetlinkJoinMulticastGroup(Socket, GroupId);
  1865. if (!KSUCCESS(Status)) {
  1866. goto JoinMulticastGroupEnd;
  1867. }
  1868. JoinMulticastGroupEnd:
  1869. KeReleaseSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  1870. return Status;
  1871. }
  1872. PNETLINK_GENERIC_FAMILY
  1873. NetlinkpGenericLookupFamilyById (
  1874. ULONG FamilyId
  1875. )
  1876. /*++
  1877. Routine Description:
  1878. This routine searches the database of registered generic netlink families
  1879. for one with the given ID. If successful, the family is returned with an
  1880. added reference which the caller must release.
  1881. Arguments:
  1882. FamilyId - Supplies the ID of the desired family.
  1883. Return Value:
  1884. Returns a pointer to the generic netlink family on success or NULL on
  1885. failure.
  1886. --*/
  1887. {
  1888. PNETLINK_GENERIC_FAMILY FoundFamily;
  1889. PRED_BLACK_TREE_NODE FoundNode;
  1890. NETLINK_GENERIC_FAMILY SearchFamily;
  1891. FoundFamily = NULL;
  1892. SearchFamily.Properties.Id = FamilyId;
  1893. KeAcquireSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  1894. FoundNode = RtlRedBlackTreeSearch(&NetlinkGenericFamilyTree,
  1895. &(SearchFamily.TreeNode));
  1896. if (FoundNode != NULL) {
  1897. FoundFamily = RED_BLACK_TREE_VALUE(FoundNode,
  1898. NETLINK_GENERIC_FAMILY,
  1899. TreeNode);
  1900. NetlinkpGenericFamilyAddReference(FoundFamily);
  1901. }
  1902. KeReleaseSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  1903. return FoundFamily;
  1904. }
  1905. PNETLINK_GENERIC_FAMILY
  1906. NetlinkpGenericLookupFamilyByName (
  1907. PSTR FamilyName
  1908. )
  1909. /*++
  1910. Routine Description:
  1911. This routine searches the database of registered generic netlink families
  1912. for one with the given name. If successful, the family is returned with an
  1913. added reference which the caller must release.
  1914. Arguments:
  1915. FamilyName - Supplies the name of the desired family.
  1916. Return Value:
  1917. Returns a pointer to the generic netlink family on success or NULL on
  1918. failure.
  1919. --*/
  1920. {
  1921. PNETLINK_GENERIC_FAMILY Family;
  1922. PNETLINK_GENERIC_FAMILY FoundFamily;
  1923. BOOL Match;
  1924. PRED_BLACK_TREE_NODE Node;
  1925. FoundFamily = NULL;
  1926. KeAcquireSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  1927. Node = RtlRedBlackTreeGetLowestNode(&NetlinkGenericFamilyTree);
  1928. while (Node != NULL) {
  1929. Family = RED_BLACK_TREE_VALUE(Node, NETLINK_GENERIC_FAMILY, TreeNode);
  1930. Match = RtlAreStringsEqual(Family->Properties.Name,
  1931. FamilyName,
  1932. NETLINK_GENERIC_MAX_FAMILY_NAME_LENGTH);
  1933. if (Match != FALSE) {
  1934. FoundFamily = Family;
  1935. NetlinkpGenericFamilyAddReference(FoundFamily);
  1936. break;
  1937. }
  1938. Node = RtlRedBlackTreeGetNextNode(&NetlinkGenericFamilyTree,
  1939. FALSE,
  1940. Node);
  1941. }
  1942. KeReleaseSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  1943. return FoundFamily;
  1944. }
  1945. VOID
  1946. NetlinkpGenericFamilyAddReference (
  1947. PNETLINK_GENERIC_FAMILY Family
  1948. )
  1949. /*++
  1950. Routine Description:
  1951. This routine increments the reference count of a generic netlink family.
  1952. Arguments:
  1953. Family - Supplies a pointer to a generic netlink family.
  1954. Return Value:
  1955. None.
  1956. --*/
  1957. {
  1958. ULONG OldReferenceCount;
  1959. OldReferenceCount = RtlAtomicAdd32(&(Family->ReferenceCount), 1);
  1960. ASSERT((OldReferenceCount != 0) && (OldReferenceCount < 0x10000000));
  1961. return;
  1962. }
  1963. VOID
  1964. NetlinkpGenericFamilyReleaseReference (
  1965. PNETLINK_GENERIC_FAMILY Family
  1966. )
  1967. /*++
  1968. Routine Description:
  1969. This routine decrements the reference count of a generic netlink family,
  1970. releasing all of its resources if the reference count drops to zero.
  1971. Arguments:
  1972. Family - Supplies a pointer to a generic netlink family.
  1973. Return Value:
  1974. None.
  1975. --*/
  1976. {
  1977. ULONG OldReferenceCount;
  1978. OldReferenceCount = RtlAtomicAdd32(&(Family->ReferenceCount), -1);
  1979. ASSERT((OldReferenceCount != 0) && (OldReferenceCount < 0x10000000));
  1980. if (OldReferenceCount == 1) {
  1981. NetlinkpGenericDestroyFamily(Family);
  1982. }
  1983. return;
  1984. }
  1985. //
  1986. // --------------------------------------------------------- Internal Functions
  1987. //
  1988. VOID
  1989. NetlinkpGenericInsertReceivedPacket (
  1990. PNETLINK_GENERIC_SOCKET Socket,
  1991. PNETLINK_GENERIC_RECEIVED_PACKET Packet
  1992. )
  1993. /*++
  1994. Routine Description:
  1995. This routine attempts to insert the given packet into the socket's list of
  1996. received packets.
  1997. Arguments:
  1998. Socket - Supplies a pointer to the generic netlink socket that received the
  1999. packet.
  2000. Packet - Supplies a pointer to the generic netlink packet that was received.
  2001. Return Value:
  2002. None.
  2003. --*/
  2004. {
  2005. ULONG PacketLength;
  2006. PacketLength = Packet->NetPacket->FooterOffset -
  2007. Packet->NetPacket->DataOffset;
  2008. KeAcquireQueuedLock(Socket->ReceiveLock);
  2009. if (PacketLength <= Socket->ReceiveBufferFreeSize) {
  2010. INSERT_BEFORE(&(Packet->ListEntry),
  2011. &(Socket->ReceivedPacketList));
  2012. Socket->ReceiveBufferFreeSize -= PacketLength;
  2013. ASSERT(Socket->ReceiveBufferFreeSize <
  2014. Socket->ReceiveBufferTotalSize);
  2015. //
  2016. // One packet is always enough to notify a waiting receiver.
  2017. //
  2018. IoSetIoObjectState(Socket->NetlinkSocket.NetSocket.KernelSocket.IoState,
  2019. POLL_EVENT_IN,
  2020. TRUE);
  2021. Packet = NULL;
  2022. } else {
  2023. Socket->DroppedPacketCount += 1;
  2024. }
  2025. KeReleaseQueuedLock(Socket->ReceiveLock);
  2026. //
  2027. // If the packet wasn't nulled out, that's an indication it wasn't added to
  2028. // the list, so free it up.
  2029. //
  2030. if (Packet != NULL) {
  2031. NetFreeBuffer(Packet->NetPacket);
  2032. MmFreePagedPool(Packet);
  2033. }
  2034. return;
  2035. }
  2036. KSTATUS
  2037. NetlinkpGenericProcessReceivedKernelData (
  2038. PNET_LINK Link,
  2039. PNET_SOCKET Socket,
  2040. PNET_PACKET_BUFFER Packet,
  2041. PNETWORK_ADDRESS SourceAddress,
  2042. PNETWORK_ADDRESS DestinationAddress
  2043. )
  2044. /*++
  2045. Routine Description:
  2046. This routine is called to process a packet received by a kernel socket.
  2047. Arguments:
  2048. Link - Supplies a pointer to the link that received the packet.
  2049. Socket - Supplies a pointer to the network socket that received the packet.
  2050. Packet - Supplies a pointer to a structure describing the incoming packet.
  2051. This structure may not be used as a scratch space and must not be
  2052. modified by this routine.
  2053. SourceAddress - Supplies a pointer to the source (remote) address that the
  2054. packet originated from. This memory will not be referenced once the
  2055. function returns, it can be stack allocated.
  2056. DestinationAddress - Supplies a pointer to the destination (local) address
  2057. that the packet is heading to. This memory will not be referenced once
  2058. the function returns, it can be stack allocated.
  2059. Return Value:
  2060. Status code.
  2061. --*/
  2062. {
  2063. PNETLINK_GENERIC_COMMAND Command;
  2064. NETLINK_GENERIC_COMMAND_INFORMATION CommandInformation;
  2065. PNETLINK_GENERIC_FAMILY Family;
  2066. BOOL FoundCommand;
  2067. PNETLINK_GENERIC_HEADER GenericHeader;
  2068. PNETLINK_HEADER Header;
  2069. ULONG Index;
  2070. NET_PACKET_BUFFER LocalPacket;
  2071. ULONG PacketLength;
  2072. USHORT RequiredFlags;
  2073. KSTATUS Status;
  2074. Family = NULL;
  2075. //
  2076. // Make a local copy of the network packet buffer so that the offsets can
  2077. // be modified. The original is not allowed to be modified.
  2078. //
  2079. RtlCopyMemory(&LocalPacket, Packet, sizeof(NET_PACKET_BUFFER));
  2080. PacketLength = LocalPacket.FooterOffset - LocalPacket.DataOffset;
  2081. Header = LocalPacket.Buffer + LocalPacket.DataOffset;
  2082. ASSERT(PacketLength >= NETLINK_HEADER_LENGTH);
  2083. ASSERT((Header->Flags & NETLINK_HEADER_FLAG_REQUEST) != 0);
  2084. ASSERT(Header->Type >= NETLINK_MESSAGE_TYPE_PROTOCOL_MINIMUM);
  2085. ASSERT(Header->Length <= PacketLength);
  2086. LocalPacket.DataOffset += NETLINK_HEADER_LENGTH;
  2087. PacketLength -= NETLINK_HEADER_LENGTH;
  2088. //
  2089. // The generic header must be present.
  2090. //
  2091. GenericHeader = NETLINK_DATA(Header);
  2092. if (PacketLength < NETLINK_GENERIC_HEADER_LENGTH) {
  2093. RtlDebugPrint("NETLINK: packet does not have space for generic "
  2094. "header. %d expected, has %d.\n",
  2095. NETLINK_GENERIC_HEADER_LENGTH,
  2096. PacketLength);
  2097. Status = STATUS_BUFFER_TOO_SMALL;
  2098. goto ProcessReceivedKernelDataEnd;
  2099. }
  2100. LocalPacket.DataOffset += NETLINK_GENERIC_HEADER_LENGTH;
  2101. PacketLength -= NETLINK_GENERIC_HEADER_LENGTH;
  2102. //
  2103. // Find the generic netlink family and call the command's callback.
  2104. //
  2105. Family = NetlinkpGenericLookupFamilyById(Header->Type);
  2106. if (Family == NULL) {
  2107. Status = STATUS_NOT_SUPPORTED;
  2108. goto ProcessReceivedKernelDataEnd;
  2109. }
  2110. FoundCommand = FALSE;
  2111. for (Index = 0; Index < Family->Properties.CommandCount; Index += 1) {
  2112. Command = &(Family->Properties.Commands[Index]);
  2113. if (Command->CommandId == GenericHeader->Command) {
  2114. FoundCommand = TRUE;
  2115. break;
  2116. }
  2117. }
  2118. if (FoundCommand == FALSE) {
  2119. Status = STATUS_NOT_SUPPORTED;
  2120. goto ProcessReceivedKernelDataEnd;
  2121. }
  2122. RequiredFlags = Command->RequiredFlags;
  2123. if ((Header->Flags & RequiredFlags) != RequiredFlags) {
  2124. Status = STATUS_NOT_SUPPORTED;
  2125. goto ProcessReceivedKernelDataEnd;
  2126. }
  2127. CommandInformation.Message.SourceAddress = SourceAddress;
  2128. CommandInformation.Message.DestinationAddress = DestinationAddress;
  2129. CommandInformation.Message.SequenceNumber = Header->SequenceNumber;
  2130. CommandInformation.Message.Type = Header->Type;
  2131. CommandInformation.Command = GenericHeader->Command;
  2132. CommandInformation.Version = GenericHeader->Version;
  2133. Status = Command->ProcessCommand(Socket, &LocalPacket, &CommandInformation);
  2134. if (!KSUCCESS(Status)) {
  2135. goto ProcessReceivedKernelDataEnd;
  2136. }
  2137. ProcessReceivedKernelDataEnd:
  2138. if (Family != NULL) {
  2139. NetlinkpGenericFamilyReleaseReference(Family);
  2140. }
  2141. return Status;
  2142. }
  2143. COMPARISON_RESULT
  2144. NetlinkpGenericCompareFamilies (
  2145. PRED_BLACK_TREE Tree,
  2146. PRED_BLACK_TREE_NODE FirstNode,
  2147. PRED_BLACK_TREE_NODE SecondNode
  2148. )
  2149. /*++
  2150. Routine Description:
  2151. This routine compares two netlink generic family Red-Black tree nodes.
  2152. Arguments:
  2153. Tree - Supplies a pointer to the Red-Black tree that owns both nodes.
  2154. FirstNode - Supplies a pointer to the left side of the comparison.
  2155. SecondNode - Supplies a pointer to the second side of the comparison.
  2156. Return Value:
  2157. Same if the two nodes have the same value.
  2158. Ascending if the first node is less than the second node.
  2159. Descending if the second node is less than the first node.
  2160. --*/
  2161. {
  2162. PNETLINK_GENERIC_FAMILY FirstFamily;
  2163. PNETLINK_GENERIC_FAMILY SecondFamily;
  2164. FirstFamily = RED_BLACK_TREE_VALUE(FirstNode,
  2165. NETLINK_GENERIC_FAMILY,
  2166. TreeNode);
  2167. SecondFamily = RED_BLACK_TREE_VALUE(SecondNode,
  2168. NETLINK_GENERIC_FAMILY,
  2169. TreeNode);
  2170. if (FirstFamily->Properties.Id < SecondFamily->Properties.Id) {
  2171. return ComparisonResultAscending;
  2172. }
  2173. if (FirstFamily->Properties.Id > SecondFamily->Properties.Id) {
  2174. return ComparisonResultDescending;
  2175. }
  2176. return ComparisonResultSame;
  2177. }
  2178. VOID
  2179. NetlinkpGenericDestroyFamily (
  2180. PNETLINK_GENERIC_FAMILY Family
  2181. )
  2182. /*++
  2183. Routine Description:
  2184. This routine destroys a generic netlink family and all of its resources. It
  2185. should already be unregistered and removed from the global tree.
  2186. Arguments:
  2187. Family - Supplies a pointer to a generic netlink family.
  2188. Return Value:
  2189. None.
  2190. --*/
  2191. {
  2192. MmFreePagedPool(Family);
  2193. return;
  2194. }
  2195. KSTATUS
  2196. NetlinkpGenericAllocateFamilyId (
  2197. PULONG FamilyId
  2198. )
  2199. /*++
  2200. Routine Description:
  2201. This routine attempts to allocate a free generic netlink family ID. It
  2202. assumes the netlink generic family lock is held exclusively.
  2203. Arguments:
  2204. FamilyId - Supplies a pointer that receives the newly allocated ID.
  2205. Return Value:
  2206. Status code.
  2207. --*/
  2208. {
  2209. PRED_BLACK_TREE_NODE FoundNode;
  2210. ULONG NextId;
  2211. NETLINK_GENERIC_FAMILY SearchFamily;
  2212. KSTATUS Status;
  2213. ASSERT(KeIsSharedExclusiveLockHeldExclusive(NetlinkGenericFamilyLock));
  2214. Status = STATUS_INSUFFICIENT_RESOURCES;
  2215. NextId = NetlinkGenericFamilyNextId;
  2216. //
  2217. // Iterate until all the possible message types have been tried.
  2218. //
  2219. do {
  2220. SearchFamily.Properties.Id = NextId;
  2221. NextId += 1;
  2222. if (NextId < NETLINK_MESSAGE_TYPE_PROTOCOL_MINIMUM) {
  2223. NextId = NETLINK_MESSAGE_TYPE_PROTOCOL_MINIMUM;
  2224. }
  2225. FoundNode = RtlRedBlackTreeSearch(&NetlinkGenericFamilyTree,
  2226. &(SearchFamily.TreeNode));
  2227. if (FoundNode == NULL) {
  2228. *FamilyId = SearchFamily.Properties.Id;
  2229. Status = STATUS_SUCCESS;
  2230. break;
  2231. }
  2232. } while (NextId != NetlinkGenericFamilyNextId);
  2233. //
  2234. // Update the global to make the next search start where this left off.
  2235. //
  2236. NetlinkGenericFamilyNextId = NextId;
  2237. return Status;
  2238. }
  2239. KSTATUS
  2240. NetlinkpGenericAllocateMulticastGroups (
  2241. PNETLINK_GENERIC_FAMILY Family
  2242. )
  2243. /*++
  2244. Routine Description:
  2245. This routine allocates a region of the multicast group ID namespace for the
  2246. given family. It assumes the netlink generic family lock is held
  2247. exclusively.
  2248. Arguments:
  2249. Family - Supplies a pointer to the netlink generic family in need of
  2250. multicast group allocation.
  2251. Return Value:
  2252. Status code.
  2253. --*/
  2254. {
  2255. ULONG BitmapIndex;
  2256. ULONG Count;
  2257. PNETLINK_GENERIC_MULTICAST_GROUP Group;
  2258. ULONG Index;
  2259. ULONG Mask;
  2260. PULONG NewBitmap;
  2261. ULONG NewBitmapSize;
  2262. ULONG NewGroups;
  2263. ULONG Offset;
  2264. ULONG Run;
  2265. KSTATUS Status;
  2266. ULONG Value;
  2267. ASSERT(KeIsSharedExclusiveLockHeldExclusive(NetlinkGenericFamilyLock));
  2268. Count = Family->Properties.MulticastGroupCount;
  2269. //
  2270. // Search through the existing bitmap for a run that can accomodate the
  2271. // new multicast groups.
  2272. //
  2273. Offset = 0;
  2274. Run = 0;
  2275. for (BitmapIndex = 0;
  2276. BitmapIndex < (NetlinkGenericMulticastBitmapSize / sizeof(ULONG));
  2277. BitmapIndex += 1) {
  2278. Value = NetlinkGenericMulticastBitmap[BitmapIndex];
  2279. for (Index = 0; Index < (sizeof(ULONG) * BITS_PER_BYTE); Index += 1) {
  2280. if ((Value & 0x1) != 0) {
  2281. Offset += Run + 1;
  2282. Run = 0;
  2283. } else {
  2284. Run += 1;
  2285. if (Run == Count) {
  2286. break;
  2287. }
  2288. }
  2289. Value >>= 1;
  2290. }
  2291. if (Run == Count) {
  2292. break;
  2293. }
  2294. //
  2295. // A multicast group ID of 0 should never be assigned.
  2296. //
  2297. ASSERT(Offset != 0);
  2298. }
  2299. //
  2300. // If there is not enough space, allocate a bigger array. If the run
  2301. // is not zero, that means that there was some space at the end of the
  2302. // last ULONG of the bitmap. Account for that when added more ULONGs.
  2303. //
  2304. if (Run != Count) {
  2305. NewGroups = Count - Run;
  2306. //
  2307. // Avoid allocating group ID 0. It is invalid.
  2308. //
  2309. if (Offset == 0) {
  2310. NewGroups += 1;
  2311. Offset = 1;
  2312. }
  2313. NewGroups = ALIGN_RANGE_UP(NewGroups, sizeof(ULONG) * BITS_PER_BYTE);
  2314. NewBitmapSize = NetlinkGenericMulticastBitmapSize +
  2315. (NewGroups / BITS_PER_BYTE);
  2316. NewBitmap = MmAllocatePagedPool(NewBitmapSize,
  2317. NETLINK_GENERIC_ALLOCATION_TAG);
  2318. if (NewBitmap == NULL) {
  2319. Status = STATUS_INSUFFICIENT_RESOURCES;
  2320. goto AllocateMulticastGroupOffsetEnd;
  2321. }
  2322. RtlZeroMemory((PVOID)NewBitmap + NetlinkGenericMulticastBitmapSize,
  2323. (NewGroups / BITS_PER_BYTE));
  2324. //
  2325. // If there is an existing bitmap, copy it to the new bitmap and
  2326. // then release it.
  2327. //
  2328. if (NetlinkGenericMulticastBitmap != NULL) {
  2329. RtlCopyMemory(NewBitmap,
  2330. NetlinkGenericMulticastBitmap,
  2331. NetlinkGenericMulticastBitmapSize);
  2332. MmFreePagedPool(NetlinkGenericMulticastBitmap);
  2333. //
  2334. // Otherwise, this is the first allocation. Reserve group ID 0.
  2335. //
  2336. } else {
  2337. Index = NETLINK_SOCKET_BITMAP_INDEX(0);
  2338. Mask = NETLINK_SOCKET_BITMAP_MASK(0);
  2339. NewBitmap[Index] |= Mask;
  2340. }
  2341. NetlinkGenericMulticastBitmap = NewBitmap;
  2342. NetlinkGenericMulticastBitmapSize = NewBitmapSize;
  2343. }
  2344. //
  2345. // Set the newly allocated groups as reserved in the bitmap.
  2346. //
  2347. for (Index = 0; Index < Count; Index += 1) {
  2348. Group = &(Family->Properties.MulticastGroups[Index]);
  2349. Group->Id += Offset;
  2350. BitmapIndex = NETLINK_SOCKET_BITMAP_INDEX(Group->Id);
  2351. Mask = NETLINK_SOCKET_BITMAP_MASK(Group->Id);
  2352. NetlinkGenericMulticastBitmap[BitmapIndex] |= Mask;
  2353. }
  2354. Family->MulticastGroupOffset = Offset;
  2355. Status = STATUS_SUCCESS;
  2356. AllocateMulticastGroupOffsetEnd:
  2357. return Status;
  2358. }
  2359. VOID
  2360. NetlinkpGenericFreeMulticastGroups (
  2361. PNETLINK_GENERIC_FAMILY Family
  2362. )
  2363. /*++
  2364. Routine Description:
  2365. This routine releases the region of multicast group IDs allocated for the
  2366. given netlink generic family. It assumes the netlink generic family lock is
  2367. held exclusively.
  2368. Arguments:
  2369. Family - Supplies a pointer to the netlink generic family whose multicast
  2370. groups should be released.
  2371. Return Value:
  2372. None.
  2373. --*/
  2374. {
  2375. ULONG BitmapIndex;
  2376. UCHAR Command;
  2377. ULONG Count;
  2378. PNETLINK_GENERIC_MULTICAST_GROUP Group;
  2379. ULONG Index;
  2380. ULONG Mask;
  2381. ULONG Offset;
  2382. ULONG Protocol;
  2383. ASSERT(KeIsSharedExclusiveLockHeldExclusive(NetlinkGenericFamilyLock));
  2384. Count = Family->Properties.MulticastGroupCount;
  2385. Offset = Family->MulticastGroupOffset;
  2386. //
  2387. // Remove all sockets from these multicast groups.
  2388. //
  2389. Protocol = SOCKET_INTERNET_PROTOCOL_NETLINK_GENERIC;
  2390. NetlinkRemoveSocketsFromMulticastGroups(Protocol, Offset, Count);
  2391. //
  2392. // Free the groups from the generic netlink bitmap.
  2393. //
  2394. for (Index = 0; Index < Count; Index += 1) {
  2395. Group = &(Family->Properties.MulticastGroups[Index]);
  2396. BitmapIndex = NETLINK_SOCKET_BITMAP_INDEX(Group->Id);
  2397. Mask = NETLINK_SOCKET_BITMAP_MASK(Group->Id);
  2398. NetlinkGenericMulticastBitmap[BitmapIndex] &= ~Mask;
  2399. //
  2400. // Announce the deletion of the multicast group.
  2401. //
  2402. Command = NETLINK_CONTROL_COMMAND_DELETE_MULTICAST_GROUP;
  2403. NetlinkpGenericControlSendNotification(Family, Command, Group);
  2404. }
  2405. return;
  2406. }
  2407. KSTATUS
  2408. NetlinkpGenericValidateMulticastGroup (
  2409. ULONG GroupId,
  2410. BOOL LockHeld
  2411. )
  2412. /*++
  2413. Routine Description:
  2414. This routine validates that the group ID is valid for the netlink generic
  2415. families.
  2416. Arguments:
  2417. GroupId - Supplies the group ID that is to be validated.
  2418. LockHeld - Supplies a boolean indicating whether or not the global generic
  2419. family lock is held.
  2420. Return Value:
  2421. Status code.
  2422. --*/
  2423. {
  2424. ULONG Index;
  2425. ULONG Mask;
  2426. KSTATUS Status;
  2427. ASSERT(GroupId != 0);
  2428. if (LockHeld == FALSE) {
  2429. KeAcquireSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  2430. }
  2431. Index = NETLINK_SOCKET_BITMAP_INDEX(GroupId);
  2432. Mask = NETLINK_SOCKET_BITMAP_MASK(GroupId);
  2433. if ((Index >= (NetlinkGenericMulticastBitmapSize / sizeof(ULONG))) ||
  2434. ((NetlinkGenericMulticastBitmap[Index] & Mask) == 0)) {
  2435. Status = STATUS_INVALID_PARAMETER;
  2436. } else {
  2437. Status = STATUS_SUCCESS;
  2438. }
  2439. if (LockHeld == FALSE) {
  2440. KeReleaseSharedExclusiveLockShared(NetlinkGenericFamilyLock);
  2441. }
  2442. return Status;
  2443. }