Subversion Repositories Kolibri OS

Rev

Rev 2614 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2614 Rev 2931
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2009-2012. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2012. All rights reserved.      ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
-
 
6
;;  PPPoE.INC                                                   ;;
6
;; Clevermouse & hidnplayr                                      ;;
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                             ;;
7
;;                                                              ;;
14
;;                                                              ;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 9... Line -...
9
 
-
 
10
 
16
 
Line 11... Line 17...
11
struct  PPPoE_header
17
struct  PPPoE_frame
12
 
18
 
13
        VersionAndType  db ?
19
        VersionAndType  db ?
14
        Code            db ?
20
        Code            db ?
-
 
21
        SessionID       dw ?
Line 15... Line 22...
15
        SessionID       dw ?
22
        Length          dw ?            ; Length of payload, does NOT include the length PPPoE header.
Line 16... Line -...
16
        Length          dw ?            ; Length of payload, does NOT include the length PPPoE header.
-
 
17
 
-
 
18
ends
-
 
19
 
-
 
20
struct  PPPoE_connection
-
 
21
 
-
 
22
        next            dd ?            ; pointer to next connection
-
 
23
        prev            dd ?            ; pointer to previous connection
-
 
24
 
-
 
25
        pid             dd ?            ; identifier of base application
-
 
Line 26... Line 23...
26
 
23
        Payload         rb 0
Line 27... Line -...
27
        datalen         dd ?            ; length of received data
-
 
28
        recvbuf         rb 1500         ; buffer for received data
-
 
29
        sendbuf         rb 1500         ; buffer for data to send
24
 
30
 
25
ends
31
ends
-
 
Line 32... Line -...
32
 
-
 
33
iglobal
-
 
34
align 4
-
 
35
        PPPoE.head              dd PPPoE.head
-
 
36
        PPPoE.tail              dd PPPoE.head
26
 
Line -... Line 27...
-
 
27
 
-
 
28
uglobal
-
 
29
 
-
 
30
        PPPoE_SID       dw ?
37
endg
31
        PPPoE_MAC       dp ?
-
 
32
 
-
 
33
endg
-
 
34
 
-
 
35
 
-
 
36
;-----------------------------------------------------------------
-
 
37
;
-
 
38
; PPPoE discovery input
-
 
39
;
-
 
40
; Handler of received Ethernet packet with type = Discovery
-
 
41
;
38
 
42
;
39
uglobal
43
;  IN:  Pointer to buffer in [esp]
Line 40... Line -...
40
        PPPoE.cur_receiver      dd ?
-
 
41
        PPPoE.cur_receiver_ptr  dd ?
44
;       size of buffer in [esp+4]
Line 42... Line -...
42
        PPPoE.cur_receiver_len  dd ?
-
 
43
endg
-
 
44
 
45
;       pointer to device struct in ebx
Line 45... Line -...
45
 
-
 
46
; Allocates internal structure for future PPPoE actions.
-
 
47
align 4
-
 
48
PPPoE_alloc_connection:
-
 
49
 
-
 
50
; 1. Allocate memory in the kernel area.
-
 
51
        stdcall kernel_alloc, sizeof.PPPoE_connection
46
;       pointer to PPP header in edx
52
 
-
 
53
; 1a. If memory allocation failed, return NULL.
-
 
54
        test    eax, eax
-
 
Line 55... Line 47...
55
        jz      .nothing
47
;       size of PPP packet in ecx
-
 
48
;  OUT: /
56
 
49
;
-
 
50
;-----------------------------------------------------------------
Line -... Line 51...
-
 
51
align 4
-
 
52
PPPoE_discovery_input:
Line 57... Line -...
57
; 2. Copy PID of caller to the structure.
-
 
-
 
53
 
58
        mov     edx, [CURRENT_TASK]
54
        DEBUGF  2,"PPPoE_discovery_input\n"
Line 59... Line -...
59
        mov     [eax + PPPoE_connection.pid], edx
-
 
60
 
-
 
61
; 3. Insert the structure to the list of all connections.
-
 
62
        mov     [eax + PPPoE_connection.next], PPPoE.head
55
 
63
        mov     edx, [PPPoE.tail]
-
 
64
        mov     [eax + PPPoE_connection.prev], edx
-
 
65
        mov     [edx + PPPoE_connection.next], eax
-
 
66
        mov     [PPPoE.tail], eax
-
 
67
 
-
 
68
  .nothing:
-
 
Line 69... Line 56...
69
        ret
56
; First, find open PPPoE socket
70
 
57
 
Line 71... Line -...
71
 
-
 
72
align 4
58
        mov     eax, net_sockets
Line -... Line 59...
-
 
59
 
-
 
60
  .next_socket:
-
 
61
        mov     eax, [eax + SOCKET.NextPtr]
-
 
62
        or      eax, eax
-
 
63
        jz      .dump
Line 73... Line -...
73
PPPoE_free_connection:
-
 
Line -... Line 64...
-
 
64
 
-
 
65
        cmp     [eax + SOCKET.Domain], AF_PPP
-
 
66
        jne     .next_socket
-
 
67
 
74
 
68
        cmp     [eax + SOCKET.Protocol], PPP_PROTO_ETHERNET
75
; 1. Check that the caller is the owner of this connection.
69
        jne     .next_socket
76
        mov     eax, [CURRENT_TASK]
70
 
-
 
71
; Now, send it to the this socket
77
        cmp     [ebx+PPPoE_connection.pid], eax
72
 
78
        jnz     .nothing
73
        mov     ecx, [esp + 4]
79
 
74
        mov     esi, [esp]
80
; 2. Delete the structure from the list of all connections.
-
 
81
        mov     eax, [ebx+PPPoE_connection.next]
-
 
82
        mov     edx, [ebx+PPPoE_connection.prev]
-
 
83
        mov     [eax+PPPoE_connection.prev], edx
-
 
Line 84... Line 75...
84
        mov     [edx+PPPoE_connection.next], eax
75
 
85
 
76
        jmp     SOCKET_input
86
; 3. Free the memory.
-
 
87
        stdcall kernel_free, ebx
77
 
88
 
78
  .dump:
Line 89... Line 79...
89
  .nothing:
79
        DEBUGF 1,'PPPoE_discovery_input: dumping\n'
90
        ret
80
        call    kernel_free
91
 
81
        add     esp, 4
92
 
-
 
93
; Send PADI packet
-
 
94
 
-
 
95
; ebx (ecx in app) = size of buffer for PPPoE offers, must be at least 1514
-
 
96
; ecx (edx in app) = size of tags, 0 means "use default"
-
 
97
; edx (esi in app) = pointer to buffer for PPPoE offers
-
 
98
; esi (edi in app) = pointer to tags, ignored if 'size of tags' == 0
-
 
99
align 4
-
 
100
PPPoE_send_init:
-
 
101
 
-
 
102
; 1. Check length.
-
 
103
        cmp     ebi, 1514
-
 
104
        jb      .bad
-
 
105
 
-
 
106
; RFC2516: An entire PADI packet (including the PPPoE header) MUST NOT
-
 
107
; exceed 1484 octets.
-
 
108
; PPPoE header is 6 bytes long, so maximum length of tags is 1478.
-
 
109
        cmp     ecx, 1478
-
 
110
        ja      .bad
-
 
111
 
-
 
112
; 2. Check that no one listen for offers.
-
 
113
        cmp     [PPPoE.cur_receiver], 0
-
 
Line -... Line 82...
-
 
82
        ret
114
        jnz     .bad
83
 
-
 
84
 
Line 115... Line 85...
115
 
85
;--------------------------------------
116
; 3. Remember PID and data pointer of current listener.
86
;
Line 117... Line 87...
117
        push    [CURRENT_TASK]
87
; Send discovery packet
-
 
88
;
118
        pop     [PPPoE.cur_receiver]
89
; ebx (ecx in app) = device
119
        mov     [PPPoE.cur_receiver_ptr], edx
90
; ecx (edx in app) = size packet
Line 120... Line 91...
120
        mov     [PPPoE.cur_receiver_len], ebx
91
; edx (esi in app) = pointer to packet
-
 
92
;
-
 
93
;--------------------------------------
121
        and     dword [edx], 0 ; no offers yet
94
align 4
Line -... Line 95...
-
 
95
PPPoE_discovery_output:
-
 
96
 
-
 
97
; RFC2516: An entire PADI packet (including the PPPoE header) MUST NOT
-
 
98
; exceed 1484 octets.
-
 
99
        cmp     ecx, 1484 + 14
-
 
100
        ja      .bad
-
 
101
 
-
 
102
; Check that device exists and is ethernet device
122
 
103
        cmp     ebx, MAX_NET_DEVICES
123
; 4. Create packet.
104
        ja      .bad
124
        test    ecx, ecx
105
 
125
        jnz     @f
106
        mov     ebx, [NET_DRV_LIST + 4*ebx]
126
        mov     esi, .default_payload
107
        test    ebx, ebx
Line 127... Line 108...
127
        mov     ecx, .default_payload_length
