;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2010-2013. 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, 0 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: