1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2026-04-20 16:16:34 +00:00

Very preliminary HTTP server

This commit is contained in:
dschmenk
2015-02-09 19:32:54 -08:00
parent 175898913c
commit 9686ef8ca6
6 changed files with 687 additions and 125 deletions
+25 -17
View File
@@ -7,9 +7,24 @@ import cmdsys
predef heapmark, heapallocalign, heapalloc, heaprelease
byte MACHID
end
//
// Net object
//
import inet
predef swab, sendUDP, openUDP, closeUDP, serviceIP
predef setInterfaceIP, getInterfaceHA
word iNet
end
struc t_inet
word initIP
word serviceIP
word openUDP
word sendUDP
word closeUDP
word listenTCP
word connectTCP
word sendTCP
word closeTCP
word setInterfaceIP
word getInterfaceHA
end
//
// Needed to init subnet
@@ -178,7 +193,7 @@ def recvDHCP(remip, remport, pkt, len, param)
memcpy(@optsDHCP.5, @pkt->dhcp_yourip, 4)
memcpy(@optsDHCP.11, @pkt->dhcp_serverip, 4)
memcpy(@DHCP.dhcp_serverip, @pkt->dhcp_serverip, 4)
sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
break
is DHCP_ACK
stateDHCP = DHCP_ACK
@@ -204,15 +219,15 @@ end
//
// Get the local hardware address into the DHCP packet
//
getInterfaceHA(@DHCP.dhcp_clientha)
iNet:getInterfaceHA(@DHCP.dhcp_clientha)
//
// Clear our local IP address
//
setInterfaceIP(@zeros,@ones, @zeros)
iNet:setInterfaceIP(@zeros,@ones, @zeros)
//
// Prepare to receive DHCP packets from a server
//
portDHCP = openUDP(DHCP_CLIENT_PORT, @recvDHCP, 0)
portDHCP = iNet:openUDP(DHCP_CLIENT_PORT, @recvDHCP, 0)
//
// Service IP
//
@@ -220,24 +235,17 @@ while retry < 3 and stateDHCP <> DHCP_ACK
//
// Broadcast DHCP DISCOVER message
//
sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
for timeout = 1 to 1000
serviceIP
iNet:serviceIP()
if stateDHCP == DHCP_ACK
break
fin
next
retry = retry + 1
loop
closeUDP(portDHCP)
setInterfaceIP(@localip, @localnet, @localgw)
iNet:closeUDP(portDHCP)
iNet:setInterfaceIP(@localip, @localnet, @localgw)
puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln
//
// Service IP
//
repeat
serviceIP
until ^$C000 > 127
^$C010
done
+68 -16
View File
@@ -4,16 +4,35 @@ import cmdsys
predef memset, memcpy, modaddr, modexec
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
byte MACHID
//
// Module don't free memory
//
const modkeep = $2000
const modinitkeep = $4000
end
//
// Module don't free memory
// Net object
//
const modkeep = $2000
const modinitkeep = $4000
import inet
word iNet
end
struc t_inet
word initIP
word serviceIP
word openUDP
word sendUDP
word closeUDP
word listenTCP
word connectTCP
word sendTCP
word closeTCP
word setInterfaceIP
word getInterfaceHA
end
//
// Predefine service routine
//
predef serviceIP
predef etherServiceIP
//
// Segment list element
//
@@ -183,7 +202,7 @@ end
//
// Swap bytes in word
//
export asm swab
asm swab
LDA ESTKL,X
LDY ESTKH,X
STA ESTKH,X
@@ -194,7 +213,7 @@ end
// 1'S COMPLIMENT SUM BE format
// sum1(PREVSUM, BUF, LEN)
//
export asm sum1
asm sum1
LDY #$00
LDA ESTKL+1,X
STA SRCL
@@ -242,7 +261,7 @@ end
//
// Send IP datagram
//
export def sendIP(ipdst, proto, seglist, size)
def etherSendIP(ipdst, proto, seglist, size)
byte[t_iphdr] hdr
byte retry
word timeout
@@ -275,7 +294,7 @@ export def sendIP(ipdst, proto, seglist, size)
setFrameLen(t_earp)
writeFrame(@eFrame, t_earp)
for timeout = 1000 downto 0
serviceIP
etherServiceIP
if remoteha:0 | remoteha:2 | remoteha:4
break
fin
@@ -312,7 +331,7 @@ end
//
// Send UDP datagram
//
export def sendUDP(port, ipdst, portdst, data, len)
def etherSendUDP(port, ipdst, portdst, data, len)
word[8] seglist // list of data and header segments
byte[t_udphdr] hdr
@@ -324,12 +343,12 @@ export def sendUDP(port, ipdst, portdst, data, len)
seglist:0:seg_len = t_udphdr
seglist:4:seg_buf = data
seglist:4:seg_len = len
return sendIP(ipdst, IP_PROTO_UDP, @seglist, t_udphdr + len)
return etherSendIP(ipdst, IP_PROTO_UDP, @seglist, t_udphdr + len)
end
//
// Notify on UDP datagram received
//
export def openUDP(localport, callback, param)
def etherOpenUDP(localport, callback, param)
word port
byte i
@@ -363,7 +382,7 @@ end
//
// Clear notify on UDP port
//
export def closeUDP(port)
def etherCloseUDP(port)
word port
byte i
@@ -382,9 +401,29 @@ export def closeUDP(port)
return -1
end
//
// Open TCP socket in SERVER mode
//
def etherListenTCP(lclport, callback, param)
end
//
// Open TCP socket in CLIENT mode
//
def etherConnectTCP(remip, remport, lclport, callback, param)
end
//
// Write to TCP socket
//
def etherSendTCP(wiz, data, len)
end
//
// Close TCP socket
//
def etherCloseTCP(wiz)
end
//
// Service incoming packets
//
export def serviceIP
def etherServiceIP
word rxsize, rxpacket, rxptr
word iphdr, opt, optlen, port, lclport, remport
byte i, echolen
@@ -470,7 +509,7 @@ export def serviceIP
echo_reply:icmp_chksm = 0
seglist:seg_buf = @echo_reply
seglist:seg_len = echolen
sendIP(@iphdr=>ip_src, IP_PROTO_ICMP, @seglist, echolen)
etherSendIP(@iphdr=>ip_src, IP_PROTO_ICMP, @seglist, echolen)
fin
if hookICMP
hookICMP(@iphdr=>ip_src, rxptr, rxsize)
@@ -516,7 +555,7 @@ end
//
// Set the local IP addresses
//
export def setInterfaceIP(newIP, newSubnet, newGateway)
def setEtherIP(newIP, newSubnet, newGateway)
if newIP; memcpy(@localip, newIP, IP4ADR_SIZE); fin
if newSubnet; memcpy(@subnet, newSubnet, IP4ADR_SIZE); fin
if newGateway; memcpy(@gateway, newGateway, IP4ADR_SIZE); fin
@@ -524,9 +563,22 @@ end
//
// Get the interface hardware address
//
export def getInterfaceHA(ha)
def getEtherHA(ha)
if ha; memcpy(ha, @myMAC, MAC_SIZE); fin
return MAC_SIZE
end
//
// Fill in Net class
//
iNet:serviceIP = @etherServiceIP
iNet:openUDP = @etherOpenUDP
iNet:sendUDP = @etherSendUDP
iNet:closeUDP = @etherCloseUDP
iNet:listenTCP = @etherListenTCP
iNet:connectTCP = @etherConnectTCP
iNet:sendTCP = @etherSendTCP
iNet:closeTCP = @etherCloseTCP
iNet:setInterfaceIP = @setEtherIP
iNet:getInterfaceHA = @getEtherHA
done
+47 -16
View File
@@ -5,6 +5,31 @@ import cmdsys
byte MACHID
end
//
// Module don't free memory
//
const modkeep = $2000
const modinitkeep = $4000
//
// Net object
//
struc t_inet
word initIP
word serviceIP
word openUDP
word sendUDP
word closeUDP
word listenTCP
word connectTCP
word sendTCP
word closeTCP
word setInterfaceIP
word getInterfaceHA
end
//
// External interface to net class. Must be first.
//
export byte[t_inet] iNet
//
// List of loadable network device drivers
//
byte netDrivers = "WIZNET"
@@ -15,22 +40,28 @@ word driver = @netDrivers
// DHCP module to load
//
byte dhcp = "DHCP"
//
// Look for net hardware
//
while ^driver
puts(driver);putln
if modexec(driver) >= 0
break
export def iNetInit
//
// Look for net hardware
//
while ^driver
//puts(driver);putln
if modexec(driver) >= 0
break
fin
driver = driver + ^driver + 1
loop
if !^driver
return 0
fin
driver = driver + ^driver + 1
loop
if !^driver
return -1
fin
//
// Get an IP address
//
modexec(@dhcp)
//
// Get an IP address
//
modexec(@dhcp)
return @iNet
end
iNet:initIP = @iNetInit
done
+311 -75
View File
@@ -12,6 +12,25 @@ import cmdsys
byte MACHID
end
//
// Net object
//
import inet
word iNet
end
struc t_inet
word initIP
word serviceIP
word openUDP
word sendUDP
word closeUDP
word listenTCP
word connectTCP
word sendTCP
word closeTCP
word setInterfaceIP
word getInterfaceHA
end
//
// Module don't free memory
//
const modkeep = $2000
@@ -96,7 +115,7 @@ byte[4] gateway
//
// Predefine service routine
//
predef serviceIP
predef wizServiceIP
//
// Segment list element
//
@@ -190,18 +209,35 @@ end
//
const MAX_WIZ_CHANNELS = 4
//
// Channel protocols
//
const WIZ_PROTO_CLOSED = 0
const WIZ_PROTO_TCP = 1
const WIZ_PROTO_UDP = 2
const WIZ_PROTO_IP = 3
const WIZ_PROTO_RAW = 4
//
// State transistions
//
const TCP_STATE_CLOSED = 0
const TCP_STATE_CLOSING = 1
const TCP_STATE_LISTEN = 2
const TCP_STATE_CONNECT = 3
const TCP_STATE_OPEN = 4
//
// HW channels
//
struc t_channel
byte channel_proto
word channel_regs
word channel_txmem
word channel_rxmem
word channel_lclport
word channel_remport
word channel_remip
word channel_recv_func
word channel_recv_parm
byte channel_proto
byte channel_state
word channel_regs
word channel_txmem
word channel_rxmem
word channel_lclport
word channel_remport
byte[4] channel_remip
word channel_recv_func
word channel_recv_parm
end
byte[t_channel * MAX_WIZ_CHANNELS] wizChannel
//
@@ -217,7 +253,7 @@ end
//
// Swap bytes in word
//
export asm swab
asm swab
LDA ESTKL,X
LDY ESTKH,X
STA ESTKH,X
@@ -225,55 +261,6 @@ export asm swab
RTS
end
//
// 1'S COMPLIMENT SUM BE format
// sum1(PREVSUM, BUF, LEN)
//
export asm sum1
LDY #$00
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LSR ESTKH,X ; CONVERT BYTE LEN TO WORD LEN
LDA ESTKL,X
ROR
ADC #$00
STA ESTKL,X
BEQ +
INC ESTKH,X
BCC CHKLP
INC ESTKH,X
CLC
CHKLP LDA (SRC),Y
PHA
INY
BNE +
INC SRCH
+ LDA (SRC),Y
ADC ESTKH+2,X
STA ESTKH+2,X
PLA
ADC ESTKL+2,X
STA ESTKL+2,X
INY
BNE +
INC SRCH
+ DEC ESTKL,X
BNE CHKLP
DEC ESTKH,X
BNE CHKLP
- LDA #$00
ADC ESTKH+2,X
STA ESTKH+2,X
LDA #$00
ADC ESTKL+2,X
STA ESTKL+2,X
BCS -
INX
INX
RTS
end
//
// Wiznet I/O functions
//
// POKE WORD TO I/O SPACE
@@ -440,6 +427,7 @@ def peekregw(reg)
_pokeiow(reg)
dataw.1 = _peekio()
_pokeiow(reg + 1)
dataw.0 = _peekio()
return dataw
end
@@ -475,7 +463,7 @@ end
//
// Send UDP datagram
//
export def sendUDP(wiz, ipdst, portdst, data, len)
def wizSendUDP(wiz, ipdst, portdst, data, len)
word wizregs, wizdata, txrr, txwr, splitlen
wizregs = wiz=>channel_regs
@@ -512,7 +500,7 @@ end
//
// Open UDP channel and set datagram received callback
//
export def openUDP(localport, callback, param)
def wizOpenUDP(localport, callback, param)
word wiz
byte i
@@ -520,6 +508,7 @@ export def openUDP(localport, callback, param)
//
// Look for an existing notification on localport
//
putc('O')
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == IP_PROTO_UDP and wiz=>channel_lclport == localport
@@ -542,10 +531,11 @@ export def openUDP(localport, callback, param)
return 0
fin
fin
putc('0' + i);putln
//
// Fill in this channel and open it
//
wiz->channel_proto = IP_PROTO_UDP
wiz->channel_proto = WIZ_PROTO_UDP
wiz=>channel_lclport = localport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
@@ -557,14 +547,170 @@ end
//
// Close UDP port
//
export def closeUDP(wiz)
if isuge(wiz, wizChannel) and isult(wiz, wizChannel + MAX_WIZ_CHANNELS * t_channel)
def wizCloseUDP(wiz)
putc('S')
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
if wiz->channel_proto == IP_PROTO_UDP
wiz->channel_proto = 0
pokereg(wiz=>channel_regs + WIZ_SnCR, $00) // CLOSE
if wiz->channel_proto == WIZ_PROTO_UDP
putc('1' + ((wiz=>channel_regs - WIZ_SREGS) >> 8));putln
wiz->channel_proto = WIZ_PROTO_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
return 0
fin
fin
putc('!');putln
//
// Invalid port
//
return -1
end
//
// Open TCP socket in SERVER mode
//
def wizListenTCP(lclport, callback, param)
word wiz
byte i
//
// Look for an existing notification on localport
//
putc('L')
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == WIZ_PROTO_TCP and wiz->channel_state == TCP_STATE_LISTEN and wiz=>channel_lclport == lclport
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
//
// Add notification on localport if room
//
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if !wiz->channel_proto
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
return 0
fin
fin
putc('0' + i);putln
//
// Fill in this channel and open it
//
wiz->channel_proto = WIZ_PROTO_TCP
wiz->channel_state = TCP_STATE_LISTEN
wiz=>channel_remip:0 = 0
wiz=>channel_remip:2 = 0
wiz=>channel_remport = 0
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokereg(wiz=>channel_regs + WIZ_SnCR, $02) // LISTEN
return wiz
end
//
// Open TCP socket in CLIENT mode
//
def wizConnectTCP(remip, remport, lclport, callback, param)
word wiz
byte i
//
// Look for an existing notification on localport
//
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if wiz->channel_proto == WIZ_PROTO_TCP and wiz->channel_state == TCP_STATE_CONNECT and wiz=>channel_lclport == lclport
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
//
// Add notification on localport if room
//
wiz = @wizChannel
for i = 1 to MAX_WIZ_CHANNELS
if !wiz->channel_proto
break
fin
wiz = wiz + t_channel
next
if i > MAX_WIZ_CHANNELS
return 0
fin
fin
//
// Fill in this channel and open it
//
wiz->channel_proto = WIZ_PROTO_TCP
wiz->channel_state = TCP_STATE_CONNECT
wiz=>channel_remip:0 = remip=>0
wiz=>channel_remip:2 = remip=>2
wiz=>channel_remport = remport
wiz=>channel_lclport = lclport
wiz=>channel_recv_func = callback
wiz=>channel_recv_parm = param
pokeregs(wiz=>channel_regs + WIZ_SnDIPR, remip, IP4ADR_SIZE)
pokeregw(wiz=>channel_regs + WIZ_SnDPORT, remport)
pokeregw(wiz=>channel_regs + WIZ_SnPORT, lclport)
pokereg(wiz=>channel_regs + WIZ_SnMR, $01) // TCP protocol
pokereg(wiz=>channel_regs + WIZ_SnCR, $04) // CONNECT
return wiz
end
//
// Write to TCP socket
//
def wizSendTCP(wiz, data, len)
word wizregs, wizdata, txrr, txwr, splitlen
if wiz->channel_state <> TCP_STATE_OPEN; return -1; fin
wizregs = wiz=>channel_regs
wizdata = wiz=>channel_txmem
//
// Wait for Tx room
//
repeat
txrr = peekregw(wizregs + WIZ_SnTXRD)
txwr = peekregw(wizregs + WIZ_SnTXWR)
until txrr == txwr
//
// Calc new write ptr, check for split
//
txwr = txrr + len
if txwr >= WIZ_TXSIZE
splitlen = WIZ_TXSIZE - txrr
pokeregs(wizdata + txrr, data, splitlen)
pokeregs(wizdata, data + splitlen, len - splitlen)
else
pokeregs(wizdata + txrr, data, len)
fin
pokeregw(wizregs + WIZ_SnTXWR, txwr)
pokereg(wizregs + WIZ_SnCR, $20) // SEND
end
//
// Close TCP socket
//
def wizCloseTCP(wiz)
if isuge(wiz, @wizChannel) and isult(wiz, @wizChannel + MAX_WIZ_CHANNELS * t_channel)
//
// Clear notiications on this port
//
if wiz->channel_proto == WIZ_PROTO_TCP and (wiz->channel_state == TCP_STATE_OPEN or wiz->channel_state == TCP_STATE_CLOSING)
wiz->channel_state = TCP_STATE_CLOSING
pokereg(wiz=>channel_regs + WIZ_SnCR, $08) // DISCON
repeat
wizServiceIP()
until wiz->channel_state == TCP_STATE_CLOSED
wiz->channel_proto = WIZ_PROTO_CLOSED
return 0
fin
fin
@@ -576,13 +722,13 @@ end
//
// Service incoming packets
//
export def serviceIP
def wizServiceIP
word wiz, wizregs, wizdata, rxlen, rxrr, rxwr, rxpkt, splitlen
byte ir, i, sir
ir = peekreg(WIZ_IR)
if ir and ir <> $FF // Ignore spurious read of IR
//putc('I');putb(ir)
putc('I');putb(ir)
wiz = @wizChannel
for i = 0 to 3
when ir & (1 << i)
@@ -594,7 +740,86 @@ export def serviceIP
wizdata = wiz=>channel_rxmem
sir = peekreg(wizregs + WIZ_SnIR)
when wiz->channel_proto
is IP_PROTO_UDP
is WIZ_PROTO_TCP
if sir & $01
putc('C')
//
// Connect TCP socket
//
when wiz->channel_state
is TCP_STATE_LISTEN
peekregs(wiz=>channel_regs + WIZ_SnDIPR, @wiz=>channel_remip, IP4ADR_SIZE)
wiz=>channel_remport = peekregw(wiz=>channel_regs + WIZ_SnDPORT)
is TCP_STATE_CONNECT
wiz->channel_state = TCP_STATE_OPEN
break
otherwise
putc('?')
wend
fin
if sir & $04
putc('R')
//
// Receive TCP packet
//
rxlen = peekregw(wizregs + WIZ_SnRSR)
rxrr = peekregw(wizregs + WIZ_SnRXRD)
rxwr = rxrr + rxlen
rxpkt = heapalloc(rxlen)
if rxwr >= WIZ_RXSIZE
putc('!')
splitlen = WIZ_RXSIZE - rxrr
peekregs(wizdata + rxrr, rxpkt, splitlen)
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
else
peekregs(wizdata + rxrr, rxpkt, rxlen)
fin
putc('=');putip(@wiz=>channel_remip);putc(':');puti(wiz=>channel_remport);putln
pokeregw(wizregs + WIZ_SnRXRD, rxwr)
pokereg(wizregs + WIZ_SnCR, $40) // RECV
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,rxpkt,rxlen,wiz=>channel_recv_parm)
heaprelease(rxpkt)
fin
if sir & $02
putc('S')
//
// Close TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,0,wiz=>channel_lclport,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
break
otherwise
putc('?')
wend
fin
if sir & $08
putc('T')
//
// Timeout on TCP socket
//
when wiz->channel_state
is TCP_STATE_OPEN
wiz->channel_state = TCP_STATE_CLOSING
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
break
is TCP_STATE_CONNECT
wiz=>channel_recv_func(@wiz=>channel_remip,wiz=>channel_remport,wiz=>channel_lclport,0,0,wiz=>channel_recv_parm)
is TCP_STATE_CLOSING
wiz->channel_state = TCP_STATE_CLOSED
pokereg(wiz=>channel_regs + WIZ_SnCR, $10) // CLOSE
break
otherwise
putc('?')
wend
fin
break
is WIZ_PROTO_UDP
//putc('U');putb(sir)
if sir & $04
//putc('R')
@@ -622,8 +847,6 @@ export def serviceIP
heaprelease(rxpkt)
fin
break
is IP_PROTO_TCP
break
otherwise
wend
pokereg(wiz=>channel_regs + WIZ_SnIR, sir) // Clear SnIR
@@ -643,7 +866,7 @@ end
//
// Set the local IP addresses
//
export def setInterfaceIP(newIP, newSubnet, newGateway)
def setWizIP(newIP, newSubnet, newGateway)
if newIP
localip:0 = newIP=>0; localip:2 = newIP=>2
pokeregs(WIZ_SIPR, newIP, IP4ADR_SIZE)
@@ -660,7 +883,7 @@ end
//
// Get the interface hardware address
//
export def getInterfaceHA(ha)
def getWizHA(ha)
if ha
ha=>0 = wizMAC:0; ha=>2 = wizMAC:2; ha=>4 = wizMAC:4
fin
@@ -708,6 +931,19 @@ for slot = $F0 downto $90 step $10
saveidx=>channel_rxmem = WIZ_RXMEM + (WIZ_RXSIZE * slot)
saveidx = saveidx + t_channel
next
//
// Fill in Net class
//
iNet:serviceIP = @wizServiceIP
iNet:openUDP = @wizOpenUDP
iNet:sendUDP = @wizSendUDP
iNet:closeUDP = @wizCloseUDP
iNet:listenTCP = @wizListenTCP
iNet:connectTCP = @wizConnectTCP
iNet:sendTCP = @wizSendTCP
iNet:closeTCP = @wizCloseTCP
iNet:setInterfaceIP = @setWizIP
iNet:getInterfaceHA = @getWizHA
return modkeep
fin
fin