CPU: Wrong CPU Load %.
[tomato.git] / release / src / router / ppp / pppd / plugins / pppoe / pppoe_client.c
blob8cb2b1e1b5a055b3f8c1ce1a1ced024bf832b041
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.
12 #include <pppoe.h>
14 int retry_num = 10;
16 static int std_rcv_pado(struct session* ses,
17 struct pppoe_packet *p_in,
18 struct pppoe_packet **p_out){
20 struct pppoe_tag *ac_name, *srv_name;
21 char ac[1024], srv[1024];
23 if(ses->state != PADO_CODE ){
24 poe_error(ses,"Unexpected packet: %P",p_in);
25 return 0;
28 if( verify_packet(ses, p_in) < 0)
29 return 0;
31 LOGX_INFO("Received PADO.");
33 if (DEB_DISC2)
34 poe_dbglog (ses,"PADO received: %P", p_in);
36 memcpy(&ses->remote, &p_in->addr, sizeof(struct sockaddr_ll));
37 memcpy(&ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
39 ses->curr_pkt.hdr->code = PADR_CODE;
41 /* The HOST_UNIQ has been verified already... there's no "if" about this */
42 /* if(ses->filt->htag) */
43 copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_HOST_UNIQ));
45 if (ses->filt->ntag) {
46 ses->curr_pkt.tags[TAG_AC_NAME]=NULL;
49 ac_name = get_tag(p_in->hdr,PTT_AC_NAME);
50 srv_name = get_tag(p_in->hdr,PTT_SRV_NAME);
52 memset(ac, 0, sizeof(ac));
53 memset(srv, 0, sizeof(srv));
55 strncpy(ac, ac_name->tag_data, ntohs(ac_name->tag_len));
56 strncpy(srv, srv_name->tag_data, ntohs(srv_name->tag_len));
58 script_setenv("AC_NAME", ac, 1);
59 script_setenv("SRV_NAME", srv, 1);
61 if(ses->filt->stag) {
62 ses->curr_pkt.tags[TAG_SRV_NAME]=NULL;
64 copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_SRV_NAME));
66 copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_AC_COOKIE));
67 copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_RELAY_SID));
69 ses->state = PADS_CODE;
71 ses->retransmits = 0;
73 LOGX_INFO("Sending PADR.");
75 send_disc(ses, &ses->curr_pkt);
76 (*p_out) = &ses->curr_pkt;
78 if (ses->np)
79 return 1;
81 return 0;
84 static int std_init_disc(struct session* ses,
85 struct pppoe_packet *p_in,
86 struct pppoe_packet **p_out){
88 /* Check if already connected */
89 if( ses->state != PADO_CODE ){
90 return -1;
93 memset(&ses->curr_pkt,0, sizeof(struct pppoe_packet));
95 ses->curr_pkt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
96 ses->curr_pkt.hdr->ver = 1;
97 ses->curr_pkt.hdr->type = 1;
98 ses->curr_pkt.hdr->code = PADI_CODE;
101 memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
103 LOGX_INFO("Sending PADI.");
105 ses->retransmits = 0 ;
107 if(ses->filt->ntag) {
108 ses->curr_pkt.tags[TAG_AC_NAME]=ses->filt->ntag;
109 poe_info(ses,"overriding AC name\n");
112 if(ses->filt->stag)
113 ses->curr_pkt.tags[TAG_SRV_NAME]=ses->filt->stag;
115 if(ses->filt->htag)
116 ses->curr_pkt.tags[TAG_HOST_UNIQ]=ses->filt->htag;
118 ses->retransmits = 0 ;
120 send_disc(ses, &ses->curr_pkt);
121 (*p_out)= &ses->curr_pkt;
123 return 0;
127 static int std_rcv_pads(struct session* ses,
128 struct pppoe_packet *p_in,
129 struct pppoe_packet **p_out){
130 if(ses->state != PADS_CODE ){
131 poe_error(ses,"Unexpected packet: %P",p_in);
132 return 0;
135 if( verify_packet(ses, p_in) < 0)
136 return 0;
138 ses->sp.sa_family = AF_PPPOX;
139 ses->sp.sa_protocol = PX_PROTO_OE;
140 ses->sp.sa_addr.pppoe.sid = p_in->hdr->sid;
141 memcpy(ses->sp.sa_addr.pppoe.dev,ses->name, IFNAMSIZ);
142 memcpy(ses->sp.sa_addr.pppoe.remote, p_in->addr.sll_addr, ETH_ALEN);
144 if (DEB_DISC)
145 poe_dbglog (ses,"Got connection: %x %s <--->%E",
146 ses->sp.sa_addr.pppoe.sid,
147 ses->sp.sa_addr.pppoe.dev, ses->sp.sa_addr.pppoe.remote);
149 LOGX_INFO("Received PADS. SID: 0x%04X", ses->sp.sa_addr.pppoe.sid);
150 return 1;
153 static int std_rcv_padt(struct session* ses,
154 struct pppoe_packet *p_in,
155 struct pppoe_packet **p_out){
157 LOGX_INFO("Received PADT.");
158 ses->state = PADO_CODE;
159 return 0;
163 extern int disc_sock;
165 int client_init_ses (struct session *ses, char* devnam)
167 int i=0;
168 int retval;
169 char dev[IFNAMSIZ+1];
170 int addr[ETH_ALEN];
171 int sid;
173 /* Make socket if necessary */
174 if (disc_sock < 0) {
175 disc_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
176 if (disc_sock < 0){
177 poe_fatal(ses, "Cannot create PF_PACKET socket for PPPoE discovery\n");
181 /* Check for long format */
182 retval =sscanf(devnam, FMTSTRING(IFNAMSIZ),addr, addr+1, addr+2,
183 addr+3, addr+4, addr+5,&sid,dev);
184 if( retval != 8 ){
185 /* Verify the device name , construct ses->local */
186 retval = get_sockaddr_ll(devnam,&ses->local);
187 if (retval < 0)
188 poe_fatal(ses, "client_init_ses: "
189 "Cannot create PF_PACKET socket for PPPoE discovery\n");
192 ses->state = PADO_CODE;
193 memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
195 memset( ses->remote.sll_addr, 0xff, ETH_ALEN);
196 }else{
197 /* long form parsed */
199 /* Verify the device name , construct ses->local */
200 retval = get_sockaddr_ll(dev,&ses->local);
201 if (retval < 0)
202 poe_fatal(ses,"client_init_ses(2): "
203 "Cannot create PF_PACKET socket for PPPoE discovery\n");
204 ses->state = PADS_CODE;
205 ses->sp.sa_family = AF_PPPOX;
206 ses->sp.sa_protocol = PX_PROTO_OE;
207 ses->sp.sa_addr.pppoe.sid = sid;
209 memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
211 for(; i < ETH_ALEN ; ++i ){
212 ses->sp.sa_addr.pppoe.remote[i] = addr[i];
213 ses->remote.sll_addr[i]=addr[i];
215 memcpy(ses->sp.sa_addr.pppoe.dev, dev, IFNAMSIZ);
220 if( retval < 0 )
221 error("bad device name: %s",devnam);
224 if (DEB_DISC)
225 poe_dbglog (ses,"Local ETH %E", ses->local.sll_addr);
228 retval = bind( disc_sock ,
229 (struct sockaddr*)&ses->local,
230 sizeof(struct sockaddr_ll));
233 if( retval < 0 ){
234 error("bind to PF_PACKET socket failed: %m");
237 /* Make socket if necessary */
238 if (ses->fd < 0) {
239 ses->fd = socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_OE);
240 if(ses->fd < 0)
242 poe_fatal(ses,"Failed to create PPPoE socket: %m");
247 ses->init_disc = std_init_disc;
248 ses->rcv_pado = std_rcv_pado;
249 ses->rcv_pads = std_rcv_pads;
250 ses->rcv_padt = std_rcv_padt;
252 /* this should be filter overridable */
253 ses->retries = retry_num;
255 return ses->fd;