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