IPX16A.ASM 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. .8086
  19. .model large
  20. option segment:USE16
  21. option readonly
  22. option oldstructs
  23. assume ds:@data
  24. assume es:nothing
  25. RECEIVE_BUFFER_LENGTH =1024
  26. MAX_RECEIVE_BUFFERS =32
  27. externdef GLOBALDOSALLOC:far
  28. externdef GLOBALDOSFREE:far
  29. .data
  30. IPXCallOffset dw 0
  31. IPXCallSegment dw 0
  32. RealSegment dw 0
  33. PseudoES dw 0
  34. RegisterDump db 32h dup (0)
  35. MyNetworkNumber db 4 dup (?)
  36. MyNodeAddress db 6 dup (?)
  37. MySocket dw ?
  38. ReceiveBufferSegment dw ?
  39. ReceiveBufferSelector dw ?
  40. ReceiveECBOffset dw ?
  41. CurrentReceiveBuffer dw ?
  42. LastPassedReceiveBuffer dw ?
  43. RealModeCallbackSegment dw ?
  44. RealModeCallbackOffset dw ?
  45. CallbackRegisterDump db 32h dup (0)
  46. Listening db ?
  47. NoReenter db 0
  48. IPXHold db 0
  49. OFFS =0
  50. SEGM =2
  51. ;---------------------------------------------------------------------------
  52. ;These defines are for the IPX functions. The function number is specified
  53. ;by placing it in BX when IPX is called. There are two ways to invoke IPX:
  54. ;use interrupt 0x7a, or use a function whose address is obtained by calling
  55. ;interrupt 0x2f with AX=0x7a00; the function address is returned in ES:DI.
  56. ;This is the preferred method, since other apps are known to use int 0x7a.
  57. ;---------------------------------------------------------------------------
  58. IPX_OPEN_SOCKET = 0000h
  59. IPX_CLOSE_SOCKET = 0001h
  60. IPX_GET_LOCAL_TARGET = 0002h
  61. IPX_SEND_PACKET = 0003h
  62. IPX_LISTEN_FOR_PACKET = 0004h
  63. IPX_SCHEDULE_EVENT = 0005h
  64. IPX_CANCEL_EVENT = 0006h
  65. IPX_GET_INTERVAL_MARKER = 0008h
  66. IPX_GET_INTERNETWORK_ADDRESS = 0009h
  67. IPX_RELINQUISH_CONTROL = 000Ah
  68. IPX_DISCONNECT_FROM_TARGET = 000Bh
  69. ;/*---------------------------------------------------------------------------
  70. ;These defines are for various IPX error codes:
  71. ;---------------------------------------------------------------------------*/
  72. IPXERR_CONNECTION_SEVERED = 00ech
  73. IPXERR_CONNECTION_FAILED = 00edh
  74. IPXERR_NO_CONNECTION = 00eeh
  75. IPXERR_CONNECTION_TABLE_FULL = 00efh
  76. IPXERR_NO_CANCEL_ECB = 00f9h
  77. IPXERR_NO_PATH = 00fah
  78. IPXERR_ECB_INACTIVE = 00fch
  79. IPXERR_INVALID_PACKET_LENGTH = 00fdh
  80. IPXERR_SOCKET_TABLE_FULL = 00feh
  81. IPXERR_SOCKET_ERROR = 00ffh
  82. ;/*---------------------------------------------------------------------------
  83. ;These defines are for various interrupt vectors and DPMI functions:
  84. ;---------------------------------------------------------------------------*/
  85. IPX_INT = 007ah
  86. DPMI_INT = 0031h
  87. DPMI_ALLOC_DOS_MEM = 0100h
  88. DPMI_FREE_DOS_MEM = 0101h
  89. DPMI_CALL_REAL_INT = 0300h
  90. DPMI_CALL_REAL_PROC = 0301h
  91. DPMI_ALLOCATE_CALLBACK = 0303h
  92. DPMI_RELEASE_CALLBACK = 0304h
  93. DPMI_LOCK_MEM = 0600h
  94. DPMI_UNLOCK_MEM = 0601h
  95. request_buffer struct
  96. len word ?
  97. buffer_type byte ?
  98. connect_number byte ?
  99. request_buffer ends
  100. request_local_target_buffer struct
  101. lt_network_number db ?,?,?,?
  102. lt_physical_node db ?,?,?,?,?,?
  103. lt_socket dw ?
  104. request_local_target_buffer ends
  105. local_target_reply_buffer struct
  106. lt_local_target db ?,?,?,?,?,?
  107. local_target_reply_buffer ends
  108. reply_buffer struct
  109. lem word ?
  110. network_number byte ?,?,?,?
  111. physical_node byte ?,?,?,?,?,?
  112. server_socket word ?
  113. reply_buffer ends
  114. userid_buffer struct
  115. struct_len word ?
  116. object_id byte ?,?,?,?
  117. object_type byte ?,?
  118. object_name byte 48 dup(?)
  119. login_time byte 7 dup (?)
  120. reserved word ?
  121. userid_buffer ends
  122. .code
  123. .386
  124. include <pcmacro.16>
  125. externdef pascal _IPX_Initiialise:far16
  126. externdef pascal _IPX_Uninitialise:far16
  127. _IPX_Initialise proc far pascal
  128. push ebx
  129. push ecx
  130. push edx
  131. push esi
  132. push edi
  133. push ebp
  134. push ds
  135. push es
  136. push fs
  137. push gs
  138. mov ax,7a00h
  139. int 2fh
  140. and eax,0ffh
  141. cmp al,-1
  142. setz al
  143. test al,al
  144. jz @f
  145. mov bx,@data
  146. mov ds,bx
  147. mov [IPXCallSegment],es
  148. mov [IPXCallOffset],di
  149. @@: pop gs
  150. pop fs
  151. pop es
  152. pop ds
  153. pop ebp
  154. pop edi
  155. pop esi
  156. pop edx
  157. pop ecx
  158. pop ebx
  159. ret
  160. _IPX_Initialise endp
  161. _IPX_Open_Socket95 proc far pascal uses bx cx dx si di ds es fs gs,
  162. socket:word
  163. mov bx,@data
  164. mov ds,bx
  165. mov bx,IPX_OPEN_SOCKET ;open socket
  166. mov_w dx,[socket] ;socket number
  167. mov_w [MySocket],dx ;save it for later
  168. mov ax,0ffh ;long lived
  169. call Call_IPX
  170. ret
  171. _IPX_Open_Socket95 endp
  172. _IPX_Close_Socket95 proc far pascal uses ax bx cx dx si di ds es fs gs,
  173. socket:word
  174. mov bx,1
  175. mov_w dx,[socket]
  176. call Call_IPX
  177. ret
  178. _IPX_Close_Socket95 endp
  179. _IPX_Uninitialise proc far pascal
  180. int 3
  181. ret
  182. _IPX_Uninitialise endp
  183. _IPX_Get_Connection_Number95 proc far pascal uses bx cx dx si di ds es fs gs
  184. mov ax,0dc00h
  185. call Call_DOS
  186. and eax,255
  187. ret
  188. _IPX_Get_Connection_Number95 endp
  189. _IPX_Get_Internet_Address95 proc far pascal uses bx cx dx si di ds es fs gs,
  190. connection_number :dword,
  191. network_number_off :word,
  192. network_number_seg :word,
  193. physical_node_off :word,
  194. physical_node_seg :word
  195. local selector:word
  196. local segmento:word
  197. ret
  198. ifdef cuts ;(unfinished)
  199. ;
  200. ; Allocate DOS memory for buffers passed to interrupt
  201. ;
  202. int 3
  203. xor ax,ax
  204. mov bx,(sizeof reply_buffer + sizeof request_buffer + 15)
  205. save bp
  206. push ax
  207. push bx
  208. call GLOBALDOSALLOC
  209. restore bp
  210. test ax,ax
  211. jz @@dpmi_error
  212. mov [segmento],dx
  213. mov [selector],ax
  214. mov fs,dx
  215. xor di,di
  216. mov_w fs:[di.len],2
  217. mov_b fs:[di.buffer_type],13h
  218. mov_b al,[connection_number]
  219. mov_b fs:[di.connect_number],al
  220. mov di,sizeof request_buffer
  221. mov fs:[di.len],12
  222. mov ax,0e300h
  223. mov ds,[segmento]
  224. mov es,[segmento]
  225. xor si,si
  226. pusha
  227. call Call_DOS
  228. popa
  229. les di,dword ptr [network_number_off]
  230. mov ds,[selector]
  231. mov si,sizeof request_buffer + network_number
  232. movsd
  233. les di,dword ptr [physical_node_off]
  234. mov si,sizeof request_buffer + physical_node
  235. movsd
  236. movsw
  237. ;
  238. ; Save it here for posterity (or perhaps later use)
  239. ;
  240. mov di,offset MyNetworkNumber
  241. mov ax,@data
  242. mov es,ax
  243. mov ds,[selector]
  244. mov si,sizeof request_buffer + network_number
  245. movsd
  246. mov di,offset MyNodeAddress
  247. mov si,sizeof request_buffer + physical_node
  248. movsd
  249. movsw
  250. ;
  251. ; Free the DOS memory
  252. ;
  253. mov bx,@data
  254. mov ds,bx
  255. mov es,bx
  256. mov fs,bx
  257. mov gs,bx
  258. mov bx,[selector]
  259. push bx
  260. call GLOBALDOSFREE
  261. xor ax,ax
  262. ret
  263. @@dpmi_error: mov ax,-1
  264. ret
  265. endif
  266. _IPX_Get_Internet_Address95 endp
  267. _IPX_Get_User_ID95 proc far pascal uses bx cx dx si di ds es fs gs,
  268. connection_number:dword,
  269. user_id_off:word,
  270. user_id_seg:word
  271. local segmento:word
  272. local selector:word
  273. int 3
  274. cmp [connection_number],0
  275. jz @@return_error
  276. ;
  277. ; Allocate DOS memory for buffers passed to interrupt
  278. ;
  279. xor ax,ax
  280. mov bx,(sizeof reply_buffer + sizeof request_buffer + 15)
  281. save bp
  282. push ax
  283. push bx
  284. call GLOBALDOSALLOC
  285. restore bp
  286. test ax,ax
  287. jz @@return_error
  288. mov [segmento],dx
  289. mov [selector],ax
  290. mov fs,dx
  291. xor di,di
  292. mov ax,@data
  293. mov ds,ax
  294. mov_w fs:[di.len],2
  295. mov_b fs:[di.buffer_type],16h
  296. mov_b al,[connection_number]
  297. mov_b fs:[di.connect_number],al
  298. mov di,sizeof request_buffer
  299. mov fs:[di.struct_len],sizeof userid_buffer-2
  300. mov ax,0e300h
  301. mov ds,[segmento]
  302. mov es,[segmento]
  303. xor si,si
  304. pusha
  305. call Call_DOS
  306. popa
  307. les di,dword ptr [user_id_off]
  308. mov ds,[selector]
  309. mov si,sizeof request_buffer + object_name
  310. mov cx,48/4
  311. rep movsd
  312. ;
  313. ; Free the DOS memory
  314. ;
  315. mov bx,@data
  316. mov ds,bx
  317. mov es,bx
  318. mov fs,bx
  319. mov gs,bx
  320. mov bx,[selector]
  321. push bx
  322. call GLOBALDOSFREE
  323. xor ax,ax
  324. ret
  325. @@return_error: mov ax,-1
  326. ret
  327. _IPX_Get_User_ID95 endp
  328. ;---------------------------------------------------------------------------
  329. ;This is the IPX Packet structure. It's followed by the data itself, which
  330. ;can be up to 546 bytes long. Annotation of 'IPX' means IPX will set this
  331. ;field; annotation of 'APP' means the application must set the field.
  332. ;NOTE: All header fields are ordered high-byte,low-byte.
  333. ;---------------------------------------------------------------------------*/
  334. IPXHeaderType struct
  335. CheckSum dw ? ; IPX: Not used; always 0xffff
  336. IPXLength dw ? ; IPX: Total size, incl header & data
  337. TransportControl db ? ; IPX: # bridges message crossed
  338. PacketType db ? ; APP: Set to 4 for IPX (5 for SPX)
  339. DestNetworkNumber db ?,?,?,? ; APP: destination Network Number
  340. DestNetworkNode db ?,?,?,?,?,? ; APP: destination Node Address
  341. DestNetworkSocket dw ? ; APP: destination Socket Number
  342. SourceNetworkNumber db ?,?,?,? ; IPX: source Network Number
  343. SourceNetworkNode db ?,?,?,?,?,? ; IPX: source Node Address
  344. SourceNetworkSocket dw ? ; IPX: source Socket Number
  345. IPXHeaderType ends
  346. ;/*---------------------------------------------------------------------------
  347. ;This is the IPX Event Control Block. It serves as a communications area
  348. ;between IPX and the application for a single IPX operation. You should set
  349. ;up a separate ECB for each IPX operation you perform.
  350. ;---------------------------------------------------------------------------*/
  351. ECB struct
  352. Link_Address dd ?
  353. Event_Service_Routine dd ? ; APP: event handler (NULL=none)
  354. InUse db ? ; IPX: 0 = event complete
  355. CompletionCode db ? ; IPX: event's return code
  356. SocketNumber dw ? ; APP: socket to send data through
  357. ConnectionID dw ? ; returned by Listen (???)
  358. RestOfWorkspace dw ?
  359. DriverWorkspace db 12 dup (?)
  360. ImmediateAddress db 6 dup (?) ; returned by Get_Local_Target
  361. PacketCount dw ?
  362. PacketAddress0 dd ?
  363. PacketLength0 dw ?
  364. PacketAddress1 dd ?
  365. PacketLength1 dw ?
  366. ECB ends
  367. SEND_ECB_OFFSET =0
  368. SEND_HEADER_OFFSET =(sizeof ECB +3) AND 0fffch
  369. SEND_BUFFER_OFFSET =(SEND_HEADER_OFFSET + sizeof IPXHeaderType +3) AND 0fffch
  370. _IPX_Send_Packet95 proc far pascal uses ebx ecx edx esi edi ds es fs gs,
  371. send_address :far ptr byte,
  372. send_buffer :far ptr byte,
  373. send_buffer_len :word
  374. local selector :word
  375. local segmento :word
  376. local dos_send_ecb :far ptr ECB
  377. local dos_send_header :far ptr IPXHeaderType
  378. local dos_send_buffer :far ptr byte
  379. local completion_code :word
  380. int 3
  381. ;
  382. ; Allocate required DOS memory
  383. ;
  384. xor ax,ax
  385. mov bx,(sizeof ECB + sizeof IPXHeaderType + 1024 +31)
  386. save bp
  387. push ax
  388. push bx
  389. call GLOBALDOSALLOC
  390. restore bp
  391. test ax,ax
  392. jz @@error
  393. mov [segmento],dx
  394. mov [selector],ax
  395. ;
  396. ; Set up the pointers to the dos memory
  397. ;
  398. mov_w [dos_send_ecb+OFFS],SEND_ECB_OFFSET
  399. mov_w [dos_send_ecb+SEGM],ax
  400. mov_w [dos_send_header+OFFS],SEND_HEADER_OFFSET
  401. mov_w [dos_send_header+SEGM],ax
  402. mov_w [dos_send_buffer+OFFS],SEND_BUFFER_OFFSET
  403. mov_w [dos_send_buffer+SEGM],ax
  404. ;
  405. ; Clear out the send ECB
  406. ;
  407. xor al,al
  408. mov cx,sizeof ECB
  409. les di,[dos_send_ecb]
  410. rep stosb
  411. ;
  412. ; Clear out the send header
  413. ;
  414. mov cx,sizeof IPXHeaderType
  415. les di,[dos_send_header]
  416. rep stosb
  417. ;
  418. ; Copy the data to be sent into the send buffer
  419. ;
  420. mov cx,546
  421. cmp_w cx,[send_buffer_len]
  422. jle @@got_buffer_len
  423. mov_w cx,[send_buffer_len]
  424. @@got_buffer_len:
  425. mov_w [send_buffer_len],546 ;always send same size packets (nice and big for Kali hehe)
  426. les di,[dos_send_buffer]
  427. lds si,[send_buffer]
  428. rep movsb
  429. ;
  430. ; Fill in the ECB
  431. ;
  432. mov ax,@data
  433. mov ds,ax
  434. mov fs,ax ;keep ptr to data seg in fs
  435. les di,[dos_send_ecb]
  436. assume ds:@data
  437. assume fs:@data
  438. mov ax,[MySocket]
  439. mov es:[di.SocketNumber],ax
  440. mov es:[di.PacketCount],2
  441. mov ax,[segmento]
  442. shl eax,16
  443. mov_w ax,[dos_send_header+OFFS]
  444. mov_d es:[di.PacketAddress0],eax
  445. mov_w es:[di.PacketLength0],sizeof IPXHeaderType
  446. mov_w ax,[dos_send_buffer+OFFS]
  447. mov_d es:[di.PacketAddress1],eax
  448. mov_w ax,[send_buffer_len]
  449. mov_w es:[di.PacketLength1],ax
  450. ;assume ds:nothing
  451. ;
  452. ; Fill in the address field
  453. ;
  454. lds si,[send_address]
  455. mov eax,[si]
  456. mov_d es:[di.ImmediateAddress],eax
  457. mov ax,[si+4]
  458. mov_w es:[di.ImmediateAddress+4],ax
  459. ;
  460. ; Fill in the outgoing header
  461. ;
  462. les di,[dos_send_header]
  463. mov es:[di.PacketType],4
  464. push fs:[MySocket]
  465. pop es:[di.DestNetworkSocket]
  466. ;
  467. ; Fill in the nwtowrk number and node address
  468. ;
  469. mov_d eax,fs:[MyNetworkNumber]
  470. mov_d es:[di.DestNetworkNumber],eax
  471. mov_d eax,fs:[MyNodeAddress]
  472. mov_d es:[di.DestNetworkNode],eax
  473. mov_w ax,fs:[MyNodeAddress+4]
  474. mov_w es:[di.DestNetworkNode+4],ax
  475. ;
  476. ; Send that sucker!
  477. ;
  478. mov si,[segmento]
  479. mov fs:[PseudoES],si
  480. mov si,SEND_ECB_OFFSET
  481. mov bx,IPX_SEND_PACKET
  482. pusha
  483. push fs
  484. call Call_IPX
  485. pop fs
  486. popa
  487. mov fs:[PseudoES],0
  488. assume fs:nothing
  489. ;
  490. ; Wait for the send to finish
  491. ;
  492. @@wait_send_loop:
  493. lds si,[dos_send_ecb]
  494. cmp [si.InUse],0
  495. jz @@done
  496. mov bx,IPX_RELINQUISH_CONTROL
  497. save bp
  498. call Call_IPX
  499. restore bp
  500. jmp @@wait_send_loop
  501. ;
  502. ; Get the completion code
  503. ;
  504. @@done: lds si,[dos_send_ecb]
  505. mov al,[si.CompletionCode]
  506. xor ah,ah
  507. mov [completion_code],ax
  508. ;
  509. ; Free the DOS memory
  510. ;
  511. mov bx,@data
  512. mov ds,bx
  513. mov es,bx
  514. mov fs,bx
  515. mov gs,bx
  516. mov bx,[selector]
  517. save bp
  518. push bx
  519. call GLOBALDOSFREE
  520. restore bp
  521. cmp [completion_code],0
  522. jz @@error
  523. @@success: mov ax,1
  524. ret
  525. @@error: xor ax,ax
  526. ret
  527. _IPX_Send_Packet95 endp
  528. _IPX_Broadcast_Packet95 proc far pascal uses ebx ecx edx esi edi ds es fs gs,
  529. send_buffer :far ptr byte,
  530. send_buffer_len :word
  531. local selector :word
  532. local segmento :word
  533. local dos_send_ecb :far ptr ECB
  534. local dos_send_header :far ptr IPXHeaderType
  535. local dos_send_buffer :far ptr byte
  536. local completion_code :word
  537. int 3
  538. ;
  539. ; Allocate required DOS memory
  540. ;
  541. xor ax,ax
  542. mov bx,(sizeof ECB + sizeof IPXHeaderType + 1024 +31)
  543. save bp
  544. push ax
  545. push bx
  546. call GLOBALDOSALLOC
  547. restore bp
  548. test ax,ax
  549. jz @@error
  550. mov [segmento],dx
  551. mov [selector],ax
  552. ;
  553. ; Set up the pointers to the dos memory
  554. ;
  555. mov_w [dos_send_ecb+OFFS],SEND_ECB_OFFSET
  556. mov_w [dos_send_ecb+SEGM],ax
  557. mov_w [dos_send_header+OFFS],SEND_HEADER_OFFSET
  558. mov_w [dos_send_header+SEGM],ax
  559. mov_w [dos_send_buffer+OFFS],SEND_BUFFER_OFFSET
  560. mov_w [dos_send_buffer+SEGM],ax
  561. ;
  562. ; Clear out the send ECB
  563. ;
  564. xor al,al
  565. mov cx,sizeof ECB
  566. les di,[dos_send_ecb]
  567. rep stosb
  568. ;
  569. ; Clear out the send header
  570. ;
  571. mov cx,sizeof IPXHeaderType
  572. les di,[dos_send_header]
  573. rep stosb
  574. ;
  575. ; Copy the data to be sent into the send buffer
  576. ;
  577. mov cx,546
  578. cmp_w cx,[send_buffer_len]
  579. jle @@got_buffer_len
  580. mov_w cx,[send_buffer_len]
  581. @@got_buffer_len:
  582. mov_w [send_buffer_len],546 ;always send same size packets (nice and big for Kali hehe)
  583. les di,[dos_send_buffer]
  584. lds si,[send_buffer]
  585. rep movsb
  586. ;
  587. ; Fill in the ECB
  588. ;
  589. mov ax,@data
  590. mov ds,ax
  591. mov fs,ax ;keep ptr to data seg in fs
  592. les di,[dos_send_ecb]
  593. assume fs:@data
  594. assume ds:@data
  595. mov ax,[MySocket]
  596. mov es:[di.SocketNumber],ax
  597. mov es:[di.PacketCount],2
  598. mov ax,[segmento]
  599. shl eax,16
  600. mov_w ax,[dos_send_header+OFFS]
  601. mov_d es:[di.PacketAddress0],eax
  602. mov_w es:[di.PacketLength0],sizeof IPXHeaderType
  603. mov_w ax,[dos_send_buffer+OFFS]
  604. mov_d es:[di.PacketAddress1],eax
  605. mov_w ax,[send_buffer_len]
  606. mov_w es:[di.PacketLength1],ax
  607. ;assume ds:nothing
  608. ;
  609. ; Fill in the address field
  610. ;
  611. mov_d es:[di.ImmediateAddress],0ffffffffh
  612. mov_w es:[di.ImmediateAddress+4],0ffffh
  613. ;
  614. ; Fill in the outgoing header
  615. ;
  616. les di,[dos_send_header]
  617. mov es:[di.PacketType],4
  618. push fs:[MySocket]
  619. pop es:[di.DestNetworkSocket]
  620. ;
  621. ; Fill in the nwtowrk number and node address
  622. ;
  623. mov_d es:[di.DestNetworkNumber],0ffffffffh
  624. mov_d es:[di.DestNetworkNode],0ffffffffh
  625. mov_w es:[di.DestNetworkNode+4],0ffffh
  626. ;
  627. ; Send that sucker!
  628. ;
  629. mov si,[segmento]
  630. mov fs:[PseudoES],si
  631. mov si,SEND_ECB_OFFSET
  632. mov bx,IPX_SEND_PACKET
  633. pusha
  634. push fs
  635. call Call_IPX
  636. pop fs
  637. popa
  638. mov fs:[PseudoES],0
  639. assume fs:nothing
  640. ;
  641. ; Wait for the send to finish
  642. ;
  643. @@wait_send_loop:
  644. lds si,[dos_send_ecb]
  645. cmp [si.InUse],0
  646. jz @@done
  647. mov bx,IPX_RELINQUISH_CONTROL
  648. save bp
  649. call Call_IPX
  650. restore bp
  651. jmp @@wait_send_loop
  652. ;
  653. ; Get the completion code
  654. ;
  655. @@done: lds si,[dos_send_ecb]
  656. mov al,[si.CompletionCode]
  657. xor ah,ah
  658. mov [completion_code],ax
  659. ;
  660. ; Free the DOS memory
  661. ;
  662. mov bx,@data
  663. mov ds,bx
  664. mov es,bx
  665. mov fs,bx
  666. mov gs,bx
  667. mov bx,[selector]
  668. save bp
  669. push bx
  670. call GLOBALDOSFREE
  671. restore bp
  672. cmp [completion_code],0
  673. jz @@error
  674. @@success: mov ax,1
  675. ret
  676. @@error: xor ax,ax
  677. ret
  678. _IPX_Broadcast_Packet95 endp
  679. _IPX_Get_Local_Target95 proc far pascal uses ebx ecx edx esi edi ds es fs gs,
  680. dest_network :far ptr byte,
  681. dest_node :far ptr byte,
  682. socket :word,
  683. bridge_address :far ptr byte
  684. local segmento :word
  685. local selector :word
  686. local result_code :word
  687. int 3
  688. ;
  689. ; Allocate DOS memory for buffers passed to interrupt
  690. ;
  691. xor ax,ax
  692. mov bx,(sizeof local_target_reply_buffer + \
  693. sizeof request_local_target_buffer + 15)
  694. save bp
  695. push ax
  696. push bx
  697. call GLOBALDOSALLOC
  698. restore bp
  699. test ax,ax
  700. jz @@return_error
  701. mov [segmento],dx
  702. mov [selector],ax
  703. mov fs,dx
  704. xor di,di
  705. ;
  706. ; Init the request structure
  707. ;
  708. mov_d eax,[dest_network]
  709. mov_d fs:[di.lt_network_number],eax
  710. mov_d eax,[dest_node]
  711. mov_d fs:[di.lt_physical_node],eax
  712. mov_w ax,[dest_node+4]
  713. mov_w fs:[di.lt_physical_node+4],ax
  714. mov ax,[socket]
  715. mov fs:[di.lt_socket],ax
  716. mov bx,IPX_GET_LOCAL_TARGET
  717. mov ax,[segmento]
  718. mov ds,ax
  719. xor si,si
  720. mov es,ax
  721. mov di,sizeof request_local_target_buffer
  722. push bp
  723. call Call_IPX
  724. pop bp
  725. mov [result_code],ax
  726. mov ds,[selector]
  727. mov si,sizeof request_local_target_buffer + lt_local_target
  728. les di,bridge_address
  729. movsd
  730. movsw
  731. ;
  732. ; Free the DOS memory
  733. ;
  734. mov bx,@data
  735. mov ds,bx
  736. mov es,bx
  737. mov fs,bx
  738. mov gs,bx
  739. mov bx,[selector]
  740. save bp
  741. push bx
  742. call GLOBALDOSFREE
  743. restore bp
  744. ;
  745. ; Return the IPX result code
  746. ;
  747. mov ax,[result_code]
  748. ret
  749. @@return_error: mov ax,-1
  750. ret
  751. _IPX_Get_Local_Target95 endp
  752. _IPX_Get_Outstanding_Buffer95 proc far pascal uses ebx ecx edx esi edi ebp ds es fs gs,
  753. copy_receive_buffer:far ptr byte
  754. int 3
  755. mov ax,@data
  756. mov ds,ax
  757. xor ax,ax
  758. mov si,[LastPassedReceiveBuffer]
  759. cmp si,[CurrentReceiveBuffer]
  760. jz @@done
  761. push ds
  762. mov cx,RECEIVE_BUFFER_LENGTH/4
  763. mov ds,[ReceiveBufferSelector]
  764. les di,[copy_receive_buffer]
  765. rep movsd
  766. pop ds
  767. cmp si,RECEIVE_BUFFER_LENGTH*MAX_RECEIVE_BUFFERS
  768. jc @@no_wrap
  769. xor si,si
  770. @@no_wrap: mov [LastPassedReceiveBuffer],si
  771. mov ax,1
  772. @@done: ret
  773. _IPX_Get_Outstanding_Buffer95 endp
  774. Receive_Callback proc far
  775. pushf
  776. cli
  777. cld
  778. pushad
  779. push ds
  780. push es
  781. push fs
  782. push gs
  783. mov ax,@data
  784. mov ds,ax
  785. cmp [NoReenter],0
  786. jnz @@out
  787. mov [NoReenter],1
  788. mov ax,[CurrentReceiveBuffer]
  789. add ax,RECEIVE_BUFFER_LENGTH
  790. cmp ax,RECEIVE_BUFFER_LENGTH*MAX_RECEIVE_BUFFERS
  791. jc @@no_wrap
  792. xor ax,ax
  793. @@no_wrap: mov [CurrentReceiveBuffer],ax
  794. call Listen_For_Packet
  795. mov ax,@data
  796. mov ds,ax
  797. mov [NoReenter],0
  798. @@out: pop gs
  799. pop fs
  800. pop es
  801. pop ds
  802. popad
  803. popf
  804. ret
  805. Receive_Callback endp
  806. Init_Receive_ECB proc near uses eax ebx ecx edx esi edi ebp ds es
  807. mov ax,@data
  808. mov ds,ax
  809. mov es,[ReceiveBufferSelector]
  810. ;
  811. ; Clear out the ECB
  812. ;
  813. mov di,[ReceiveECBOffset]
  814. mov cx,sizeof ECB
  815. xor al,al
  816. rep stosb
  817. ;
  818. ; Set up the ECB
  819. ;
  820. ;
  821. ;General ECB data
  822. mov di,[ReceiveECBOffset]
  823. mov ax,[MySocket]
  824. mov es:[di.SocketNumber],ax
  825. mov es:[di.PacketCount],2
  826. ;
  827. ; Packet address for IPX header
  828. mov ax,[CurrentReceiveBuffer]
  829. mov bx,[ReceiveBufferSegment]
  830. mov_w es:[di.PacketAddress0+OFFS],ax
  831. mov_w es:[di.PacketAddress0+SEGM],bx
  832. mov es:[di.PacketLength0],sizeof IPXHeaderType
  833. ;
  834. ; Packet address for receive buffer
  835. mov ax,[CurrentReceiveBuffer]
  836. add ax,sizeof IPXHeaderType
  837. mov_w es:[di.PacketAddress1+OFFS],ax
  838. mov_w es:[di.PacketAddress1+SEGM],bx
  839. mov es:[di.PacketLength1],546
  840. ;
  841. ; Set up the callback address
  842. mov ax,[RealModeCallbackOffset]
  843. mov_w es:[di.Event_Service_Routine+OFFS],ax
  844. mov ax,[RealModeCallbackSegment]
  845. mov_w es:[di.Event_Service_Routine+SEGM],ax
  846. ret
  847. Init_Receive_ECB endp
  848. _IPX_Start_Listening95 proc far pascal uses ebx ecx edx esi edi ebp ds es fs gs
  849. mov ax,@data
  850. mov ds,ax
  851. cmp [Listening],0
  852. jnz @@restart ;already listening
  853. ;
  854. ; Allocate and lock DOS memory for listen
  855. ; ECB and receive buffers
  856. ;
  857. mov bx,(RECEIVE_BUFFER_LENGTH*MAX_RECEIVE_BUFFERS + sizeof ECB + 15)
  858. xor ax,ax
  859. save bp,ds
  860. push ax
  861. push bx
  862. call GLOBALDOSALLOC
  863. restore bp,ds
  864. test ax,ax
  865. jz @@error
  866. mov [ReceiveBufferSegment],dx
  867. mov [ReceiveBufferSelector],ax
  868. ;
  869. ; Set up pointers to the DOS memory
  870. ;
  871. mov [ReceiveECBOffset],RECEIVE_BUFFER_LENGTH * MAX_RECEIVE_BUFFERS
  872. mov [CurrentReceiveBuffer],0 ;1st receive buffer
  873. mov [LastPassedReceiveBuffer],0
  874. ;
  875. ; Set up a real mode callback function
  876. ;
  877. mov ax,DPMI_ALLOCATE_CALLBACK
  878. mov si,offset Receive_Callback
  879. mov di,offset CallbackRegisterDump
  880. push cs
  881. pop ds
  882. mov bx,@data
  883. mov es,bx
  884. save bp
  885. int 31h
  886. restore bp
  887. bcs @@error
  888. mov ax,@data
  889. mov ds,ax
  890. mov [RealModeCallbackSegment],cx
  891. mov [RealModeCallbackOffset],dx
  892. @@restart: save ds
  893. call Listen_For_Packet
  894. restore ds
  895. mov [Listening],1
  896. @@out: mov ax,1
  897. ret
  898. @@error: xor ax,ax
  899. ret
  900. _IPX_Start_Listening95 endp
  901. _IPX_Shut_Down95 proc far pascal uses eax ebx ecx edx esi edi ebp ds es fs gs
  902. int 3
  903. mov ax,@data
  904. mov ds,ax
  905. cmp [Listening],0
  906. jz @@out
  907. ;
  908. ; Stop listening for a packet
  909. ;
  910. mov es,[ReceiveBufferSegment]
  911. mov si,[ReceiveECBOffset]
  912. mov bx,IPX_CANCEL_EVENT
  913. save bp,ds
  914. call Call_IPX
  915. save bp,ds
  916. ;
  917. ; Remove the real mode callback function
  918. ;
  919. mov cx,[RealModeCallbackSegment]
  920. mov dx,[RealModeCallbackOffset]
  921. mov ax,DPMI_RELEASE_CALLBACK
  922. save bp,ds
  923. int 31h
  924. restore bp,ds
  925. ;
  926. ; Free the DOS memory
  927. ;
  928. mov ax,@data
  929. mov ds,ax
  930. mov es,ax
  931. mov fs,ax
  932. mov gs,ax
  933. mov ax,[ReceiveBufferSelector]
  934. save bp,ds
  935. push ax
  936. call GLOBALDOSFREE
  937. restore bp,ds
  938. mov [Listening],0
  939. @@out: ret
  940. _IPX_Shut_Down95 endp
  941. Listen_For_Packet proc near uses ebx ecx edx esi edi ebp ds es fs gs
  942. call Init_Receive_ECB
  943. mov ax,@data
  944. mov ds,ax
  945. mov si,[ReceiveBufferSegment]
  946. mov [PseudoES],si
  947. mov si,[ReceiveECBOffset]
  948. mov bx,IPX_LISTEN_FOR_PACKET
  949. save ds
  950. call Call_IPX
  951. restore ds
  952. mov [PseudoES],0
  953. ret
  954. Listen_For_Packet endp
  955. Call_IPX proc far
  956. push gs
  957. push ax
  958. mov ax,@data
  959. mov gs,ax
  960. pop ax
  961. push bp
  962. mov bp,offset IPXCallOffset
  963. call dword ptr gs:[bp]
  964. pop bp
  965. pop gs
  966. ret
  967. push gs
  968. push ax
  969. mov ax,@data
  970. mov gs,ax
  971. pop ax
  972. ;
  973. ; Prevent reenterancy
  974. ;
  975. @@hold: ;cmp gs:[IPXHold],0
  976. ;jnz @@hold
  977. mov gs:[IPXHold],1
  978. ;
  979. ; Dump the registers first so we can use them
  980. ;
  981. mov_d gs:[RegisterDump+0ch],0
  982. mov_d gs:[RegisterDump],edi
  983. mov_d gs:[RegisterDump+4],esi
  984. mov_d gs:[RegisterDump+8],ebp
  985. mov_d gs:[RegisterDump+10h],ebx
  986. mov_d gs:[RegisterDump+14h],edx
  987. mov_d gs:[RegisterDump+18h],ecx
  988. mov_d gs:[RegisterDump+1ch],eax
  989. int 3
  990. push gs
  991. xor ax,ax
  992. push ax
  993. mov ax,4096 ;4k real mode stack
  994. push ax
  995. call GLOBALDOSALLOC
  996. pop gs
  997. mov bx,4094 ;stack ptr
  998. test ax,ax
  999. jnz @f
  1000. xor bx,bx
  1001. ;
  1002. ; Set up stack addr to zero - DPMI will supply a real mode stack
  1003. ;
  1004. @@: mov_w gs:[RegisterDump+2eh],bx ;sp
  1005. mov_w gs:[RegisterDump+30h],dx ;ss
  1006. save ax ;save selector so we can free the memory later
  1007. ;
  1008. ; Dump the flags
  1009. ;
  1010. pushf
  1011. pop gs:[word ptr RegisterDump+20h]
  1012. ;
  1013. ; Set up all segment register areas to point to our real mode segment
  1014. ;
  1015. mov_w gs:[RegisterDump+22h],es
  1016. mov_w gs:[RegisterDump+24h],ds
  1017. mov_w gs:[RegisterDump+26h],fs
  1018. mov_w gs:[RegisterDump+28h],gs
  1019. cmp gs:[PseudoES],0
  1020. jz @f
  1021. mov ax,gs:[PseudoES]
  1022. mov_w gs:[RegisterDump+22h],ax
  1023. @@:
  1024. ;
  1025. ; Set up the address to call
  1026. ;
  1027. mov ax,gs:[IPXCallSegment]
  1028. mov_w gs:[RegisterDump+2ch],ax
  1029. mov ax,gs:[IPXCallOffset]
  1030. mov_w gs:[RegisterDump+2ah],ax
  1031. mov ax,DPMI_CALL_REAL_INT ; Call real mode procedure with far return frame
  1032. xor bh,bh ; flags - should be zero
  1033. mov bl,07ah ; IPX interrupt
  1034. mov ecx,0 ;512 ; number of words to copy from the protected mode stack
  1035. mov di,offset RegisterDump
  1036. push gs
  1037. pop es
  1038. save gs
  1039. ;push ss
  1040. ;push sp
  1041. int 31h ;DPMI interrupt
  1042. ;pop ax
  1043. ;pop bx
  1044. ;pushf
  1045. ;pop cx
  1046. ;cli
  1047. ;mov sp,ax
  1048. ;mov ss,bx
  1049. ;add sp,2
  1050. ;push cx
  1051. ;popf
  1052. restore gs
  1053. mov ax,@data
  1054. mov ds,ax
  1055. mov es,ax
  1056. mov fs,ax
  1057. mov gs,ax
  1058. call GLOBALDOSFREE
  1059. mov_d eax,gs:[RegisterDump+1ch]
  1060. mov gs:[IPXHold],0
  1061. pop gs
  1062. ret
  1063. Call_IPX endp
  1064. Call_DOS proc far
  1065. push gs
  1066. push ax
  1067. mov ax,@data
  1068. mov gs,ax
  1069. pop ax
  1070. ;
  1071. ; Dump the registers first so we can use them
  1072. ;
  1073. mov_d gs:[RegisterDump],edi
  1074. mov_d gs:[RegisterDump+4],esi
  1075. mov_d gs:[RegisterDump+8],ebp
  1076. mov_d gs:[RegisterDump+10h],ebx
  1077. mov_d gs:[RegisterDump+14h],edx
  1078. mov_d gs:[RegisterDump+18h],ecx
  1079. mov_d gs:[RegisterDump+1ch],eax
  1080. ;
  1081. ; Dump the flags
  1082. ;
  1083. pushf
  1084. pop gs:[word ptr RegisterDump+20h]
  1085. ;
  1086. ; Set up all segment register areas to point to our real mode segment
  1087. ;
  1088. mov_w gs:[RegisterDump+22h],es
  1089. mov_w gs:[RegisterDump+24h],ds
  1090. mov_w gs:[RegisterDump+26h],fs
  1091. mov_w gs:[RegisterDump+28h],gs
  1092. ;
  1093. ; Set up stack addr to zero - DPMI will supply a real mode stack
  1094. ;
  1095. xor ax,ax
  1096. mov_w gs:[RegisterDump+2eh],ax ;sp
  1097. mov_w gs:[RegisterDump+30h],ax ;ss
  1098. mov ax,DPMI_CALL_REAL_INT; Simulate real mode interrupt
  1099. xor bh,bh ; flags - should be zero
  1100. mov bl,21h ; interrupt number
  1101. mov ecx,0 ;512 ; number of words to copy from the protected mode stack
  1102. mov di,offset RegisterDump
  1103. push gs
  1104. pop es
  1105. save gs
  1106. int 31h ;DPMI interrupt
  1107. restore gs
  1108. mov_d edi,gs:[RegisterDump]
  1109. mov_d esi,gs:[RegisterDump+4]
  1110. mov_d ebp,gs:[RegisterDump+8]
  1111. mov_d ebx,gs:[RegisterDump+10h]
  1112. mov_d edx,gs:[RegisterDump+14h]
  1113. mov_d ecx,gs:[RegisterDump+18h]
  1114. mov_d eax,gs:[RegisterDump+1ch]
  1115. mov_w es,gs:[RegisterDump+22h]
  1116. mov_w ds,gs:[RegisterDump+24h]
  1117. pop gs
  1118. ret
  1119. Call_DOS endp
  1120. end