Details | 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 | |||
2964 | hidnplayr | 206 | ; cmp ax, PPP_IPv6 |
207 | ; je IPv6_input |
||
2961 | hidnplayr | 208 | |
2964 | hidnplayr | 209 | jmp PPPoE_discovery_input ; Send LCP,CHAP,CBCP,... packets to the PPP dialer |
2931 | hidnplayr | 210 | DEBUGF 2,"PPPoE_input: Unknown protocol=%x\n", ax |
211 | |||
212 | .dump: |
||
213 | DEBUGF 2,"PPPoE_input: dumping\n" |
||
214 | call kernel_free |
||
215 | add esp, 4 |
||
2614 | hidnplayr | 216 | ret |
217 | |||
218 | |||
219 | |||
2931 | hidnplayr | 220 | |
2614 | hidnplayr | 221 | ;----------------------------------------------------------------- |
222 | ; |
||
2931 | hidnplayr | 223 | ; PPPoE_output |
2614 | hidnplayr | 224 | ; |
2931 | hidnplayr | 225 | ; IN: |
226 | ; ebx = device ptr |
||
227 | ; ecx = packet size |
||
2614 | hidnplayr | 228 | ; |
2931 | hidnplayr | 229 | ; di = protocol |
2614 | hidnplayr | 230 | ; |
2931 | hidnplayr | 231 | ; OUT: edi = 0 on error, pointer to buffer otherwise |
232 | ; eax = buffer start |
||
233 | ; ebx = to device structure |
||
234 | ; ecx = unchanged (packet size of embedded data) |
||
235 | ; edx = size of complete buffer |
||
2614 | hidnplayr | 236 | ; |
237 | ;----------------------------------------------------------------- |
||
238 | align 4 |
||
2931 | hidnplayr | 239 | PPPoE_output: |
2614 | hidnplayr | 240 | |
2931 | hidnplayr | 241 | DEBUGF 1,"PPPoE_output: size=%u device=%x\n", ecx, ebx |
2614 | hidnplayr | 242 | |
2931 | hidnplayr | 243 | pushw di |
244 | pushw [PPPoE_SID] |
||
2614 | hidnplayr | 245 | |
2931 | hidnplayr | 246 | lea eax, [ebx + ETH_DEVICE.mac] |
247 | lea edx, [PPPoE_MAC] |
||
248 | add ecx, PPPoE_frame.Payload + 2 |
||
249 | mov di, ETHER_PPP_SESSION |
||
250 | call ETH_output |
||
251 | jz .eth_error |
||
2614 | hidnplayr | 252 | |
2960 | hidnplayr | 253 | sub ecx, PPPoE_frame.Payload |
2931 | hidnplayr | 254 | mov [edi + PPPoE_frame.VersionAndType], 0x11 |
255 | mov [edi + PPPoE_frame.Code], 0 |
||
256 | popw [edi + PPPoE_frame.SessionID] |
||
257 | xchg cl, ch |
||
258 | mov [edi + PPPoE_frame.Length], cx |
||
259 | xchg cl, ch |
||
2960 | hidnplayr | 260 | |
2931 | hidnplayr | 261 | pop word [edi + PPPoE_frame.Payload] |
2614 | hidnplayr | 262 | |
2960 | hidnplayr | 263 | sub ecx, 2 |
2931 | hidnplayr | 264 | add edi, PPPoE_frame.Payload + 2 |
2614 | hidnplayr | 265 | |
2931 | hidnplayr | 266 | DEBUGF 1,"PPPoE_output: success!\n" |
267 | ret |
||
2614 | hidnplayr | 268 | |
269 | |||
2931 | hidnplayr | 270 | .eth_error: |
271 | add esp, 4 |
||
272 | xor edi, edi |
||
2614 | hidnplayr | 273 | |
274 | ret |
||
275 | |||
276 | |||
2931 | hidnplayr | 277 | PPPoE_start_connection: |
2614 | hidnplayr | 278 | |
2961 | hidnplayr | 279 | DEBUGF 2,"PPPoE_start_connection: %x\n", cx |
280 | |||
2931 | hidnplayr | 281 | cmp [PPPoE_SID], 0 |
2960 | hidnplayr | 282 | jne .fail |
2931 | hidnplayr | 283 | |
284 | mov [PPPoE_SID], cx |
||
285 | mov dword [PPPoE_MAC], edx |
||
286 | mov word [PPPoE_MAC + 4], si |
||
287 | |||
288 | xor eax, eax |
||
289 | ret |
||
290 | |||
291 | .fail: |
||
292 | or eax, -1 |
||
293 | ret |
||
294 | |||
295 | |||
296 | align 4 |
||
297 | PPPoE_stop_connection: |
||
298 | |||
2961 | hidnplayr | 299 | DEBUGF 2,"PPPoE_stop_connection\n" |
300 | |||
2931 | hidnplayr | 301 | xor eax, eax |
302 | mov [PPPoE_SID], ax |
||
303 | mov dword [PPPoE_MAC], eax |
||
304 | mov word [PPPoE_MAC + 4], ax |
||
305 | |||
306 | ret |
||
307 | |||
308 | |||
2614 | hidnplayr | 309 | ;--------------------------------------------------------------------------- |
310 | ; |
||
311 | ; PPPoE API |
||
312 | ; |
||
313 | ; This function is called by system function 75 |
||
314 | ; |
||
315 | ; IN: subfunction number in bl |
||
316 | ; device number in bh |
||
317 | ; ecx, edx, .. depends on subfunction |
||
318 | ; |
||
319 | ; OUT: |
||
320 | ; |
||
321 | ;--------------------------------------------------------------------------- |
||
322 | align 4 |
||
323 | PPPoE_api: |
||
324 | |||
325 | movzx eax, bh |
||
326 | shl eax, 2 |
||
327 | |||
328 | and ebx, 0xff |
||
329 | cmp ebx, .number |
||
330 | ja .error |
||
331 | jmp dword [.table + 4*ebx] |
||
332 | |||
333 | .table: |
||
2931 | hidnplayr | 334 | dd PPPoE_start_connection ; 0 |
335 | dd PPPoE_stop_connection ; 1 |
||
2614 | hidnplayr | 336 | .number = ($ - .table) / 4 - 1 |
337 | |||
338 | .error: |
||
339 | mov eax, -1 |
||
340 | ret |