Subversion Repositories Kolibri OS

Rev

Rev 3600 | Rev 3698 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2012. All rights reserved.      ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;  PPPoE.INC                                                   ;;
7
;;                                                              ;;
8
;;  Part of the tcp/ip network stack for KolibriOS              ;;
9
;;                                                              ;;
10
;;    Written by hidnplayr@kolibrios.org                        ;;
11
;;                                                              ;;
12
;;          GNU GENERAL PUBLIC LICENSE                          ;;
13
;;             Version 2, June 1991                             ;;
14
;;                                                              ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
17
struct  PPPoE_frame
18
        VersionAndType  db ?
19
        Code            db ?
20
        SessionID       dw ?
21
        Length          dw ?            ; Length of payload, does NOT include the length PPPoE header.
22
        Payload         rb 0
23
ends
24
 
25
uglobal
26
        PPPoE_SID       dw ?
27
        PPPoE_MAC       dp ?
28
endg
29
 
30
;-----------------------------------------------------------------
31
;
32
; PPPoE_init
33
;
34
;  This function resets all IP variables
35
;
36
;-----------------------------------------------------------------
37
macro   PPPoE_init {
38
 
39
        call    PPPoE_stop_connection
40
 
41
}
42
 
43
 
44
;-----------------------------------------------------------------
45
;
46
; PPPoE discovery input
47
;
48
; Handler of received Ethernet packet with type = Discovery
49
;
50
;
51
;  IN:  Pointer to buffer in [esp]
52
;       size of buffer in [esp+4]
53
;       pointer to device struct in ebx
54
;       pointer to PPP header in edx
55
;       size of PPP packet in ecx
56
;  OUT: /
57
;
58
;-----------------------------------------------------------------
59
align 4
60
PPPoE_discovery_input:
61
 
3556 hidnplayr 62
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_input\n"
3545 hidnplayr 63
 
64
; First, find open PPPoE socket
65
 
3647 hidnplayr 66
        pusha
67
        mov     ecx, socket_mutex
68
        call    mutex_lock
69
        popa
70
 
3545 hidnplayr 71
        mov     eax, net_sockets
72
 
73
  .next_socket:
74
        mov     eax, [eax + SOCKET.NextPtr]
75
        or      eax, eax
76
        jz      .dump
77
 
78
        cmp     [eax + SOCKET.Domain], AF_PPP
79
        jne     .next_socket
80
 
81
        cmp     [eax + SOCKET.Protocol], PPP_PROTO_ETHERNET
82
        jne     .next_socket
83
 
3647 hidnplayr 84
        pusha
85
        mov     ecx, socket_mutex
86
        call    mutex_unlock
87
        popa
88
 
3545 hidnplayr 89
; Now, send it to the this socket
90
 
91
        mov     ecx, [esp + 4]
92
        mov     esi, [esp]
93
 
94
        jmp     SOCKET_input
95
 
96
  .dump:
3647 hidnplayr 97
        pusha
98
        mov     ecx, socket_mutex
99
        call    mutex_unlock
100
        popa
101
 
3556 hidnplayr 102
        DEBUGF  DEBUG_NETWORK_VERBOSE, 'PPPoE_discovery_input: dumping\n'
3545 hidnplayr 103
        call    kernel_free
104
        add     esp, 4
105
        ret
106
 
107
 
108
;--------------------------------------
109
;
110
; Send discovery packet
111
;
112
; IN: eax = socket pointer
113
;     ecx = number of bytes to send
114
;     esi = pointer to data
115
;
116
;--------------------------------------
117
 
118
align 4
119
PPPoE_discovery_output:
120
 
3556 hidnplayr 121
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_output: socket=%x buffer=%x size=%d\n", eax, esi, ecx
3545 hidnplayr 122
 
123
; RFC2516: An entire PADI packet (including the PPPoE header) MUST NOT
124
; exceed 1484 octets.
125
        cmp     ecx, 1484 + 14
126
        ja      .bad
127
 
128
; Check that device exists and is ethernet device
129
        mov     ebx, [eax + SOCKET.device]
130
 
3600 hidnplayr 131
        cmp     ebx, NET_DEVICES_MAX
3545 hidnplayr 132
        ja      .bad
133
 
134
        mov     ebx, [NET_DRV_LIST + 4*ebx]
135
        test    ebx, ebx
136
        jz      .bad
137
 
3600 hidnplayr 138
        cmp     [ebx + NET_DEVICE.device_type], NET_DEVICE_ETH
3545 hidnplayr 139
        jne     .bad
140
 
3556 hidnplayr 141
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_output: device=%x\n", ebx
3545 hidnplayr 142
 
143
; Create packet.
144
        push    ecx esi
145
        stdcall kernel_alloc, 1500
146
        pop     esi ecx
147
        test    eax, eax
148
        jz      .bad
149
 
150
        mov     edx, ecx
151
        mov     edi, eax
152
        rep     movsb
153
 
154
        cmp     edx, 60         ; Min ETH size
155
        ja      @f
156
        mov     edx, 60
157
       @@:
158
 
159
        push    edx eax         ; size and packet ptr for driver send proc
160
 
161
; Overwrite source MAC and protocol type
162
        lea     edi, [eax + ETH_header.SrcMAC]
163
        lea     esi, [ebx + ETH_DEVICE.mac]
164
        movsd
165
        movsw
3600 hidnplayr 166
        cmp     word[edi], ETHER_PROTO_PPP_SESSION      ; Allow only PPP_discovery, or LCP
3545 hidnplayr 167
        je      @f
3600 hidnplayr 168
        mov     ax, ETHER_PROTO_PPP_DISCOVERY
3545 hidnplayr 169
        stosw
170
       @@:
171
 
172
; And send the packet
173
        call    [ebx + NET_DEVICE.transmit]
174
 
175
        xor     eax, eax
176
        ret
177
 
178
  .bad:
179
        or      eax, -1
180
        ret
181
 
182
 
183
;-----------------------------------------------------------------
184
;
185
; PPPoE session input
186
;
187
; Handler of received Ethernet packet with type = Session
188
;
189
;
190
;  IN:  Pointer to buffer in [esp]
191
;       size of buffer in [esp+4]
192
;       pointer to device struct in ebx
193
;       pointer to PPP header in edx
194
;       size of PPP packet in ecx
195
;  OUT: /
196
;
197
;-----------------------------------------------------------------
198
align 4
199
PPPoE_session_input:
200
 
201
        cmp     [edx + PPPoE_frame.VersionAndType], 0x11
202
        jne     .dump
203
 
204
        cmp     [edx + PPPoE_frame.Code], 0x00
205
        jne     .dump
206
 
207
        movzx   ecx, [edx + PPPoE_frame.Length]
208
        xchg    cl, ch
209
 
210
        mov     ax, [edx + PPPoE_frame.SessionID]
3556 hidnplayr 211
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_input: session ID=%x, length=%u\n", ax, cx
3545 hidnplayr 212
        cmp     ax, [PPPoE_SID]
213
        jne     .dump
214
 
215
        mov     ax, word [edx + PPPoE_frame.Payload]
216
        add     edx, PPPoE_frame.Payload + 2
217
 
3600 hidnplayr 218
        cmp     ax, PPP_PROTO_IPv4
3545 hidnplayr 219
        je      IPv4_input
220
 
3600 hidnplayr 221
;        cmp     ax, PPP_PROTO_IPv6
3545 hidnplayr 222
;        je      IPv6_input
223
 
224
        jmp     PPPoE_discovery_input   ; Send LCP,CHAP,CBCP,... packets to the PPP dialer
3556 hidnplayr 225
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_input: Unknown protocol=%x\n", ax
3545 hidnplayr 226
 
227
  .dump:
3556 hidnplayr 228
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_input: dumping\n"
3545 hidnplayr 229
        call    kernel_free
