mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-08-26 11:28:54 +00:00
940 lines
22 KiB
HTML
940 lines
22 KiB
HTML
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><link rel="stylesheet" type="text/css" href="ca65-doc-style.css"/></head><body><a href="ref_index.html"><h1>ip65 technical reference</h1></a><h1>File : ip65/cifs.s</h1><pre>a simple NETBIOS over TCP server
|
|
aka "Common Internet File System"
|
|
|
|
refs: RFC1001, RFC1002, "Implementing CIFS" - http://ubiqx.org/cifs/
|
|
</pre><h2 id="functions">functions</h2><table><tr><th>function</th><th>description</th></tr><tr><td id="cifs_l1_decode">cifs_l1_decode</td><td><pre>given a 'level 1 encoded' hostname, decode to ASCII .
|
|
|
|
inputs:
|
|
AX: pointer to encoded hostname to be decoded
|
|
outputs:
|
|
AX: pointer to decoded hostname (will be 16 byte hostname, right padded with spaces, nul terminated)
|
|
</pre></td></tr><tr><td id="cifs_l1_encode">cifs_l1_encode</td><td><pre>given an ASCII (or PETSCII) hostname, convert to
|
|
canonical 'level 1 encoded' form.
|
|
|
|
only supports the default scope (' ' : 0x20)
|
|
inputs:
|
|
AX: pointer to null terminated hostname to be encoded
|
|
outputs:
|
|
AX: pointer to decoded hostname
|
|
</pre></td></tr><tr><td id="cifs_start">cifs_start</td><td><pre>start a CIFS (SMB) server process, and advertise the specified hostname on the local LAN
|
|
|
|
inputs:
|
|
AX = ptr to hostname to be used
|
|
outputs:
|
|
none
|
|
</pre></td></tr></table><h2>implementation</h2><pre id="code">;a simple NETBIOS over TCP server
|
|
;aka "Common Internet File System"
|
|
;
|
|
; refs: RFC1001, RFC1002, "Implementing CIFS" - http://ubiqx.org/cifs/
|
|
|
|
.include "../inc/common.i"
|
|
|
|
.ifndef KPR_API_VERSION_NUMBER
|
|
.define EQU =
|
|
.include "../inc/kipper_constants.i"
|
|
.endif
|
|
|
|
DEFAULT_CIFS_CMD_BUFFER = $6800
|
|
DEFAULT_SMB_RESPONSE_BUFFER=$6000
|
|
.export cifs_l1_encode
|
|
.export cifs_l1_decode
|
|
.export cifs_start
|
|
|
|
.import copymem
|
|
.importzp copy_src
|
|
.importzp copy_dest
|
|
|
|
.import cfg_ip
|
|
.import output_buffer
|
|
.importzp udp_data
|
|
.import udp_send
|
|
.import udp_inp
|
|
.importzp udp_data
|
|
.import udp_send_dest
|
|
.import udp_send_src_port
|
|
.import udp_send_dest_port
|
|
.import udp_send_len
|
|
.importzp ip_src
|
|
.importzp ip_dest
|
|
.import ip_data
|
|
.import ip_inp
|
|
.import tcp_close
|
|
.import tcp_listen
|
|
.import tcp_callback
|
|
.import tcp_inbound_data_length
|
|
.import tcp_inbound_data_ptr
|
|
.import tcp_send
|
|
.import tcp_send_data_len
|
|
|
|
.import ip65_process
|
|
.import udp_add_listener
|
|
.import udp_callback
|
|
|
|
nbns_txn_id = 0
|
|
nbns_opcode=2
|
|
nbns_flags_rcode=3
|
|
nbns_qdcount=4
|
|
nbns_ancount=6
|
|
nbns_nscount=8
|
|
nbns_arcount=10
|
|
nbns_question_name=12
|
|
nbns_service_type=43
|
|
|
|
|
|
nbns_my_ip=64
|
|
nbns_registration_message_length=68
|
|
|
|
|
|
;given an ASCII (or PETSCII) hostname, convert to
|
|
;canonical 'level 1 encoded' form.
|
|
;
|
|
;only supports the default scope (' ' : 0x20)
|
|
;inputs:
|
|
; AX: pointer to null terminated hostname to be encoded
|
|
;outputs:
|
|
; AX: pointer to decoded hostname
|
|
cifs_l1_encode:
|
|
stax copy_src
|
|
lda #0
|
|
tax
|
|
sta hostname_buffer+32
|
|
@empty_buffer_loop:
|
|
lda #$43
|
|
sta hostname_buffer,x
|
|
inx
|
|
lda #$41
|
|
sta hostname_buffer,x
|
|
inx
|
|
cpx #$20
|
|
bmi @empty_buffer_loop
|
|
ldy #0
|
|
ldx #0
|
|
@copy_loop:
|
|
|
|
lda (copy_src),y
|
|
beq @done
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
clc
|
|
adc #$41
|
|
sta hostname_buffer,x
|
|
|
|
inx
|
|
lda (copy_src),y
|
|
and #$0F
|
|
clc
|
|
adc #$41
|
|
sta hostname_buffer,x
|
|
inx
|
|
iny
|
|
cpx #$1D
|
|
bmi @copy_loop
|
|
@done:
|
|
ldax #hostname_buffer
|
|
rts
|
|
|
|
;given a 'level 1 encoded' hostname, decode to ASCII .
|
|
;
|
|
;inputs:
|
|
; AX: pointer to encoded hostname to be decoded
|
|
;outputs:
|
|
; AX: pointer to decoded hostname (will be 16 byte hostname, right padded with spaces, nul terminated)
|
|
cifs_l1_decode:
|
|
stax copy_src
|
|
ldy #0
|
|
ldx #0
|
|
@decode_loop:
|
|
lda (copy_src),y
|
|
sec
|
|
sbc #$41
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sta hi_nibble
|
|
iny
|
|
lda (copy_src),y
|
|
sec
|
|
sbc #$41
|
|
clc
|
|
adc hi_nibble
|
|
sta hostname_buffer,x
|
|
iny
|
|
inx
|
|
cpx #$10
|
|
bmi @decode_loop
|
|
lda #0
|
|
sta hostname_buffer,x
|
|
ldax #hostname_buffer
|
|
rts
|
|
|
|
|
|
;start a CIFS (SMB) server process, and advertise the specified hostname on the local LAN
|
|
;
|
|
;inputs:
|
|
;AX = ptr to hostname to be used
|
|
;outputs:
|
|
; none
|
|
cifs_start:
|
|
|
|
;save the hostname in 'raw' form
|
|
stax copy_src
|
|
ldax #raw_local_hostname
|
|
stax copy_dest
|
|
ldax #$0f
|
|
stx raw_local_hostname+15
|
|
jsr copymem
|
|
|
|
;set up callbacks
|
|
ldax #nbns_callback
|
|
stax udp_callback
|
|
ldax #137
|
|
jsr udp_add_listener
|
|
|
|
ldax #nbns_callback
|
|
stax udp_callback
|
|
ldax #137
|
|
jsr udp_add_listener
|
|
|
|
ldax #raw_local_hostname
|
|
jsr cifs_l1_encode
|
|
ldx #0
|
|
@copy_hostname_loop:
|
|
lda hostname_buffer,x
|
|
sta local_hostname,x
|
|
inx
|
|
cpx #$21
|
|
bmi @copy_hostname_loop
|
|
|
|
jsr cifs_advertise_hostname
|
|
jsr cifs_advertise_hostname
|
|
|
|
|
|
ldax #nb_session_callback
|
|
stax tcp_callback
|
|
@listen:
|
|
|
|
ldax #-4 ;start at -4, to skip the NBT header length
|
|
stax cifs_cmd_length
|
|
|
|
|
|
ldax cifs_cmd_buffer
|
|
stax cifs_cmd_buffer_ptr
|
|
ldax #139
|
|
stx connection_closed
|
|
|
|
jsr tcp_listen
|
|
|
|
@loop:
|
|
inc $d020 ;FIXME
|
|
jsr ip65_process
|
|
lda connection_closed
|
|
beq @loop
|
|
|
|
jmp @listen
|
|
rts
|
|
|
|
|
|
;broadcast a Name Registration Request message to the local LAN
|
|
cifs_advertise_hostname:
|
|
|
|
; advertise the 'server' service for own hostname
|
|
;overwrite the hostname in 'DNS compressed form'
|
|
;we assume this hostname ends with <20>
|
|
lda #$20 ;indicates what follows is a netbios name
|
|
sta output_buffer+nbns_question_name
|
|
|
|
ldx #0
|
|
@copy_hostname_loop:
|
|
lda local_hostname,x
|
|
sta registration_request_servername+1,x
|
|
inx
|
|
cpx #$21
|
|
bmi @copy_hostname_loop
|
|
|
|
jsr @send_nbns_message
|
|
|
|
|
|
;copy our encode hostname to the host announcment
|
|
ldax #local_hostname
|
|
stax copy_src
|
|
ldax #host_announce_hostname
|
|
stax copy_dest
|
|
ldax #$20
|
|
jsr copymem
|
|
|
|
;copy our raw hostname to the host announcment
|
|
ldax #raw_local_hostname
|
|
stax copy_src
|
|
ldax #host_announce_servername
|
|
stax copy_dest
|
|
ldax #$10
|
|
jsr copymem
|
|
|
|
|
|
;copy the local IP address to the 'sender' field of the host announcment
|
|
ldx #03
|
|
@copy_sending_address_loop:
|
|
lda cfg_ip,x
|
|
sta host_announce_my_ip,x
|
|
dex
|
|
bpl @copy_sending_address_loop
|
|
|
|
|
|
ldax #138
|
|
stax udp_send_dest_port
|
|
stax udp_send_src_port
|
|
|
|
ldax #host_announce_message_length
|
|
stax udp_send_len
|
|
|
|
ldax #host_announce_message
|
|
jsr udp_send
|
|
rts
|
|
|
|
|
|
@send_nbns_message:
|
|
;copy the local IP address
|
|
ldx #03
|
|
@copy_my_address_loop:
|
|
lda cfg_ip,x
|
|
sta nbns_my_ip,x
|
|
dex
|
|
bpl @copy_my_address_loop
|
|
|
|
;send to the broadcast address
|
|
lda #$ff
|
|
ldx #03
|
|
@copy_broadcast_address_loop:
|
|
sta udp_send_dest,x
|
|
dex
|
|
bpl @copy_broadcast_address_loop
|
|
|
|
ldax #137
|
|
stax udp_send_dest_port
|
|
stax udp_send_src_port
|
|
|
|
ldax #nbns_registration_message_length
|
|
stax udp_send_len
|
|
|
|
ldax #registration_request
|
|
jsr udp_send
|
|
|
|
|
|
rts
|
|
|
|
|
|
|
|
nbns_callback:
|
|
|
|
lda udp_inp+udp_data+nbns_opcode
|
|
and #$f8 ;mask the lower three bits
|
|
beq @name_request
|
|
rts
|
|
@name_request:
|
|
|
|
;this is a NB NAME REQUEST.
|
|
;is it a unicast message?
|
|
ldx #3
|
|
@check_unicast_loop:
|
|
lda ip_inp+ip_dest,x
|
|
cmp cfg_ip,x
|
|
bne @not_unicast
|
|
dex
|
|
bpl @check_unicast_loop
|
|
|
|
jmp @looking_for_us
|
|
|
|
@not_unicast:
|
|
;is it looking for our local hostname?
|
|
ldax #udp_inp+udp_data+nbns_question_name+1
|
|
stax copy_src
|
|
ldy #0
|
|
@cmp_loop:
|
|
lda (copy_src),y
|
|
cmp local_hostname,y
|
|
bne @not_us
|
|
iny
|
|
cpy #30
|
|
bne @cmp_loop
|
|
|
|
@looking_for_us:
|
|
;this is a request for our name!
|
|
;copy the txn id
|
|
ldax udp_inp+udp_data ;first 2 bytes of data are txn id
|
|
stax netbios_name_query_response
|
|
|
|
;set the sender & recipients IP address
|
|
ldx #03
|
|
@copy_address_loop:
|
|
lda ip_inp+ip_src,x
|
|
sta udp_send_dest,x
|
|
lda cfg_ip,x
|
|
sta netbios_name_query_response_ip,x
|
|
dex
|
|
bpl @copy_address_loop
|
|
|
|
;copy our encoded hostname
|
|
ldax #local_hostname
|
|
stax copy_src
|
|
ldax #netbios_name_query_response_hostname
|
|
stax copy_dest
|
|
ldax #30
|
|
jsr copymem
|
|
|
|
;copy the service identifier - last 2 bytes in the query hostname
|
|
.import eth_inp
|
|
ldax eth_inp+$55
|
|
stax netbios_name_query_response_hostname+30
|
|
|
|
ldax #137
|
|
stax udp_send_dest_port
|
|
stax udp_send_src_port
|
|
|
|
ldax #netbios_name_query_response_length
|
|
stax udp_send_len
|
|
|
|
ldax #netbios_name_query_response
|
|
jmp udp_send
|
|
|
|
|
|
@not_us:
|
|
rts
|
|
|
|
|
|
nb_session_callback:
|
|
|
|
lda tcp_inbound_data_length+1
|
|
cmp #$ff
|
|
bne @not_eof
|
|
@eof:
|
|
inc connection_closed
|
|
@done:
|
|
rts
|
|
@not_eof:
|
|
|
|
;copy this chunk to our input buffer
|
|
ldax cifs_cmd_buffer_ptr
|
|
stax copy_dest
|
|
ldax tcp_inbound_data_ptr
|
|
stax copy_src
|
|
ldax tcp_inbound_data_length
|
|
jsr copymem
|
|
|
|
;increment the pointer into the input buffer
|
|
clc
|
|
lda cifs_cmd_buffer_ptr
|
|
adc tcp_inbound_data_length
|
|
sta cifs_cmd_buffer_ptr
|
|
lda cifs_cmd_buffer_ptr+1
|
|
adc tcp_inbound_data_length+1
|
|
sta cifs_cmd_buffer_ptr+1
|
|
|
|
;increment the cmd buffer length
|
|
clc
|
|
lda cifs_cmd_length
|
|
adc tcp_inbound_data_length
|
|
sta cifs_cmd_length
|
|
lda cifs_cmd_length+1
|
|
adc tcp_inbound_data_length+1
|
|
sta cifs_cmd_length+1
|
|
|
|
;have we got a complete message?
|
|
ldax cifs_cmd_buffer
|
|
stax copy_src
|
|
ldy #3
|
|
lda (copy_src),y
|
|
cmp cifs_cmd_length
|
|
bne @not_got_full_message
|
|
dey
|
|
lda (copy_src),y
|
|
cmp cifs_cmd_length+1
|
|
bne @not_got_full_message
|
|
|
|
;we have a complete message!
|
|
ldy #0
|
|
lda (copy_src),y ;get the message type
|
|
cmp #$81 ;is it a session request?
|
|
bne @not_session_request
|
|
ldax #positive_session_response_packet_length
|
|
stax tcp_send_data_len
|
|
ldax #positive_session_response_packet
|
|
jsr tcp_send
|
|
|
|
jmp @message_handled
|
|
@not_session_request:
|
|
cmp #$00 ;is it a session message?
|
|
bne @not_session_message
|
|
|
|
;this SHOULD be a SMB - best check the header
|
|
|
|
ldy #4
|
|
lda (copy_src),y ;get the message data
|
|
cmp #$FF ;start of SMB header
|
|
bne @not_smb
|
|
iny
|
|
lda (copy_src),y ;get the message data
|
|
cmp #'S' ;start of SMB header
|
|
bne @not_smb
|
|
|
|
jsr smb_handler
|
|
|
|
jmp @message_handled
|
|
|
|
;this doesn't look like a NBT session message or SMB, so give up
|
|
@not_session_message:
|
|
|
|
@not_smb:
|
|
|
|
jsr tcp_close
|
|
jmp @eof
|
|
|
|
@message_handled:
|
|
;reset ready for next message on this connection
|
|
ldax #-4 ;start at -4, to skip the NBT header length
|
|
stax cifs_cmd_length
|
|
|
|
|
|
ldax cifs_cmd_buffer
|
|
stax cifs_cmd_buffer_ptr
|
|
|
|
|
|
|
|
@not_got_full_message:
|
|
rts
|
|
|
|
|
|
smb_handler:
|
|
; at this point, copy_src points to an SMB block encapsulated in an NBT session header
|
|
|
|
clc
|
|
lda copy_src
|
|
adc #4
|
|
sta smb_ptr ;skip past the NBT header
|
|
lda copy_src+1
|
|
adc #00
|
|
sta smb_ptr+1
|
|
|
|
ldy #8
|
|
lda (copy_src),y ;get the SMB type
|
|
cmp #$72
|
|
bne @not_negotiate_protocol
|
|
jmp @negotiate_protocol
|
|
@not_negotiate_protocol:
|
|
;we assume it is an "AndX" command
|
|
|
|
|
|
|
|
sta andx_opcode
|
|
lda smb_ptr
|
|
clc
|
|
adc #$20 ;skip over SMB header
|
|
sta andx_ptr
|
|
|
|
lda smb_ptr+1
|
|
adc #00
|
|
sta andx_ptr+1
|
|
|
|
jsr start_smb_response
|
|
|
|
@parse_andx_block:
|
|
ldax andx_ptr
|
|
stax copy_src
|
|
lda andx_opcode
|
|
|
|
cmp #$ff
|
|
beq @done_all_andx_blocks
|
|
|
|
ldy #0
|
|
@andx_opcode_scan:
|
|
lda andx_opcodes,y
|
|
beq @opcode_not_found
|
|
cmp andx_opcode
|
|
beq @opcode_found
|
|
iny
|
|
iny
|
|
iny
|
|
jmp @andx_opcode_scan
|
|
@opcode_found:
|
|
lda andx_opcodes+1,y
|
|
sta andx_handler+1
|
|
lda andx_opcodes+2,y
|
|
sta andx_handler+2
|
|
jsr andx_handler
|
|
jmp @go_to_next_andx_block
|
|
|
|
@opcode_not_found:
|
|
jsr unknown_andx
|
|
|
|
@go_to_next_andx_block:
|
|
ldy #3
|
|
lda (copy_src),y ;get the AndX offset low byte
|
|
clc
|
|
adc smb_ptr
|
|
sta andx_ptr
|
|
iny
|
|
lda (copy_src),y ;get the AndX offset high byte
|
|
adc smb_ptr+1
|
|
sta andx_ptr+1
|
|
ldy #1
|
|
lda (copy_src),y ;get the subsequent AndX opcode
|
|
sta andx_opcode
|
|
|
|
jmp @parse_andx_block
|
|
|
|
@done_all_andx_blocks:
|
|
ldax smb_response_length
|
|
inx ;FIXME! this is to force wireshark to dump as SMB even tho packet is incorrect
|
|
stax tcp_send_data_len
|
|
ldax smb_response_buffer
|
|
jsr tcp_send
|
|
|
|
rts
|
|
@negotiate_protocol:
|
|
;copy the request TID,PID,UID,MID into the response
|
|
ldy #28 ;offset of TID from start of message
|
|
ldx #0
|
|
:
|
|
lda (copy_src),y
|
|
sta negotiate_protocol_response_tid,x
|
|
inx
|
|
iny
|
|
cpx #8
|
|
bne :-
|
|
|
|
|
|
lda #$ff
|
|
sta dialect_index
|
|
sta dialect_index+1
|
|
clc
|
|
lda cifs_cmd_buffer
|
|
adc #$26
|
|
sta copy_src
|
|
lda cifs_cmd_buffer+1
|
|
adc #$00
|
|
sta copy_src+1
|
|
|
|
ldy #$0
|
|
@dialect_scan_loop:
|
|
iny
|
|
bmi @end_of_dialects ;if we go to offset $80, we have gone too far
|
|
lda dialect_index
|
|
cmp #$10 ;if we've scanned more than $10 dialects, something is wrong
|
|
beq @end_of_dialects
|
|
lda (copy_src),y
|
|
cmp #$02
|
|
bne @test_dialect
|
|
inc dialect_index
|
|
jmp @dialect_scan_loop
|
|
@test_dialect:
|
|
|
|
tya
|
|
clc
|
|
adc copy_src
|
|
sta copy_src
|
|
bcc :+
|
|
inc copy_src+1
|
|
:
|
|
ldy #0
|
|
|
|
@test_dialect_loop:
|
|
lda (copy_src),y
|
|
cmp preferred_dialect_id,y
|
|
bne @dialect_scan_loop
|
|
iny
|
|
cpy #preferred_dialect_id_length
|
|
bne @test_dialect_loop
|
|
inc dialect_index+1
|
|
jmp @found_preferred_dialect
|
|
|
|
@end_of_dialects:
|
|
lda #$ff
|
|
sta dialect_index
|
|
|
|
@found_preferred_dialect:
|
|
|
|
ldax #negotiate_protocol_response_message_length
|
|
stax tcp_send_data_len
|
|
ldax #negotiate_protocol_response_message
|
|
jsr tcp_send
|
|
|
|
rts
|
|
|
|
start_smb_response:
|
|
ldax smb_response_buffer
|
|
stax copy_dest
|
|
ldy #0
|
|
@copy_header_loop:
|
|
lda (copy_src),y ; copy_src should be the SMB request - cloning this will set PID / MID etc
|
|
sta (copy_dest),y
|
|
iny
|
|
cpy #smb_response_header_length
|
|
bne @copy_header_loop
|
|
lda #0
|
|
sta smb_response_length+1
|
|
lda #smb_response_header_length
|
|
sta smb_response_length
|
|
ldy #3
|
|
sta (copy_dest),y
|
|
|
|
;set the flags correctly
|
|
ldy #smb_response_flags_offset
|
|
lda #$82 ;FLAGS byte
|
|
sta (copy_dest),y
|
|
iny
|
|
lda #$01 ;FLAGS2 low byte
|
|
sta (copy_dest),y
|
|
iny
|
|
lda #$00 ;FLAGS2 hi byte
|
|
sta (copy_dest),y
|
|
|
|
rts
|
|
|
|
add_andx_response:
|
|
rts
|
|
|
|
|
|
.import print_a
|
|
.import print_hex
|
|
session_setup_andx:
|
|
lda #'S'
|
|
jsr print_a
|
|
rts
|
|
|
|
tree_connect_andx:
|
|
lda #'T'
|
|
jsr print_a
|
|
rts
|
|
|
|
unknown_andx:
|
|
lda andx_opcode
|
|
jsr print_hex
|
|
lda #'?'
|
|
jsr print_a
|
|
rts
|
|
|
|
.rodata
|
|
|
|
andx_opcodes:
|
|
.byte $73
|
|
.word session_setup_andx
|
|
.byte $75
|
|
.word tree_connect_andx
|
|
.byte $00
|
|
|
|
|
|
|
|
.data
|
|
|
|
andx_handler:
|
|
jmp $FFFF ;filled in later
|
|
|
|
smb_response_header:
|
|
negotiate_protocol_response_message:
|
|
.byte $00 ;message type = session message
|
|
.byte $00,$00,negotiate_protocol_response_message_length-4 ;NBT header
|
|
.byte $FF,"SMB" ;SMB header
|
|
.byte $72 ;command = negotiate protocol
|
|
.byte $00,$00,$00,$00 ;status = OK
|
|
smb_response_flags_offset =*-smb_response_header
|
|
.byte $82 ;flags : oplocks not supported, paths are case sensitive
|
|
.byte $01,$00 ;flags 2 - long file names allowed
|
|
.byte $00, $00 ;PID HIGH
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00 ; signature
|
|
.byte $00, $00 ;reserved
|
|
negotiate_protocol_response_tid:
|
|
.byte $00,$00 ;tree ID
|
|
.byte $98,$76 ;PID - to be overwritten
|
|
.byte $65,$64 ;USER ID - to be overwritten
|
|
.byte $ab,$cd ;multiplex ID - to be overwritten
|
|
smb_response_header_length=*-smb_response_header
|
|
.byte $11 ;word count
|
|
dialect_index: .res 2 ;index of selected dialect
|
|
.byte $00 ;security mode: share, no encryption
|
|
.byte $01,$00 ;Max MPX count
|
|
.byte $01,$00 ;Max VCs count
|
|
.byte $00,$08,$00,$00 ;max buffer size
|
|
.byte $00,$08,$00,$00 ;max raw size
|
|
.byte $12,$34,$56,$78 ;session key
|
|
.byte $00,$00,$00,$00 ;capabilities
|
|
.byte $00,$00,$00,$00 ;server time low
|
|
.byte $00,$00,$00,$00 ;server time high
|
|
.byte $00,$00 ;server GMT offset
|
|
.byte $00 ;encryption key length
|
|
.word negotiate_protocol_response_message_data_length ;data length
|
|
negotiate_protocol_response_message_data:
|
|
.byte "WORKGROUP",0
|
|
.byte "SERVERNAME",0
|
|
|
|
negotiate_protocol_response_message_length=*-negotiate_protocol_response_message
|
|
negotiate_protocol_response_message_data_length=*-negotiate_protocol_response_message_data
|
|
|
|
host_announce_message:
|
|
.byte $11 ;message type = direct group datagram
|
|
.byte $02 ;no more fragments, this is first fragment, node type = B
|
|
.byte $ab,$cd ;txn id
|
|
host_announce_my_ip:
|
|
.byte $0,0,0,0 ;source IP
|
|
.byte $0,138 ;source port
|
|
.byte $00,<(host_announce_message_length-4) ;datagram length
|
|
.byte $00,$00 ;packet offset
|
|
.byte $20 ;hostname length
|
|
host_announce_hostname:
|
|
.res 32 ;hostname
|
|
.byte $0 ;nul at end of hostname
|
|
;now WORKGROUP<1D> encoded
|
|
|
|
.byte $20, $46, $48, $45, $50, $46, $43, $45, $4c, $45, $48, $46, $43, $45, $50, $46
|
|
.byte $46, $46, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $42, $4E, $00
|
|
|
|
.byte $ff,"SMB" ;Server Message Block header
|
|
.byte $25 ;SMB command = Transaction
|
|
.byte $00 ;error class = success
|
|
.byte $00 ;reserved
|
|
.byte $00,$00 ;no error
|
|
.byte $00 ;flags
|
|
.byte $00,$00 ;flags2
|
|
.byte $00,$00 ;PID high
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00 ;Signature
|
|
.byte $00,$00 ;reserved
|
|
.byte $00,$00 ;tree ID
|
|
.byte $00,$00 ;process ID
|
|
.byte $00,$00 ;user ID
|
|
.byte $00,$00 ;multiplex ID
|
|
.byte $11 ;txn word count
|
|
.byte $00,$00 ;txn paramater count
|
|
.byte $21,$00 ;txn total data count
|
|
.byte $00,$00 ;txn max paramater count
|
|
.byte $00,$00 ;txn max data count
|
|
.byte $00 ;txn max setup count
|
|
.byte $00 ;reserved
|
|
.byte $00,$00 ;flags
|
|
.byte $ed,$03,$00,$00 ;timeout = 1 second
|
|
.byte $00,$00 ;reserved
|
|
.byte $00,$00 ;paramater count
|
|
.byte $00,$00 ;paramater offset
|
|
.byte $21,$00 ;data count
|
|
.byte $56,$00 ;data offset
|
|
.byte $03 ;setup count
|
|
.byte $00 ;reserved
|
|
|
|
.byte $01,$00 ;opcode = WRITE MAIL SLOT
|
|
.byte $00,$00 ;priority 0
|
|
.byte $02,$00 ;class = unreliable & broadcast
|
|
.byte $32,$00 ;byte count
|
|
.byte "\MAILSLOT\BROWSE", 0
|
|
.byte $01 ;command - HOST ANNOUNCEMENT
|
|
.byte $0 ;update count 0
|
|
.byte $80,$fc,03,00 ;update period
|
|
host_announce_servername:
|
|
.res 16
|
|
.byte $01 ;OS major version
|
|
.byte $64 ;OS minor version
|
|
.byte $03,$02,$0,$0 ;advertise as a workstation, server & print host
|
|
.byte $0F ;browser major version
|
|
.byte $01 ;browser minor version
|
|
.byte $55,$aa ;signature
|
|
.byte $0 ;host comment
|
|
host_announce_message_length=*-host_announce_message
|
|
|
|
|
|
netbios_name_query_response:
|
|
.byte $12,$34 ;transaction id
|
|
.byte $85,$00 ;flags: name query response, no error
|
|
.byte $00,$00 ;questions = 0
|
|
.byte $00,$01 ;answers = 1
|
|
.byte $00,$00 ;authority records = 0
|
|
.byte $00,$00 ;additional records = 0
|
|
.byte $20 ;
|
|
netbios_name_query_response_hostname:
|
|
.res 30 ;will be replaced with encoded hostname
|
|
.byte $43,$41 ;
|
|
.byte $00 ;
|
|
.byte $00,$20 ; type = NB
|
|
.byte $00,$01 ;class = IN
|
|
.byte $00,$00,$01,$40 ; TTL = 64 seconds
|
|
.byte $00,$06 ;data length
|
|
.byte $00,$00 ;FLAGS = B-NODE, UNIQUE NAME
|
|
netbios_name_query_response_ip:
|
|
.res 4 ;filled in with our IP
|
|
netbios_name_query_response_length=*-netbios_name_query_response
|
|
|
|
registration_request:
|
|
|
|
.byte $0c, $64 ;txn ID
|
|
.byte $29,$10 ;Registration Request opcode & flags
|
|
.byte $00,$01 ;questions = 1
|
|
.byte $00,$00 ;answers = 0
|
|
.byte $00,$00 ;authority records = 0
|
|
.byte $00,$01 ;additional records = 1
|
|
registration_request_servername:
|
|
;now WORKGROUP<00> encoded
|
|
.byte $20, $46, $48, $45, $50, $46, $43, $45, $4c, $45, $48, $46, $43, $45, $50, $46
|
|
.byte $46, $46, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $43, $41, $41, $41, $00
|
|
|
|
.byte $00,$20 ;question_type = NB
|
|
.byte $00,$01 ;question_class = IN
|
|
.byte $c0,$0c ;additional record name : ptr to string in QUESTION NAME
|
|
.byte $00,$20 ;question_type = NB
|
|
.byte $00,$01 ;question_class = IN
|
|
.byte $00,$00,$01,$40 ; TTL = 64 seconds
|
|
.byte $00,$06 ;data length
|
|
.byte $00,$00 ;FLAGS = B-NODE, UNIQUE NAME
|
|
|
|
.rodata
|
|
preferred_dialect_id: .byte "NT LM 0.12"
|
|
preferred_dialect_id_length=*-preferred_dialect_id
|
|
|
|
positive_session_response_packet:
|
|
.byte $82 ;packet type = Positive session response
|
|
.byte $00 ;flags
|
|
.byte $00, $00 ;message length
|
|
positive_session_response_packet_length=*-positive_session_response_packet
|
|
|
|
.data
|
|
|
|
cifs_cmd_buffer: .word DEFAULT_CIFS_CMD_BUFFER
|
|
|
|
smb_response_buffer: .word DEFAULT_SMB_RESPONSE_BUFFER
|
|
|
|
.bss
|
|
hostname_buffer: .res 33
|
|
|
|
|
|
local_hostname: .res 33
|
|
|
|
raw_local_hostname:
|
|
.res 16
|
|
|
|
hi_nibble: .res 1
|
|
|
|
connection_closed: .res 1
|
|
|
|
cifs_cmd_buffer_ptr: .res 2
|
|
cifs_cmd_length: .res 2
|
|
|
|
andx_opcode: .res 1
|
|
andx_ptr: .res 2 ;pointer to next 'AndX' command
|
|
andx_length: .res 2
|
|
smb_ptr: .res 2
|
|
smb_response_length: .res 2
|
|
|
|
|
|
; The contents of this file are subject to the Mozilla Public License
|
|
; Version 1.1 (the "License"); you may not use this file except in
|
|
; compliance with the License. You may obtain a copy of the License at
|
|
; http://www.mozilla.org/MPL/
|
|
;
|
|
; Software distributed under the License is distributed on an "AS IS"
|
|
; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
|
; License for the specific language governing rights and limitations
|
|
; under the License.
|
|
;
|
|
; The Original Code is ip65.
|
|
;
|
|
; The Initial Developer of the Original Code is Jonno Downes,
|
|
; jonno@jamtronix.com.
|
|
; Portions created by the Initial Developer are Copyright (C) 2009
|
|
; Jonno Downes. All Rights Reserved.
|
|
; -- LICENSE END --
|
|
|
|
</pre></body></html> |