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: |