kolibrios-fun/programs/network/pppoe/pppoe.asm
hidnplayr e4cf34c0de Merge new network stack with trunk
git-svn-id: svn://kolibrios.org@3545 a494cfbc-eb01-0410-851d-a64ba20cac60
2013-05-28 17:34:26 +00:00

363 lines
9.9 KiB
NASM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2012. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; pppoe.asm - PPPoE dialer for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format binary as ""
use32
db 'MENUET01' ; signature
dd 1 ; header version
dd start ; entry point
dd i_end ; initialized size
dd mem ; required memory
dd mem ; stack pointer
dd 0 ; parameters
dd 0 ; path
include '../macros.inc'
purge mov,add,sub
include '../proc32.inc'
include '../dll.inc'
include '../network.inc'
include '../struct.inc'
; Ethernet protocol numbers
ETHER_PPP_DISCOVERY = 0x6388
ETHER_PPP_SESSION = 0x6488
; PPP protocol numbers
PPP_LCP = 0x21c0 ; Link Configure Protocol
PPP_CBCP = 0x29c0 ; CallBack Control Protocol
PPP_PAP = 0x23c0 ; Password Authenication Protocol packet
PPP_CHAP = 0x23c2 ; Challenge Handshake Authentication Protocol
PPP_IPCP = 0x2180 ; Internet Protocol Configure Protocol (maybe this should be in kernel?)
PPP_CCP = 0xfd80 ; Compression Configure Protocol
; PPP Active Discovery...
PPPoE_PADI = 0x09 ; .. Initiation
PPPoE_PADO = 0x07 ; .. Offer
PPPoE_PADR = 0x19 ; .. Request
PPPoE_PADS = 0x65 ; .. Session-confirmation
PPPoE_PADT = 0xa7 ; .. Terminate
TAG_EOL = 0x0000
TAG_SERVICE_NAME= 0x0101
TAG_AC_NAME = 0x0201
TAG_HOST_UNIQ = 0x0301
TAG_AC_COOKIE = 0x0401
LCP_config_request = 1
LCP_config_ack = 2
LCP_config_nak = 3
LCP_config_reject = 4
LCP_terminate_request = 5
LCP_terminate_ack = 6
LCP_code_reject = 7
LCP_protocol_reject = 8
LCP_echo_request = 9
LCP_echo_reply = 10
LCP_discard_request = 11
struct ETH_frame
DestMac dp ?
SrcMac dp ?
Type dw ?
ends
struct PPPoE_frame ETH_frame
VersionAndType db ?
Code db ?
SessionID dw ?
Length dw ? ; Length of payload, does NOT include the length PPPoE header.
Payload rb 0
ends
struct PPP_frame PPPoE_frame
Protocol dw ?
ends
struct LCP_frame PPP_frame
LCP_Code db ?
LCP_Identifier db ?
LCP_Length dw ?
LCP_Data rb 0
ends
; entry point
start:
; load libraries
stdcall dll.Load, @IMPORT
test eax, eax
jnz exit
; initialize console
push 1
call [con_start]
push title
push 25
push 80
push 25
push 80
call [con_init]
main:
mcall 40, 1 shl 7
call [con_cls]
; Welcome user
push str1
call [con_write_asciiz]
mcall socket, 777, 3, 666
mov [socketnum], eax
mcall send, [socketnum], PADI, PADI.length, 0
mainloop:
mcall 10
call [con_get_flags]
test eax, 0x200 ; con window closed?
jnz close_conn
mcall recv, [socketnum], buffer, 4096
cmp eax, sizeof.PPPoE_frame
jb mainloop
cmp word [buffer + ETH_frame.Type], ETHER_PPP_SESSION
je SESSION_input
cmp word [buffer + ETH_frame.Type], ETHER_PPP_DISCOVERY
jne mainloop
cmp [buffer + PPPoE_frame.Code], PPPoE_PADO
je pado
cmp [buffer + PPPoE_frame.Code], PPPoE_PADS
je pads
cmp [buffer + PPPoE_frame.Code], PPPoE_PADT
je padt
jmp mainloop
pado:
push str2
call [con_write_asciiz]
lea esi, [buffer + ETH_frame.SrcMac] ; source mac -> dest mac
lea edi, [buffer + ETH_frame.DestMac]
movsw
movsd
mov byte [buffer + PPPoE_frame.Code], PPPoE_PADR ; change packet type to PADR
mov al, byte [buffer + PPPoE_frame.Length + 1] ; get packet size
mov ah, byte [buffer + PPPoE_frame.Length + 0]
movzx esi, ax
add esi, sizeof.PPPoE_frame
mcall send, [socketnum], buffer, , 0 ; now send it!
jmp mainloop
pads:
push str3
call [con_write_asciiz]
mov edx, dword [buffer + ETH_frame.SrcMac] ; source mac -> dest mac
mov si, word [buffer + ETH_frame.SrcMac + 4]
mov dword [PADT.mac], edx
mov word [PADT.mac + 4], si
mov cx, word [buffer + PPPoE_frame.SessionID] ; and Session ID
mov [PADT.sid], cx
mcall 76, API_PPPOE + 0 ; Start PPPoE session
jmp mainloop
padt:
push str4
call [con_write_asciiz]
mcall 76, API_PPPOE + 1 ; Stop PPPoE session
exit:
mcall close, [socketnum]
mcall -1
close_conn:
mcall send, [socketnum], PADT, PADT.length, 0
jmp exit
SESSION_input:
mov ax, word[buffer + PPP_frame.Protocol]
cmp ax, PPP_LCP
je LCP_input
cmp ax, PPP_CBCP
je CBCP_input
cmp ax, PPP_PAP
je PAP_input
cmp ax, PPP_CHAP
je CHAP_input
cmp ax, PPP_IPCP
je IPCP_input
cmp ax, PPP_CCP
je CCP_input
jmp mainloop
LCP_input:
stdcall con_write_asciiz, str_lcp
cmp [buffer + LCP_frame.LCP_Code], LCP_echo_request
je .echo
.dump:
jmp mainloop
.echo:
mov [buffer + LCP_frame.LCP_Code], LCP_echo_reply
lea esi, [buffer + ETH_frame.SrcMac] ; source mac -> dest mac
lea edi, [buffer + ETH_frame.DestMac]
movsw
movsd
mov esi, eax
mcall send, [socketnum], buffer, , 0 ; now send it back!
jmp mainloop
CBCP_input:
stdcall con_write_asciiz, str_cbcp
jmp mainloop
PAP_input:
stdcall con_write_asciiz, str_pap
jmp mainloop
CHAP_input:
stdcall con_write_asciiz, str_chap
jmp mainloop
IPCP_input:
stdcall con_write_asciiz, str_ipcp
jmp mainloop
CCP_input:
stdcall con_write_asciiz, str_ccp
jmp mainloop
; data
title db 'PPPoE',0
str1 db 'Sending PADI',13,10,0
str2 db 'Got PADO',13,10,'Sending PADR',13,10,0
str3 db 'Got PADS',13,10,'starting PPPoE session',13,10,0
str4 db 'Got PADT - connection terminated by Access Concentrator',13,10,0
str_lcp db 'Got LCP packet',13,10,0
str_cbcp db 'got CBCP packet',13,10,0
str_pap db 'got PAP packet',13,10,0
str_chap db 'got CHAP packet',13,10,0
str_ipcp db 'got IPCP packet',13,10,0
str_ccp db 'got CCP packet',13,10,0
PADI:
dp 0xffffffffffff ; dest mac: broadcast
dp 0 ; source mac (overwritten by kernel)
dw ETHER_PPP_DISCOVERY ; type
db 0x11 ; Version and Type
db PPPoE_PADI ; Code
dw 0 ; session ID
dw 20 shl 8 ; Payload Length
dw TAG_SERVICE_NAME ; tag
dw 0x0000 ; length
dw TAG_HOST_UNIQ ; tag
dw 0x0c00 ; length = 12 bytes
dd 0xdead ; some random id
dd 0xbeef
dd 0x1337
.length = $ - PADI
PADT:
.mac dp 0 ; Dest mac, to be filled in
dp 0 ; source mac (overwritten by kernel)
dw ETHER_PPP_DISCOVERY ; Type
db 0x11 ; Version and Type
db PPPoE_PADT ; Code: terminate connection
.sid dw 0 ; session id, to be filled in
dw 0 ; PAyload length = 0
.length = $ - PADT
; import
align 4
@IMPORT:
library console, 'console.obj'
import console, \
con_start, 'START', \
con_init, 'con_init', \
con_write_asciiz, 'con_write_asciiz', \
con_exit, 'con_exit', \
con_gets, 'con_gets',\
con_cls, 'con_cls',\
con_getch2, 'con_getch2',\
con_set_cursor_pos, 'con_set_cursor_pos',\
con_write_string, 'con_write_string',\
con_get_flags, 'con_get_flags'
i_end:
socketnum dd ?
buffer rb 4096
rb 4096 ; stack
mem: