Subversion Repositories Kolibri OS

Rev

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

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