230
        add     esp, 4
231
        ret
232
 
233
 
234
 
235
 
236
;-----------------------------------------------------------------
237
;
238
; PPPoE_output
239
;
240
; IN:
241
;     ebx = device ptr
242
;     ecx = packet size
243
;
244
;      di = protocol
245
;
246
; OUT: edi = 0 on error, pointer to buffer otherwise
247
;      eax = buffer start
248
;      ebx = to device structure
249
;      ecx = unchanged (packet size of embedded data)
250
;      edx = size of complete buffer
251
;
252
;-----------------------------------------------------------------
253
align 4
254
PPPoE_output:
255
 
3556 hidnplayr 256
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_output: size=%u device=%x\n", ecx, ebx
3545 hidnplayr 257
 
258
        pushw   di
259
        pushw   [PPPoE_SID]
260
 
261
        lea     eax, [ebx + ETH_DEVICE.mac]
262
        lea     edx, [PPPoE_MAC]
263
        add     ecx, PPPoE_frame.Payload + 2
3600 hidnplayr 264
        mov     di, ETHER_PROTO_PPP_SESSION
3545 hidnplayr 265
        call    ETH_output
266
        jz      .eth_error
267
 
268
        sub     ecx, PPPoE_frame.Payload
269
        mov     [edi + PPPoE_frame.VersionAndType], 0x11
270
        mov     [edi + PPPoE_frame.Code], 0
271
        popw    [edi + PPPoE_frame.SessionID]
272
        xchg    cl, ch
273
        mov     [edi + PPPoE_frame.Length], cx
274
        xchg    cl, ch
275
 
276
        pop     word [edi + PPPoE_frame.Payload]
277
 
278
        sub     ecx, 2
279
        add     edi, PPPoE_frame.Payload + 2
280
 
3556 hidnplayr 281
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_output: success!\n"
3545 hidnplayr 282
        ret
283
 
284
 
285
  .eth_error:
286
        add     esp, 4
287
        xor     edi, edi
288
 
289
        ret
290
 
291
 
292
PPPoE_start_connection:
293
 
3556 hidnplayr 294
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_start_connection: %x\n", cx
3545 hidnplayr 295
 
296
        cmp     [PPPoE_SID], 0
297
        jne     .fail
298
 
299
        mov     [PPPoE_SID], cx
300
        mov     dword [PPPoE_MAC], edx
301
        mov     word [PPPoE_MAC + 4], si
302
 
303
        xor     eax, eax
304
        ret
305
 
306
  .fail:
307
        or      eax, -1
308
        ret
309
 
310
 
311
align 4
312
PPPoE_stop_connection:
313
 
3556 hidnplayr 314
        DEBUGF  DEBUG_NETWORK_VERBOSE, "PPPoE_stop_connection\n"
3545 hidnplayr 315
 
316
        xor     eax, eax
317
        mov     [PPPoE_SID], ax
318
        mov     dword [PPPoE_MAC], eax
319
        mov     word [PPPoE_MAC + 4], ax
320
 
321
        ret
322
 
323
 
324
;---------------------------------------------------------------------------
325
;
326
; PPPoE API
327
;
328
; This function is called by system function 75
329
;
330
; IN:  subfunction number in bl
331
;      device number in bh
332
;      ecx, edx, .. depends on subfunction
333
;
334
; OUT:
335
;
336
;---------------------------------------------------------------------------
337
align 4
338
PPPoE_api:
339
 
340
        movzx   eax, bh
341
        shl     eax, 2
342
 
343
        and     ebx, 0xff
344
        cmp     ebx, .number
345
        ja      .error
346
        jmp     dword [.table + 4*ebx]
347
 
348
  .table:
349
        dd      PPPoE_start_connection  ; 0
350
        dd      PPPoE_stop_connection   ; 1
351
  .number = ($ - .table) / 4 - 1
352
 
353
  .error:
354
        mov     eax, -1
355
        ret