;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2012-2015. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; PPPoE.INC ;; ;; ;; ;; Part of the tcp/ip network stack for KolibriOS ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $Revision$ struct PPPoE_frame VersionAndType db ? Code db ? SessionID dw ? Length dw ? ; Length of payload, does NOT include the length PPPoE header. Payload rb 0 ends uglobal align 4 PPPoE_SID dw ? PPPoE_MAC dp ? endg ;-----------------------------------------------------------------; ; ; ; pppoe_init: Reset all pppoe variables ; ; ; ;-----------------------------------------------------------------; macro pppoe_init { call pppoe_stop_connection } ;-----------------------------------------------------------------; ; ; ; pppoe_discovery_input ; ; ; ; IN: [esp] = ptr to buffer ; ; [esp+4] = size of buffer ; ; ebx = ptr to device struct ; ; ecx = size of PPP packet ; ; edx = ptr to PPP header ; ; ; ; OUT: / ; ; ; ;-----------------------------------------------------------------; align 4 pppoe_discovery_input: DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_input\n" ; First, find open PPPoE socket pusha mov ecx, socket_mutex call mutex_lock popa mov eax, net_sockets .next_socket: mov eax, [eax + SOCKET.NextPtr] or eax, eax jz .dump cmp [eax + SOCKET.Domain], AF_PPP jne .next_socket cmp [eax + SOCKET.Protocol], PPP_PROTO_ETHERNET jne .next_socket pusha mov ecx, socket_mutex call mutex_unlock popa ; Now, send it to the this socket mov ecx, [esp + 4] mov esi, [esp] jmp socket_input .dump: pusha mov ecx, socket_mutex call mutex_unlock popa DEBUGF DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n' call net_buff_free ret ;-----------------------------------------------------------------; ; ; ; pppoe_discovery_output ; ; ; ; IN: eax = socket pointer ; ; ecx = number of bytes to send ; ; esi = pointer to data ; ; ; ;-----------------------------------------------------------------; align 4 pppoe_discovery_output: DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_output: socket=%x buffer=%x size=%d\n", eax, esi, ecx ; RFC2516: An entire PADI packet (including the PPPoE header) MUST NOT ; exceed 1484 octets. cmp ecx, 1484 + 14 ja .bad ; Check that device exists and is ethernet device mov ebx, [eax + SOCKET.device] cmp ebx, NET_DEVICES_MAX ja .bad mov ebx, [NET_DRV_LIST + 4*ebx] test ebx, ebx jz .bad cmp [ebx + NET_DEVICE.device_type], NET_DEVICE_ETH jne .bad DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_output: device=%x\n", ebx ; Create packet. push ecx esi ;;;; FIXME stdcall kernel_alloc, 1500 pop esi ecx test eax, eax jz .bad mov edx, ecx mov edi, eax rep movsb cmp edx, 60 ; Min ETH size ja @f mov edx, 60 @@: push edx eax ; size and packet ptr for driver send proc ; Overwrite source MAC and protocol type lea edi, [eax + ETH_header.SrcMAC] lea esi, [ebx + ETH_DEVICE.mac] movsd movsw cmp word[edi], ETHER_PROTO_PPP_SESSION ; Allow only PPP_discovery, or LCP je @f mov ax, ETHER_PROTO_PPP_DISCOVERY stosw @@: ; And send the packet call [ebx + NET_DEVICE.transmit] xor eax, eax ret .bad: or eax, -1 ret ;-----------------------------------------------------------------; ; ; ; pppoe_session_input ; ; ; ; IN: [esp] = ptr to buffer ; ; [esp+4] = size of buffer ; ; ebx = ptr to device struct ; ; edx = ptr to PPP header ; ; ecx = size of PPP packet ; ; ; ; OUT: / ; ; ; ;-----------------------------------------------------------------; align 4 pppoe_session_input: cmp [edx + PPPoE_frame.VersionAndType], 0x11 jne .dump cmp [edx + PPPoE_frame.Code], 0x00 jne .dump movzx ecx, [edx + PPPoE_frame.Length] xchg cl, ch mov ax, [edx + PPPoE_frame.SessionID] DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: session ID=%x, length=%u\n", ax, cx cmp ax, [PPPoE_SID] jne .dump mov ax, word [edx + PPPoE_frame.Payload] add edx, PPPoE_frame.Payload + 2 cmp ax, PPP_PROTO_IPv4 je ipv4_input ; cmp ax, PPP_PROTO_IPv6 ; je ipv6_input jmp pppoe_discovery_input ; Send LCP,CHAP,CBCP,... packets to the PPP dialer DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: Unknown protocol=%x\n", ax .dump: DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_input: dumping\n" call net_buff_free ret ;-----------------------------------------------------------------; ; ; ; pppoe_output ; ; ; ; IN: ax = protocol ; ; ebx = device ptr ; ; ecx = packet size ; ; ; ; OUT: eax = buffer start ; ; eax = 0 on error ; ; ebx = device ptr ; ; ecx = packet size ; ; edx = size of complete buffer ; ; edi = start of PPP payload ; ; ; ;-----------------------------------------------------------------; align 4 pppoe_output: DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx pushw ax pushw [PPPoE_SID] mov ax, ETHER_PROTO_PPP_SESSION add ecx, PPPoE_frame.Payload + 2 lea edx, [PPPoE_MAC] call eth_output jz .eth_error sub ecx, PPPoE_frame.Payload mov [edi + PPPoE_frame.VersionAndType], 0x11 mov [edi + PPPoE_frame.Code], 0 popw [edi + PPPoE_frame.SessionID] xchg cl, ch mov [edi + PPPoE_frame.Length], cx xchg cl, ch pop word [edi + PPPoE_frame.Payload] sub ecx, 2 add edi, PPPoE_frame.Payload + 2 DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_output: success!\n" ret .eth_error: add esp, 4 xor eax, eax ret align 4 pppoe_start_connection: DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_start_connection: %x\n", cx cmp [PPPoE_SID], 0 jne .fail mov [PPPoE_SID], cx mov dword [PPPoE_MAC], edx mov word [PPPoE_MAC + 4], si xor eax, eax ret .fail: or eax, -1 ret align 4 pppoe_stop_connection: DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_stop_connection\n" xor eax, eax mov [PPPoE_SID], ax mov dword [PPPoE_MAC], eax mov word [PPPoE_MAC + 4], ax ret ;-----------------------------------------------------------------; ; ; ; pppoe_api: Part of system function 76 ; ; ; ; IN: subfunction number in bl ; ; device number in bh ; ; ecx, edx, .. depends on subfunction ; ; ; ; OUT: ; ; ; ;-----------------------------------------------------------------; align 4 pppoe_api: movzx eax, bh shl eax, 2 and ebx, 0xff cmp ebx, .number ja .error jmp dword [.table + 4*ebx] .table: dd pppoe_start_connection ; 0 dd pppoe_stop_connection ; 1 .number = ($ - .table) / 4 - 1 .error: mov eax, -1 ret