108
        jz      .bad
128
       @@:
109
 
129
 
110
        cmp     [ebx + NET_DEVICE.type], NET_TYPE_ETH
Line 130... Line -...
130
        mov     edx, [NET_DRV_LIST]     ;;;; FIXME
-
 
131
        lea     eax, [ebx + ETH_DEVICE.mac]     ; Source Address
-
 
132
        mov     edx, ETH_BROADCAST              ; Destination Address
-
 
133
        add     ecx, sizeof.PPPoE_header        ; Data size
-
 
134
        mov     di, ETHER_PPP_DISCOVERY         ; Protocol
-
 
Line -... Line 111...
-
 
111
        jne     .bad
-
 
112
 
-
 
113
; Create packet.
-
 
114
        stdcall kernel_alloc, 1500
-
 
115
        test    eax, eax
-
 
116
        jz      .bad
-
 
117
 
-
 
118
        push    ecx eax
-
 
119
 
-
 
120
        mov     edi, eax
-
 
121
        rep     movsb
135
        call    ETH_output
122
 
-
 
123
; Overwrite source MAC and protocol type
-
 
124
        lea     edi, [eax + ETH_header.SrcMAC]
-
 
125
        lea     esi, [ebx + ETH_DEVICE.mac]
136
        jz      .eth_error
126
        movsd
137
 
127
        movsw
Line 138... Line -...
138
        push    edx eax
-
 
139
 
-
 
140
; 4b. Set ver=1, type=1 (=> first byte 0x11), code=9 (PADI packet), session=0
128
        mov     ax, ETHER_PPP_DISCOVERY
141
        mov     dword [edi], (0x09 shl 8) + 0x11
129
        stosw
142
 
-
 
143
; 4c. Set payload length.
-
 
144
        mov     [edi+4], ch
-
 
145
        mov     [edi+5], cl
-
 
Line 146... Line -...
146
 
-
 
147
; 4e. Copy given tags.
130
 
148
        rep     movsb
131
; And send the packet
Line 149... Line 132...
149
 
132
        call    [ebx + NET_DEVICE.transmit]
150
; 5. Send packet.
-
 
151
        call    [ebx + NET_DEVICE.transmit]
-
 
152
; 6. Return.
133
 
Line -... Line 134...
-
 
134
        xor     eax, eax
-
 
135
        ret
-
 
136
 
-
 
137
  .bad:
-
 
138
        or      eax, -1
-
 
139
        ret
-
 
140
 
-
 
141
 
-
 
142
;-----------------------------------------------------------------
-
 
143
;
-
 
144
; PPPoE session input
153
        xor     eax, eax
145
;
-
 
146
; Handler of received Ethernet packet with type = Session
154
        ret
147
;
-
 
148
;
155
 
149
;  IN:  Pointer to buffer in [esp]
-
 
150
;       size of buffer in [esp+4]
156
  .bad:
151
;       pointer to device struct in ebx
Line -... Line 152...
-
 
152
;       pointer to PPP header in edx
157
        or      eax, -1
153
;       size of PPP packet in ecx
158
        ret
154
;  OUT: /
159
 
155
;
160
  .default_payload:
156
;-----------------------------------------------------------------
-
 
157
align 4
-
 
158
PPPoE_session_input:
161
; Service-Name tag with zero length
159
 
162
        dw      0x0101, 0x0000
160
        cmp     [edx + PPPoE_frame.VersionAndType], 0x11
-
 
161
        jne     .dump
163
  .default_payload_length = $ - .default_payload
162
 
164
 
163
        cmp     [edx + PPPoE_frame.Code], 0x00
165
 
164
        jne     .dump
166
; Stop receiving PADO packets
165
 
167
align 4
166
        movzx   ecx, [edx + PPPoE_frame.Length]
168
PPPoE_stop_offers:
167
        xchg    cl, ch
169
 
-
 
170
; Only the listener can stop listen.    ;;; TODO: make sure this function is called when process gets terminated
168
 
171
        mov     eax, [CURRENT_TASK]
169
        mov     ax, [edx + PPPoE_frame.SessionID]
172
        cmp     [PPPoE.cur_receiver], eax
170
        DEBUGF  2,"PPPoE_input: session ID=%x, length=%u\n", ax, cx
173
        jnz     .bad
171
        cmp     ax, [PPPoE_SID]
Line 174... Line -...
174
        xor     eax, eax
-
 
175
        mov     [PPPoE.cur_receiver_ptr], eax
-
 
176
        mov     [PPPoE.cur_receiver], eax
-
 
177
        ret
-
 
178
 
