1 /* PPPoE support library "libpppoe"
3 * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
4 * Jamal Hadi Salim <hadi@cyberus.ca>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
14 static unsigned int pcid
=1111;
15 static int srv_rcv_padi(struct session
* ses
,
16 struct pppoe_packet
*p_in
,
17 struct pppoe_packet
**p_out
){
18 struct pppoe_con
*newpc
= NULL
;
19 struct pppoe_tag
*tag
;
21 poe_dbglog(ses
,"Srv Recv'd packet: %P\n",p_in
);
24 ses
->curr_pkt
.hdr
= (struct pppoe_hdr
*) ses
->curr_pkt
.buf
;
25 ses
->curr_pkt
.hdr
->ver
= 1;
26 ses
->curr_pkt
.hdr
->type
= 1;
28 tag
= get_tag(p_in
->hdr
,PTT_SRV_NAME
);
33 if( ntohs(tag
->tag_len
)==0 ){
34 ses
->curr_pkt
.tags
[TAG_SRV_NAME
] = ses
->filt
->stag
;
35 }else if( tag
->tag_len
!= ses
->filt
->stag
->tag_len
36 || !memcmp( tag
+1, ses
->filt
->stag
, ntohs(tag
->tag_len
)) ){
39 ses
->curr_pkt
.tags
[TAG_SRV_NAME
] = tag
;
42 ses
->curr_pkt
.tags
[ TAG_AC_NAME
] = ses
->filt
->ntag
;
43 ses
->curr_pkt
.tags
[ TAG_HOST_UNIQ
] = get_tag(p_in
->hdr
,PTT_HOST_UNIQ
);
45 memcpy(&ses
->remote
, &p_in
->addr
, sizeof(struct sockaddr_ll
));
46 memcpy( &ses
->curr_pkt
.addr
, &ses
->remote
, sizeof(struct sockaddr_ll
));
48 ses
->curr_pkt
.hdr
->code
= PADO_CODE
;
51 ses
->curr_pkt
.tags
[ TAG_RELAY_SID
] = get_tag(p_in
->hdr
,PTT_RELAY_SID
);
53 send_disc(ses
, &ses
->curr_pkt
);
54 poe_dbglog(ses
,"Srv Sent packet: %P\n",&ses
->curr_pkt
);
60 static int srv_rcv_padr(struct session
* ses
,
61 struct pppoe_packet
*p_in
,
62 struct pppoe_packet
**p_out
){
63 struct pppoe_tag
*tag
;
65 poe_dbglog(ses
,"Recv'd packet: %P\n",p_in
);
69 /* Run checks to ensure this packets asks for
70 what we're willing to offer */
72 tag
= get_tag(p_in
->hdr
,PTT_SRV_NAME
);
74 if(!tag
|| tag
->tag_len
== 0 ){
75 p_in
->tags
[TAG_SRV_NAME
] = ses
->filt
->stag
;
77 }else if( tag
->tag_len
!= ses
->filt
->stag
->tag_len
78 || !memcmp(tag
+ 1 , ses
->filt
->stag
, ntohs(tag
->tag_len
)) ){
81 p_in
->tags
[TAG_SRV_NAME
] = tag
;
84 tag
= get_tag(p_in
->hdr
,PTT_AC_NAME
);
85 if( !tag
|| tag
->tag_len
==0 ){
86 p_in
->tags
[TAG_AC_NAME
] = ses
->filt
->ntag
;
87 }else if( tag
->tag_len
!= ses
->filt
->ntag
->tag_len
88 || !memcmp(tag
+ 1, ses
->filt
->ntag
, ntohs(tag
->tag_len
)) ){
91 p_in
->tags
[TAG_AC_NAME
] = tag
;
97 pcid
= ++pcid
& 0x0000ffff ;
102 p_in
->hdr
->sid
= ntohs(pcid
);
104 p_in
->hdr
->code
= PADS_CODE
;
105 send_disc(ses
, p_in
);
107 poe_dbglog(ses
,"Sent packet: %P\n",p_in
);
109 ses
->sp
.sa_family
= AF_PPPOX
;
110 ses
->sp
.sa_protocol
=PX_PROTO_OE
;
111 ses
->sp
.sa_addr
.pppoe
.sid
= p_in
->hdr
->sid
;
112 memcpy(ses
->sp
.sa_addr
.pppoe
.dev
, ses
->name
, IFNAMSIZ
);
113 memcpy(ses
->sp
.sa_addr
.pppoe
.remote
, p_in
->addr
.sll_addr
, ETH_ALEN
);
114 memcpy(&ses
->remote
, &p_in
->addr
, sizeof(struct sockaddr_ll
));
118 static int srv_rcv_padt(struct session
* ses
,
119 struct pppoe_packet
*p_in
,
120 struct pppoe_packet
**p_out
){
126 int srv_init_ses(struct session
*ses
, char* from
)
129 retval
= client_init_ses(ses
, from
);
130 ses
->init_disc
= NULL
;
131 ses
->rcv_pado
= NULL
;
132 ses
->rcv_pads
= NULL
;
133 ses
->rcv_padi
= srv_rcv_padi
;
134 ses
->rcv_padr
= srv_rcv_padr
;
135 ses
->rcv_padt
= srv_rcv_padt
;
137 /* retries forever */