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