Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2614 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2009-2012. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;; Clevermouse & hidnplayr                                      ;;
7
;;                                                              ;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
 
10
 
11
struct  PPPoE_header
12
 
13
        VersionAndType  db ?
14
        Code            db ?
15
        SessionID       dw ?
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
26
 
27
        datalen         dd ?            ; length of received data
28
        recvbuf         rb 1500         ; buffer for received data
29
        sendbuf         rb 1500         ; buffer for data to send
30
 
31
ends
32
 
33
iglobal
34
align 4
35
        PPPoE.head              dd PPPoE.head
36
        PPPoE.tail              dd PPPoE.head
37
endg
38
 
39
uglobal
40
        PPPoE.cur_receiver      dd ?
41
        PPPoE.cur_receiver_ptr  dd ?
42
        PPPoE.cur_receiver_len  dd ?
43
endg
44
 
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
52
 
53
; 1a. If memory allocation failed, return NULL.
54
        test    eax, eax
55
        jz      .nothing
56
 
57
; 2. Copy PID of caller to the structure.
58
        mov     edx, [CURRENT_TASK]
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
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:
69
        ret
70
 
71
 
72
align 4
73
PPPoE_free_connection:
74
 
75
; 1. Check that the caller is the owner of this connection.
76
        mov     eax, [CURRENT_TASK]
77
        cmp     [ebx+PPPoE_connection.pid], eax
78
        jnz     .nothing
79
 
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
84
        mov     [edx+PPPoE_connection.next], eax
85
 
86
; 3. Free the memory.
87
        stdcall kernel_free, ebx
88
 
89
  .nothing:
90
        ret
91
 
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
114
        jnz     .bad
115
 
116
; 3. Remember PID and data pointer of current listener.
117
        push    [CURRENT_TASK]
118
        pop     [PPPoE.cur_receiver]
119
        mov     [PPPoE.cur_receiver_ptr], edx
120
        mov     [PPPoE.cur_receiver_len], ebx
121
        and     dword [edx], 0 ; no offers yet
122
 
123
; 4. Create packet.
124
        test    ecx, ecx
125
        jnz     @f
126
        mov     esi, .default_payload
127
        mov     ecx, .default_payload_length
128
       @@:
129
 
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
135
        call    ETH_output
136
        jz      .eth_error
137
 
138
        push    edx eax
139
 
140
; 4b. Set ver=1, type=1 (=> first byte 0x11), code=9 (PADI packet), session=0
141
        mov     dword [edi], (0x09 shl 8) + 0x11
142
 
143
; 4c. Set payload length.
144
        mov     [edi+4], ch
145
        mov     [edi+5], cl
146
 
147
; 4e. Copy given tags.
148
        rep     movsb
149
 
150
; 5. Send packet.
151
        call    [ebx + NET_DEVICE.transmit]
152
; 6. Return.
153
        xor     eax, eax
154
        ret
155
 
156
  .bad:
157
        or      eax, -1
158
        ret
159
 
160
  .default_payload:
161
; Service-Name tag with zero length
162
        dw      0x0101, 0x0000
163
  .default_payload_length = $ - .default_payload
164
 
165
 
166
; Stop receiving PADO packets
167
align 4
168
PPPoE_stop_offers:
169
 
170
; Only the listener can stop listen.    ;;; TODO: make sure this function is called when process gets terminated
171
        mov     eax, [CURRENT_TASK]
172
        cmp     [PPPoE.cur_receiver], eax
173
        jnz     .bad
174
        xor     eax, eax
175
        mov     [PPPoE.cur_receiver_ptr], eax
176
        mov     [PPPoE.cur_receiver], eax
177
        ret
178
 
179
  .bad:
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:
191
        ret
192
 
193
 
194
 
195
;-----------------------------------------------------------------
196
;
197
; PPPoE discovery input
198
;
199
; Handler of received Ethernet packet with type = Discovery
200
;
201
;
202
;  IN:  Pointer to buffer in [esp]
203
;       size of buffer in [esp+4]
204
;       pointer to device struct in ebx
205
;       pointer to PPP header in edx
206
;       size of PPP packet in ecx
207
;  OUT: /
208
;
209
;-----------------------------------------------------------------
210
align 4
211
PPPoE_discovery_input:
212
 
213
; 1. Minimum 6 bytes for PPPoE header.
214
        cmp     ecx, sizeof.PPPoE_header
215
        jb      .bad
216
 
217
; 1. Ignore packets with ver<>1 and/or type<>1.
218
        cmp     [edx + PPPoE_header.VersionAndType], 0x11
219
        jnz     .bad
220
 
221
; 2. Code must be either 7 for Offer,
222
; or 0x65 for Session-Confirmation, or 0xa7 for Terminate.
223
; Because only Initiation/Offers are supported, we expect only value 7.
224
        cmp     [edx + PPPoE_header.Code], 7
225
        jnz     .bad
226
 
227
; 3. Session ID must be zero for Offers.
228
        cmp     [edx + PPPoE_header.SessionID], 0
229
        jnz     .bad
230
 
231
; 4. Payload length
232
        rol     [edx + PPPoE_header.Length], 8          ; Convert INET byte order to intel
233
 
234
; 5. Ignore packet if nobody is listening.
235
        cmp     [PPPoE.cur_receiver], 0
236
        jz      .bad
237
 
238
; 6. Good, now copy the received packet to the buffer of listener.
239
 
240
        ;;; TODO
241
 
242
  .bad:
243
        DEBUGF 1,'K : PPPoE - dumped\n'
244
        call    kernel_free
245
        add     esp, 4                                  ; pop (balance stack)
246
        ret
247
 
248
 
249
 
250
 
251
;---------------------------------------------------------------------------
252
;
253
; PPPoE API
254
;
255
; This function is called by system function 75
256
;
257
; IN:  subfunction number in bl
258
;      device number in bh
259
;      ecx, edx, .. depends on subfunction
260
;
261
; OUT:
262
;
263
;---------------------------------------------------------------------------
264
align 4
265
PPPoE_api:
266
 
267
        movzx   eax, bh
268
        shl     eax, 2
269
 
270
        and     ebx, 0xff
271
        cmp     ebx, .number
272
        ja      .error
273
        jmp     dword [.table + 4*ebx]
274
 
275
  .table:
276
        dd      PPPoE_send_init         ; 0
277
        dd      PPPoE_stop_offers       ; 1
278
        dd      PPPoE_alloc_connection  ; 3
279
        dd      PPPoE_free_connection   ; 4
280
        dd      PPPoE_send_discovery    ; 5
281
        dd      PPPoE_receive_discovery ; 6
282
  .number = ($ - .table) / 4 - 1
283
 
284
  .error:
285
        mov     eax, -1
286
        ret