-
 
179
  .bad:
172
        jne     .dump
180
        or      eax, -1
-
 
181
        ret
-
 
182
 
-
 
183
; Send PPPoE data in Discovery stage
-
 
184
align 4
-
 
185
PPPoE_send_discovery:
-
 
186
        ret
-
 
187
 
-
 
188
; Receive PPPoE data in Discovery stage
-
 
189
align 4
-
 
190
PPPoE_receive_discovery:
-
 
Line 191... Line 173...
191
        ret
173
 
192
 
174
        mov     ax, word [edx + PPPoE_frame.Payload]
Line 193... Line 175...
193
 
175
        add     edx, PPPoE_frame.Payload + 2
-
 
176
 
194
 
177
        cmp     ax, PPP_IPv4
-
 
178
        je      IPv4_input
-
 
179
 
195
;-----------------------------------------------------------------
180
        DEBUGF  2,"PPPoE_input: Unknown protocol=%x\n", ax
Line -... Line 181...
-
 
181
 
-
 
182
  .dump:
-
 
183
        DEBUGF  2,"PPPoE_input: dumping\n"
-
 
184
        call    kernel_free
-
 
185
        add     esp, 4
-
 
186
        ret
196
;
187
 
Line -... Line 188...
-
 
188
 
-
 
189
 
-
 
190
 
-
 
191
;-----------------------------------------------------------------
197
; PPPoE discovery input
192
;
-
 
193
; PPPoE_output
-
 
194
;
-
 
195
; IN:
-
 
196
;     ebx = device ptr
-
 
197
;     ecx = packet size
Line 198... Line -...
198
;
-
 
199
; Handler of received Ethernet packet with type = Discovery
-
 
200
;
-
 
201
;
-
 
202
;  IN:  Pointer to buffer in [esp]
198
;
Line -... Line 199...
-
 
199
;      di = protocol
-
 
200
;
-
 
201
; OUT: edi = 0 on error, pointer to buffer otherwise
-
 
202
;      eax = buffer start
-
 
203
;      ebx = to device structure
-
 
204
;      ecx = unchanged (packet size of embedded data)
-
 
205
;      edx = size of complete buffer
-
 
206
;
-
 
207
;-----------------------------------------------------------------
-
 
208
align 4
-
 
209
PPPoE_output:
-
 
210
 
-
 
211
        DEBUGF  1,"PPPoE_output: size=%u device=%x\n", ecx, ebx
-
 
212
 
-
 
213
        pushw   di
-
 
214
        pushw   [PPPoE_SID]
-
 
215
 
-
 
216
        lea     eax, [ebx + ETH_DEVICE.mac]
-
 
217
        lea     edx, [PPPoE_MAC]
-
 
218
        add     ecx, PPPoE_frame.Payload + 2
-
 
219
        mov     di, ETHER_PPP_SESSION
-
 
220
        call    ETH_output
-
 
221
        jz      .eth_error
-
 
222
 
-
 
223
        mov     [edi + PPPoE_frame.VersionAndType], 0x11
-
 
224
        mov     [edi + PPPoE_frame.Code], 0
-
 
225
        popw    [edi + PPPoE_frame.SessionID]
-
 
226
        xchg    cl, ch
Line 203... Line 227...
203
;       size of buffer in [esp+4]
227
        mov     [edi + PPPoE_frame.Length], cx
204
;       pointer to device struct in ebx
228
        xchg    cl, ch
205
;       pointer to PPP header in edx
229
        pop     word [edi + PPPoE_frame.Payload]
206
;       size of PPP packet in ecx
230
 
Line 271... Line 295...
271
        cmp     ebx, .number
295
        cmp     ebx, .number
272
        ja      .error
296
        ja      .error
273
        jmp     dword [.table + 4*ebx]
297
        jmp     dword [.table + 4*ebx]
Line 274... Line 298...
274
 
298
 
275
  .table:
-
 
276
        dd      PPPoE_send_init         ; 0
-
 
277
        dd      PPPoE_stop_offers       ; 1
299
  .table:
278
        dd      PPPoE_alloc_connection  ; 3
300
        dd      PPPoE_start_connection  ; 0
279
        dd      PPPoE_free_connection   ; 4
-
 
280
        dd      PPPoE_send_discovery    ; 5
-
 
281
        dd      PPPoE_receive_discovery ; 6
301
        dd      PPPoE_stop_connection   ; 1
Line 282... Line 302...
282
  .number = ($ - .table) / 4 - 1
302
  .number = ($ - .table) / 4 - 1
283
 
303
 
284
  .error:
304
  .error: