]> git.pld-linux.org Git - packages/ppp.git/blame - ppp-2.4.1-pppoe.patch2
- srp by default off , turn on from spec
[packages/ppp.git] / ppp-2.4.1-pppoe.patch2
CommitLineData
13a2ad11
AM
1diff -r -N -u -b -B ppp-2.4.1.orig/configure ppp-2.4.1.pppoe2/configure
2--- ppp-2.4.1.orig/configure Mon Apr 24 03:41:40 2000
3+++ ppp-2.4.1.pppoe2/configure Fri Mar 30 16:37:20 2001
4@@ -131,7 +131,7 @@
5 makext=$orig_makext
6 fi
7 fi
8- for dir in pppd pppstats chat pppdump; do
9+ for dir in pppd pppstats chat pppdump pppd/plugins pppd/plugins/pppoe; do
10 rm -f $dir/Makefile
11 if [ -f $dir/Makefile.$makext ]; then
12 ln -s Makefile.$makext $dir/Makefile
13diff -r -N -u -b -B ppp-2.4.1.orig/linux/Makefile.top ppp-2.4.1.pppoe2/linux/Makefile.top
14--- ppp-2.4.1.orig/linux/Makefile.top Mon Apr 17 06:39:26 2000
15+++ ppp-2.4.1.pppoe2/linux/Makefile.top Fri Mar 30 18:43:51 2001
16@@ -10,6 +10,7 @@
17
18 all:
19 cd chat; $(MAKE) $(MFLAGS) all
20+ cd pppd/plugins; $(MAKE) $(MFLAGS) all
21 cd pppd; $(MAKE) $(MFLAGS) all
22 cd pppstats; $(MAKE) $(MFLAGS) all
23 cd pppdump; $(MAKE) $(MFLAGS) all
24@@ -18,6 +19,7 @@
25
26 install-progs:
27 cd chat; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
28+ cd pppd/plugins; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
29 cd pppd; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
30 cd pppstats; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
31 cd pppdump; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
32@@ -44,6 +46,7 @@
33 rm -f `find . -name 'core' -print`
34 rm -f `find . -name '*~' -print`
35 cd chat; $(MAKE) clean
36+ cd pppd/plugins; $(MAKE) clean
37 cd pppd; $(MAKE) clean
38 cd pppstats; $(MAKE) clean
39 cd pppdump; $(MAKE) clean
40diff -r -N -u -b -B ppp-2.4.1.orig/pppd/options.c ppp-2.4.1.pppoe2/pppd/options.c
41--- ppp-2.4.1.orig/pppd/options.c Tue Mar 13 00:56:19 2001
42+++ ppp-2.4.1.pppoe2/pppd/options.c Fri Mar 30 19:33:55 2001
43@@ -789,6 +789,23 @@
44 }
45
46 /*
47+ * remove_option - permanently remove an option from consideration...
48+ * for use by modules to remove choices which no longer make sense.
49+ * returns true if found an option
50+ */
51+int
52+remove_option(name)
53+ char *name;
54+{
55+ option_t *o;
56+ o = find_option(name);
57+ if (o == NULL)
58+ return 0;
59+ o->name = "";
60+ return 1;
61+}
62+
63+/*
64 * check_options - check that options are valid and consistent.
65 */
66 void
67diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/Makefile.linux ppp-2.4.1.pppoe2/pppd/plugins/Makefile.linux
68--- ppp-2.4.1.orig/pppd/plugins/Makefile.linux Tue Mar 6 23:21:18 2001
69+++ ppp-2.4.1.pppoe2/pppd/plugins/Makefile.linux Sun May 27 08:08:58 2001
70@@ -3,7 +3,10 @@
71 LDFLAGS = -shared
72 INSTALL = install
73
74-all: minconn.so passprompt.so
75+all: minconn.so passprompt.so pppoe/pppoe.so
76+
77+pppoe/pppoe.so:
78+ $(MAKE) -C pppoe $(MFLAGS) pppoe.so
79
80 minconn.so: minconn.c
81 $(CC) -o $@ $(LDFLAGS) $(CFLAGS) minconn.c
82@@ -13,7 +16,10 @@
83
84 LIBDIR = /usr/lib/pppd
85
86-install: minconn.so passprompt.so
87+install: minconn.so passprompt.so pppoe/pppoe.so
88 version=`awk -F '"' '/VERSION/ { print $$2; }' ../patchlevel.h`; \
89 $(INSTALL) -d $(LIBDIR)/$$version; \
90 $(INSTALL) $? $(LIBDIR)/$$version
91\ No newline at end of file
92+
93+clean:
94+ rm -rf *.o *.so
95\ No newline at end of file
96diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/Makefile.linux ppp-2.4.1.pppoe2/pppd/plugins/pppoe/Makefile.linux
97--- ppp-2.4.1.orig/pppd/plugins/pppoe/Makefile.linux Wed Dec 31 19:00:00 1969
98+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/Makefile.linux Sun May 27 08:08:40 2001
99@@ -0,0 +1,43 @@
100+CC = gcc
101+CFLAGS = -g -I.. -I../.. -I../../../include -D_linux_=1 -fPIC
102+LDFLAGS = -shared
103+
104+all: pppoe.so pppoed
105+
106+
107+PLUGINDIR = $(LIBDIR)/plugins
108+PLUGINSRCS= pppoe.c libpppoe.c utils.c pppoehash.c pppoe_client.c \
109+ pppoe_relay.c pppoe_server.c pppd_utils.c
110+#
111+# include dependancies if present and backup if as a header file
112+ifeq (.depend,$(wildcard .depend))
113+include .depend
114+endif
115+
116+
117+
118+pppoefwd: pppoefwd.o libpppoe.a
119+ $(CC) -o $@ $^
120+
121+pppoed: pppoed.o pppd_utils.o libpppoe.a
122+ $(CC) -o $@ $^
123+
124+libpppoe.a: pppoehash.o pppoe_client.o pppoe_relay.o pppoe_server.o \
125+ utils.o libpppoe.o
126+ ar -rc $@ $^
127+
128+pppoe.so: pppoe.o libpppoe.a
129+ $(CC) -o $@ $(LDFLAGS) $^
130+
131+%.so: %.c
132+ $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^
133+
134+clean:
135+ rm -f *.o *.so *.a pppoefwd pppoed
136+
137+
138+$(PLUGINDIR):
139+ $(INSTALL) -d -m 755 $@
140+
141+depend:
142+ $(CPP) -M $(CFLAGS) $(PLUGINSRCS) >.depend
143diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/libpppoe.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/libpppoe.c
144--- ppp-2.4.1.orig/pppd/plugins/pppoe/libpppoe.c Wed Dec 31 19:00:00 1969
145+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/libpppoe.c Fri Mar 30 07:40:42 2001
146@@ -0,0 +1,631 @@
147+/* PPPoE support library "libpppoe"
148+ *
149+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
150+ * Jamal Hadi Salim <hadi@cyberus.ca>
151+ *
152+ * This program is free software; you can redistribute it and/or
153+ * modify it under the terms of the GNU General Public License
154+ * as published by the Free Software Foundation; either version
155+ * 2 of the License, or (at your option) any later version.
156+ */
157+
158+#include "pppoe.h"
159+
160+int disc_sock=-1;
161+
162+int verify_packet( struct session *ses, struct pppoe_packet *p);
163+
164+#define TAG_DATA(type,tag_ptr) ((type *) ((struct pppoe_tag*)tag_ptr)->tag_data)
165+
166+
167+/***************************************************************************
168+ *
169+ * Return the location where the next tag can be pu
170+ *
171+ **************************************************************************/
172+static struct pppoe_tag *next_tag(struct pppoe_hdr *ph)
173+{
174+ return (struct pppoe_tag *)
175+ (((char *) &ph->tag) + ntohs(ph->length));
176+}
177+
178+/**************************************************************************
179+ *
180+ * Update header to reflect the addition of a new tag
181+ *
182+ **************************************************************************/
183+static void add_tag(struct pppoe_hdr *ph, struct pppoe_tag *pt)
184+{
185+ int len = (ntohs(ph->length) +
186+ ntohs(pt->tag_len) +
187+ sizeof(struct pppoe_tag));
188+
189+ if (pt != next_tag(ph))
190+ printf("PPPoE add_tag caller is buggy\n");
191+
192+ ph->length = htons(len);
193+}
194+
195+/*************************************************************************
196+ *
197+ * Look for a tag of a specific type
198+ *
199+ ************************************************************************/
200+struct pppoe_tag *get_tag(struct pppoe_hdr *ph, u_int16_t idx)
201+{
202+ char *end = (char *) next_tag(ph);
203+ char *ptn = NULL;
204+ struct pppoe_tag *pt = &ph->tag[0];
205+
206+ /*
207+ * Keep processing tags while a tag header will still fit.
208+ *
209+ * This check will ensure that the entire tag header pointed
210+ * to by pt will fit inside the message, and thus it will be
211+ * valid to check the tag_type and tag_len fields.
212+ */
213+ while ((char *)(pt + 1) <= end) {
214+ /*
215+ * If the tag data would go past the end of the packet, abort.
216+ */
217+ ptn = (((char *) (pt + 1)) + ntohs(pt->tag_len));
218+ if (ptn > end)
219+ return NULL;
220+
221+ if (pt->tag_type == idx)
222+ return pt;
223+
224+ pt = (struct pppoe_tag *) ptn;
225+ }
226+
227+ return NULL;
228+}
229+
230+/* We want to use tag names to reference into arrays containing the tag data.
231+ This takes an RFC 2516 tag identifier and maps it into a local one.
232+ The reverse mapping is accomplished via the tag_map array */
233+#define UNMAP_TAG(x) case PTT_##x : return TAG_##x
234+static inline int tag_index(int tag){
235+ switch(tag){
236+ UNMAP_TAG(SRV_NAME);
237+ UNMAP_TAG(AC_NAME);
238+ UNMAP_TAG(HOST_UNIQ);
239+ UNMAP_TAG(AC_COOKIE);
240+ UNMAP_TAG(VENDOR);
241+ UNMAP_TAG(RELAY_SID);
242+ UNMAP_TAG(SRV_ERR);
243+ UNMAP_TAG(SYS_ERR);
244+ UNMAP_TAG(GEN_ERR);
245+ UNMAP_TAG(EOL);
246+ };
247+ return -1;
248+}
249+
250+/*************************************************************************
251+ *
252+ * Makes a copy of a tag into a PPPoE packe
253+ *
254+ ************************************************************************/
255+void copy_tag(struct pppoe_packet *dest, struct pppoe_tag *pt)
256+{
257+ struct pppoe_tag *end_tag = get_tag(dest->hdr, PTT_EOL);
258+ int tagid;
259+ int tag_len;
260+ if( !pt ) {
261+ return;
262+ }
263+ tagid = tag_index(pt->tag_type);
264+
265+ tag_len = sizeof(struct pppoe_tag) + ntohs(pt->tag_len);
266+
267+ if( end_tag ){
268+ memcpy(((char*)end_tag)+tag_len ,
269+ end_tag, sizeof(struct pppoe_tag));
270+
271+ dest->tags[tagid]=end_tag;
272+ dest->tags[TAG_EOL] = (struct pppoe_tag*)((char*)dest->tags[TAG_EOL] + tag_len);
273+ memcpy(end_tag, pt, tag_len);
274+ dest->hdr->length = htons(ntohs(dest->hdr->length) + tag_len);
275+
276+ }else{
277+ memcpy(next_tag(dest->hdr),pt, tag_len);
278+ dest->tags[tagid]=next_tag(dest->hdr);
279+ add_tag(dest->hdr,next_tag(dest->hdr));
280+ }
281+
282+
283+}
284+
285+
286+/*************************************************************************
287+ *
288+ * Put tags from a packet into a nice array
289+ *
290+ ************************************************************************/
291+static void extract_tags(struct pppoe_hdr *ph, struct pppoe_tag** buf){
292+ int i=0;
293+ for(;i<MAX_TAGS;++i){
294+ buf[i] = get_tag(ph,tag_map[i]);
295+ }
296+}
297+
298+
299+/*************************************************************************
300+ *
301+ * Verify that a packet has a tag containint a specific value
302+ *
303+ ************************************************************************/
304+static int verify_tag(struct session* ses,
305+ struct pppoe_packet* p,
306+ unsigned short id,
307+ char* data,
308+ int data_len)
309+{
310+ int len;
311+ struct pppoe_tag *pt = p->tags[id];
312+
313+ if( !pt ){
314+ poe_info(ses,"Missing tag %d. Expected %s\n",
315+ id,data);
316+ return 0;
317+ }
318+ len = ntohs(pt->tag_len);
319+ if(len != data_len){
320+ poe_info(ses,"Length mismatch on tag %d: expect: %d got: %d\n",
321+ id, data_len, len);
322+ return 0;
323+ }
324+
325+ if( 0!=memcmp(pt->tag_data,data,data_len)){
326+ poe_info(ses,"Tag data mismatch on tag %d: expect: %s vs %s\n",
327+ id, data,pt->tag_data);
328+ return 0;
329+ }
330+ return 1;
331+}
332+
333+
334+/*************************************************************************
335+ *
336+ * Verify the existence of an ethernet device.
337+ * Construct an AF_PACKET address struct to match.
338+ *
339+ ************************************************************************/
340+int get_sockaddr_ll(const char *devnam,struct sockaddr_ll* sll){
341+ struct ifreq ifr;
342+ int retval;
343+
344+ if(disc_sock<0){
345+
346+ disc_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
347+ if( disc_sock < 0 ){
348+ return -1;
349+ }
350+ }
351+
352+ strncpy(ifr.ifr_name, devnam, sizeof(ifr.ifr_name));
353+
354+ retval = ioctl( disc_sock , SIOCGIFINDEX, &ifr);
355+
356+ if( retval < 0 ){
357+// error("Bad device name: %s (%m)",devnam);
358+ return 0;
359+ }
360+
361+ if(sll) sll->sll_ifindex = ifr.ifr_ifindex;
362+
363+ retval = ioctl (disc_sock, SIOCGIFHWADDR, &ifr);
364+ if( retval < 0 ){
365+// error("Bad device name: %s (%m)",devnam);
366+ return 0;
367+ }
368+
369+ if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
370+ error("Interface %s is not Ethernet!", devnam);
371+ return 0;
372+ }
373+ if(sll){
374+ sll->sll_family = AF_PACKET;
375+ sll->sll_protocol= ntohs(ETH_P_PPP_DISC);
376+ sll->sll_hatype = ARPHRD_ETHER;
377+ sll->sll_pkttype = PACKET_BROADCAST;
378+ sll->sll_hatype = ETH_ALEN;
379+ memcpy( sll->sll_addr , ifr.ifr_hwaddr.sa_data, ETH_ALEN);
380+ }
381+ return 1;
382+}
383+
384+
385+
386+
387+/*************************************************************************
388+ *
389+ * Construct and send a discovery message.
390+ *
391+ ************************************************************************/
392+int send_disc(struct session *ses, struct pppoe_packet *p)
393+{
394+ char buf[MAX_PAYLOAD + sizeof(struct pppoe_hdr)];
395+ int data_len = sizeof(struct pppoe_hdr);
396+
397+ struct pppoe_hdr *ph = NULL;
398+ struct pppoe_tag *tag = NULL;
399+ int i, error = 0;
400+ int got_host_uniq = 0;
401+ int got_srv_name = 0;
402+ int got_ac_name = 0;
403+
404+ for (i = 0; i < MAX_TAGS; i++) {
405+ if (!p->tags[i])
406+ continue;
407+
408+ got_host_uniq |= (p->tags[i]->tag_type == PTT_HOST_UNIQ);
409+
410+ /* Relay identifiers qualify as HOST_UNIQ's:
411+ we need HOST_UNIQ to uniquely identify the packet,
412+ PTT_RELAY_SID is sufficient for us for outgoing packets */
413+ got_host_uniq |= (p->tags[i]->tag_type == PTT_RELAY_SID);
414+
415+ got_srv_name |= (p->tags[i]->tag_type == PTT_SRV_NAME);
416+ got_ac_name |= (p->tags[i]->tag_type == PTT_AC_NAME);
417+
418+ data_len += (ntohs(p->tags[i]->tag_len) +
419+ sizeof(struct pppoe_tag));
420+ }
421+
422+ ph = (struct pppoe_hdr *) buf;
423+
424+
425+ memcpy(ph, p->hdr, sizeof(struct pppoe_hdr));
426+ ph->length = __constant_htons(0);
427+
428+ /* if no HOST_UNIQ tags --- add one with process id */
429+ if (!got_host_uniq){
430+ data_len += (sizeof(struct pppoe_tag) +
431+ sizeof(struct session *));
432+ tag = next_tag(ph);
433+ tag->tag_type = PTT_HOST_UNIQ;
434+ tag->tag_len = htons(sizeof(struct session *));
435+ memcpy(tag->tag_data,
436+ &ses,
437+ sizeof(struct session *));
438+
439+ add_tag(ph, tag);
440+ }
441+
442+ if( !got_srv_name ){
443+ data_len += sizeof(struct pppoe_tag);
444+ tag = next_tag(ph);
445+ tag->tag_type = PTT_SRV_NAME;
446+ tag->tag_len = 0;
447+ add_tag(ph, tag);
448+ }
449+
450+ if(!got_ac_name && ph->code==PADO_CODE){
451+ data_len += sizeof(struct pppoe_tag);
452+ tag = next_tag(ph);
453+ tag->tag_type = PTT_AC_NAME;
454+ tag->tag_len = 0;
455+ add_tag(ph, tag);
456+ }
457+
458+ for (i = 0; i < MAX_TAGS; i++) {
459+ if (!p->tags[i])
460+ continue;
461+
462+ tag = next_tag(ph);
463+ memcpy(tag, p->tags[i],
464+ sizeof(struct pppoe_tag) + ntohs(p->tags[i]->tag_len));
465+
466+ add_tag(ph, tag);
467+ }
468+
469+ /* Now fixup the packet struct to make sure all of its pointers
470+ are self-contained */
471+ memcpy( p->hdr , ph, data_len );
472+ extract_tags( p->hdr, p->tags);
473+
474+ error = sendto(disc_sock, buf, data_len, 0,
475+ (struct sockaddr*) &p->addr,
476+ sizeof(struct sockaddr_ll));
477+
478+ if(error < 0)
479+ poe_error(ses,"sendto returned: %m\n");
480+
481+ return error;
482+}
483+
484+/*************************************************************************
485+ *
486+ * Verify that a packet is legal
487+ *
488+ *************************************************************************/
489+int verify_packet( struct session *ses, struct pppoe_packet *p){
490+ struct session * hu_val;
491+
492+ /* This code here should do all of the error checking and
493+ validation on the incoming packet */
494+
495+
496+ /* If we receive any error tags, abort */
497+#define CHECK_TAG(name, val) \
498+ if((NULL==p->tags[name])== val){ \
499+ poe_error(ses,"Tag error: " #name ); \
500+ return -1; \
501+ }
502+
503+
504+
505+ CHECK_TAG(TAG_SRV_ERR,0);
506+ CHECK_TAG(TAG_SYS_ERR,0);
507+ CHECK_TAG(TAG_GEN_ERR,0);
508+
509+ /* A HOST_UNIQ must be present */
510+ CHECK_TAG(TAG_HOST_UNIQ,1);
511+
512+ hu_val = *TAG_DATA(struct session* ,p->tags[TAG_HOST_UNIQ]);
513+
514+ if( hu_val != ses ){
515+ poe_info(ses,"HOST_UNIQ mismatch: %08x %i\n",(int)hu_val,getpid());
516+ return -1;
517+ }
518+
519+ if(ses->filt->htag &&
520+ !verify_tag(ses,p,TAG_HOST_UNIQ,ses->filt->htag->tag_data,(int)ntohs(ses->filt->htag->tag_len)))
521+ return -1;
522+ else
523+ poe_info(ses,"HOST_UNIQ successful match\n");
524+
525+
526+ if(ses->filt->ntag &&
527+ !verify_tag(ses,p,TAG_AC_NAME,ses->filt->ntag->tag_data,(int)ntohs(ses->filt->ntag->tag_len))){
528+ poe_info(ses,"AC_NAME failure");
529+ return -1;
530+ }
531+
532+ if(ses->filt->stag &&
533+ !verify_tag(ses,p,TAG_SRV_NAME,ses->filt->stag->tag_data,(int)ntohs(ses->filt->stag->tag_len))){
534+ poe_info(ses,"SRV_NAME failure");
535+ return -1;
536+ }
537+
538+}
539+
540+
541+/*************************************************************************
542+ *
543+ * Receive and verify an incoming packet.
544+ *
545+ *************************************************************************/
546+static int recv_disc( struct session *ses,
547+ struct pppoe_packet *p){
548+ int error = 0;
549+ unsigned int from_len = sizeof(struct sockaddr_ll);
550+ struct session* hu_val;
551+ struct pppoe_tag *pt;
552+
553+ p->hdr = (struct pppoe_hdr*)p->buf;
554+
555+ error = recvfrom( disc_sock, p->buf, 1500, 0,
556+ (struct sockaddr*)&p->addr, &from_len);
557+
558+ if(error < 0) return error;
559+
560+ extract_tags(p->hdr,p->tags);
561+
562+ return 1;
563+}
564+
565+
566+/*************************************************************************
567+ *
568+ * Send a PADT
569+ *
570+ *************************************************************************/
571+int session_disconnect(struct session *ses){
572+ struct pppoe_packet padt;
573+
574+ memset(&padt,0,sizeof(struct pppoe_packet));
575+ memcpy(&padt.addr, &ses->remote, sizeof(struct sockaddr_ll));
576+
577+ padt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
578+ padt.hdr->ver = 1;
579+ padt.hdr->type = 1;
580+ padt.hdr->code = PADT_CODE;
581+ padt.hdr->sid = ses->sp.sa_addr.pppoe.sid;
582+
583+ send_disc(ses,&padt);
584+ ses->sp.sa_addr.pppoe.sid = 0 ;
585+ ses->state = PADO_CODE;
586+ return 0;
587+
588+}
589+
590+
591+/*************************************************************************
592+ *
593+ * Make a connection -- behaviour depends on callbacks specified in "ses"
594+ *
595+ *************************************************************************/
596+int session_connect(struct session *ses)
597+{
598+
599+ int pkt_size=0;
600+ int ret_pkt_size=0;
601+ struct pppoe_tag *tags = NULL;
602+ struct pppoe_packet *p_out=NULL;
603+ struct pppoe_packet rcv_packet;
604+ int ret;
605+
606+
607+ if(ses->init_disc){
608+ ret = (*ses->init_disc)(ses, NULL, &p_out);
609+ if( ret != 0 ) return ret;
610+ }
611+
612+ /* main discovery loop */
613+
614+
615+ while(ses->retransmits < ses->retries || ses->retries==-1 ){
616+
617+ fd_set in;
618+ struct timeval tv;
619+ FD_ZERO(&in);
620+
621+ FD_SET(disc_sock,&in);
622+
623+ if(ses->retransmits>=0){
624+ ++ses->retransmits;
625+ tv.tv_sec = 1 << ses->retransmits;
626+ tv.tv_usec = 0;
627+ ret = select(disc_sock+1, &in, NULL, NULL, &tv);
628+ }else{
629+ ret = select(disc_sock+1, &in, NULL, NULL, NULL);
630+ }
631+
632+ if( ret == 0 ){
633+ if( DEB_DISC ){
634+ poe_dbglog(ses, "Re-sending ...");
635+ }
636+
637+ if( ses->timeout ){
638+ ret = (*ses->timeout)(ses, NULL, &p_out);
639+ if( ret != 0 )
640+ return ret;
641+
642+ }else if(p_out){
643+ send_disc(ses,p_out);
644+ }
645+ continue;
646+ }
647+
648+
649+ ret = recv_disc(ses, &rcv_packet);
650+
651+ /* Should differentiate between system errors and
652+ bad packets and the like... */
653+ if( ret < 0 && errno != EINTR){
654+
655+ return -1;
656+ }
657+
658+
659+
660+
661+ switch (rcv_packet.hdr->code) {
662+
663+ case PADI_CODE:
664+ {
665+ if(ses->rcv_padi){
666+ ret = (*ses->rcv_padi)(ses,&rcv_packet,&p_out);
667+
668+ if( ret != 0){
669+ return ret;
670+ }
671+ }
672+ break;
673+ }
674+
675+ case PADO_CODE: /* wait for PADO */
676+ {
677+ if(ses->rcv_pado){
678+ ret = (*ses->rcv_pado)(ses,&rcv_packet,&p_out);
679+
680+ if( ret != 0){
681+ return ret;
682+ }
683+ }
684+ break;
685+ }
686+
687+ case PADR_CODE:
688+ {
689+ if(ses->rcv_padr){
690+ ret = (*ses->rcv_padr)(ses,&rcv_packet,&p_out);
691+
692+ if( ret != 0){
693+ return ret;
694+ }
695+ }
696+ break;
697+ }
698+
699+ case PADS_CODE:
700+ {
701+ if(ses->rcv_pads){
702+ ret = (*ses->rcv_pads)(ses,&rcv_packet,&p_out);
703+
704+ if( ret != 0){
705+ return ret;
706+ }
707+ }
708+ break;
709+ }
710+
711+ case PADT_CODE:
712+ {
713+ if( rcv_packet.hdr->sid != ses->sp.sa_addr.pppoe.sid ){
714+ --ses->retransmits;
715+ continue;
716+ }
717+ if(ses->rcv_padt){
718+ ret = (*ses->rcv_padt)(ses,&rcv_packet,&p_out);
719+
720+ if( ret != 0){
721+ return ret;
722+ }
723+ }else{
724+ poe_error (ses,"connection terminated");
725+ return (-1);
726+ }
727+ break;
728+ }
729+ default:
730+ poe_error(ses,"invalid packet %P",&rcv_packet);
731+ return (-1);
732+ }
733+ }
734+ return (0);
735+}
736+
737+
738+/*************************************************************************
739+ *
740+ * Register an ethernet address as a client of relaying services.
741+ *
742+ *************************************************************************/
743+int add_client(char *addr)
744+{
745+ struct pppoe_con* pc = (struct pppoe_con*)malloc(sizeof(struct pppoe_con));
746+ int ret;
747+ if(!pc)
748+ return -ENOMEM;
749+
750+ memset(pc, 0 , sizeof(struct pppoe_con));
751+
752+ memcpy(pc->client,addr, ETH_ALEN);
753+ memcpy(pc->key, addr, ETH_ALEN);
754+
755+ pc->key_len = ETH_ALEN;
756+
757+ if( (ret=store_con(pc)) < 0 ){
758+ free(pc);
759+ }
760+ return ret;
761+
762+}
763+
764+struct pppoe_tag *make_filter_tag(short type, short length, char* data){
765+ struct pppoe_tag *pt =
766+ (struct pppoe_tag* )malloc( sizeof(struct pppoe_tag) + length );
767+
768+ if(pt == NULL) return NULL;
769+
770+ pt->tag_len=htons(length);
771+ pt->tag_type=type;
772+
773+ if(length>0 && data){
774+ memcpy( pt+1, data, length);
775+ }
776+ return pt;
777+}
778diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppd_utils.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppd_utils.c
779--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppd_utils.c Wed Dec 31 19:00:00 1969
780+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppd_utils.c Sun Aug 6 11:39:28 2000
781@@ -0,0 +1,162 @@
782+/* PPPoE support library "libpppoe"
783+ *
784+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
785+ * Jamal Hadi Salim <hadi@cyberus.ca>
786+ *
787+ * This program is free software; you can redistribute it and/or
788+ * modify it under the terms of the GNU General Public License
789+ * as published by the Free Software Foundation; either version
790+ * 2 of the License, or (at your option) any later version.
791+ */
792+#include "pppoe.h"
793+
794+/*
795+ *
796+ */
797+int build_ppp_opts(char *args[],struct session *ses)
798+{
799+ char buf[256];
800+ int retval=0,i=0;
801+
802+ memset(buf,0,256);
803+
804+/* pppds path */
805+ if ( NULL != ses->filt->pppd){
806+ args[0]=(char *)malloc(strlen(ses->filt->pppd));
807+ strcpy (args[0],ses->filt->pppd);
808+ } else {
809+ args[0]=(char *)malloc(strlen(_PATH_PPPD));
810+ strcpy (args[0],_PATH_PPPD);
811+ }
812+
813+/* long device name */
814+ snprintf(buf, 256,"%02x:%02x:%02x:%02x:%02x:%02x/%04x/%s",
815+ ses->remote.sll_addr[0],
816+ ses->remote.sll_addr[1],
817+ ses->remote.sll_addr[2],
818+ ses->remote.sll_addr[3],
819+ ses->remote.sll_addr[4],
820+ ses->remote.sll_addr[5],
821+ ses->sp.sa_addr.pppoe.sid,
822+ ses->name);
823+ args[1]=(char *)malloc(strlen(buf));
824+ strcpy(args[1],buf);
825+
826+ i=2;
827+
828+/* override options file */
829+ if (NULL != ses->filt->fname ) {
830+
831+ if (!ses->filt->peermode) {
832+ args[i]=(char *)malloc(strlen("file"));
833+ strcpy (args[i],"file");
834+ i++;
835+ args[i]=(char *)malloc(strlen(ses->filt->fname)+1);
836+ strcpy (args[i],ses->filt->fname);
837+ i++;
838+ } else{ /* peermode */
839+ args[i]=(char *)malloc(strlen("call"));
840+ strcpy (args[i],"call");
841+ i++;
842+ args[i]=(char *)malloc(strlen(ses->filt->fname)+1);
843+ strcpy (args[i],ses->filt->fname);
844+ i++;
845+ }
846+ }
847+
848+/* user requested for a specific name */
849+ if (NULL != ses->filt->ntag) {
850+ if ( NULL != ses->filt->ntag->tag_data) {
851+ args[i]=(char *)malloc(strlen("pppoe_ac_name"));
852+ strcpy(args[i],"pppoe_ac_name");
853+ i++;
854+ args[i]=(char *)malloc(ntohs(ses->filt->ntag->tag_len));
855+ strcpy(args[i],ses->filt->ntag->tag_data);
856+ i++;
857+ }
858+ }
859+/* user requested for a specific service name */
860+ if (NULL != ses->filt->stag) {
861+ if ( NULL != ses->filt->stag->tag_data) {
862+ args[i]=(char *)malloc(strlen("pppoe_srv_name"));
863+ strcpy(args[i],"pppoe_srv_name");
864+ i++;
865+ args[i]=(char *)malloc(ntohs(ses->filt->stag->tag_len));
866+ strcpy(args[i],ses->filt->stag->tag_data);
867+ i++;
868+ }
869+ }
870+
871+/*
872+ */
873+ if (ses->opt_daemonize) {
874+ args[i]=(char *)malloc(strlen("nodetach"));
875+ strcpy(args[i],"nodetach");
876+ i++;
877+ }
878+
879+ args[i]=NULL;
880+ {
881+ int j;
882+ poe_info(ses,"calling pppd with %d args\n",i);
883+ j=i;
884+ for (i=0; i<j,NULL !=args[i]; i++) {
885+ poe_info(ses," <%d: %s > \n",i,args[i]);
886+ }
887+ }
888+ return retval;
889+}
890+
891+
892+/*
893+ *
894+ */
895+int ppp_connect (struct session *ses)
896+{
897+ int ret,pid;
898+ char *args[32];
899+
900+
901+ poe_info(ses,"calling ses_connect\n");
902+ do{
903+ ret = session_connect(ses);
904+ }while(ret == 0);
905+
906+ if (ret > 0 )
907+ if (ses->np == 1 && ret == 1)
908+ return ses->np; /* -G */
909+ if (ses->np == 2)
910+ return ses->np; /* -H */
911+
912+ if( ret <= 0){
913+ return ret;
914+ }
915+
916+ poe_info(ses,"DONE calling ses_connect np is %d \n",ses->np);
917+
918+
919+ pid = fork ();
920+ if (pid < 0) {
921+ poe_error (ses,"unable to fork() for pppd: %m");
922+ poe_die (-1);
923+ }
924+
925+
926+ if(!pid) {
927+ poe_info(ses,"calling build_ppp_opts\n");
928+ if (0> build_ppp_opts(args,ses)) {
929+ poe_error(ses,"ppp_connect: failed to build ppp_opts\n");
930+ return -1;
931+ }
932+ execvp(args[0],args);
933+ poe_info (ses," child got killed");
934+ } else if( ses->type == SESSION_CLIENT) {
935+ if (!ses->opt_daemonize)
936+ return 1;
937+ pause();
938+ poe_info (ses," OK we got killed");
939+ return -1;
940+ }
941+ return 1;
942+}
943+
944diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.c
945--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.c Wed Dec 31 19:00:00 1969
946+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.c Sat May 26 23:35:01 2001
947@@ -0,0 +1,385 @@
948+/* pppoe.c - pppd plugin to implement PPPoE protocol.
949+ *
950+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
951+ * Jamal Hadi Salim <hadi@cyberus.ca>
952+ * Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr.,
953+ * which is based in part on work from Jens Axboe and Paul Mackerras.
954+ *
955+ * This program is free software; you can redistribute it and/or
956+ * modify it under the terms of the GNU General Public License
957+ * as published by the Free Software Foundation; either version
958+ * 2 of the License, or (at your option) any later version.
959+ */
960+
961+#include <string.h>
962+#include <sys/ioctl.h>
963+#include <sys/types.h>
964+#include <sys/socket.h>
965+#include <unistd.h>
966+#include <errno.h>
967+#include <sys/stat.h>
968+#include "pppoe.h"
969+#if _linux_
970+extern int new_style_driver; /* From sys-linux.c */
971+#include <linux/ppp_defs.h>
972+#include <linux/if_pppox.h>
973+#include <linux/if_ppp.h>
974+#else
975+#error this module meant for use with linux only at this time
976+#endif
977+
978+
979+#include "pppd.h"
980+#include "fsm.h"
981+#include "lcp.h"
982+#include "ipcp.h"
983+#include "ccp.h"
984+#include "pathnames.h"
985+
986+const char pppd_version[] = VERSION;
987+
988+#define _PATH_ETHOPT _ROOT_PATH "/etc/ppp/options."
989+
990+#define PPPOE_MTU 1492
991+extern int kill_link;
992+static char *bad_options[] = {
993+ "noaccomp",
994+ "-ac",
995+ "default-asyncmap",
996+ "-am",
997+ "asyncmap",
998+ "-as",
999+ "escape",
1000+ "multilink",
1001+ "receive-all",
1002+ "crtscts",
1003+ "-crtscts",
1004+ "nocrtscts",
1005+ "cdtrcts",
1006+ "nocdtrcts",
1007+ "xonxoff",
1008+ "modem",
1009+ "local",
1010+ "sync",
1011+ "deflate",
1012+ "nodeflate",
1013+ "vj",
1014+ "novj",
1015+ "nobsdcomp",
1016+ "bsdcomp",
1017+ "-bsdcomp",
1018+ NULL
1019+};
1020+
1021+bool pppoe_server=0;
1022+char *pppoe_srv_name=NULL;
1023+char *pppoe_ac_name=NULL;
1024+char *hostuniq = NULL;
1025+int retries = 0;
1026+
1027+int setdevname_pppoe(const char *cp);
1028+
1029+static option_t pppoe_options[] = {
1030+ { "device name", o_wild, (void *) &setdevname_pppoe,
1031+ "Serial port device name",
1032+ OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC,
1033+ devnam},
1034+ { "pppoe_srv_name", o_string, &pppoe_srv_name,
1035+ "PPPoE service name"},
1036+ { "pppoe_ac_name", o_string, &pppoe_ac_name,
1037+ "PPPoE access concentrator name"},
1038+ { "pppoe_hostuniq", o_string, &hostuniq,
1039+ "PPPoE client uniq hostid "},
1040+ { "pppoe_retransmit", o_int, &retries,
1041+ "PPPoE client number of retransmit tries"},
1042+ { "pppoe_server", o_bool, &pppoe_server,
1043+ "PPPoE listen for incoming requests",1},
1044+ { NULL }
1045+};
1046+
1047+
1048+
1049+struct session *ses = NULL;
1050+static int connect_pppoe_ses(void)
1051+{
1052+ int i,err=-1;
1053+ if( pppoe_server == 1 ){
1054+ srv_init_ses(ses,devnam);
1055+ }else{
1056+ client_init_ses(ses,devnam);
1057+ }
1058+#if 0
1059+ ses->np=1; /* jamal debug the discovery portion */
1060+#endif
1061+ strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
1062+
1063+ err= session_connect ( ses );
1064+
1065+ if(err < 0){
1066+ poe_fatal(ses,"Failed to negotiate PPPoE connection: %d %m",errno,errno);
1067+ }
1068+
1069+
1070+ poe_info(ses,"Connecting PPPoE socket: %E %04x %s %p",
1071+ ses->sp.sa_addr.pppoe.remote,
1072+ ses->sp.sa_addr.pppoe.sid,
1073+ ses->sp.sa_addr.pppoe.dev,ses);
1074+
1075+ err = connect(ses->fd, (struct sockaddr*)&ses->sp,
1076+ sizeof(struct sockaddr_pppox));
1077+
1078+
1079+ if( err < 0 ){
1080+ poe_fatal(ses,"Failed to connect PPPoE socket: %d %m",errno,errno);
1081+ return err;
1082+ }
1083+#if 0
1084+ if (ses->np)
1085+ fatal("discovery complete\n");
1086+#endif
1087+ /* Once the logging is fixed, print a message here indicating
1088+ connection parameters */
1089+
1090+ return ses->fd;
1091+}
1092+
1093+static void disconnect_pppoe_ses(void)
1094+{
1095+ int ret;
1096+ warn("Doing disconnect");
1097+ session_disconnect(ses);
1098+ ses->sp.sa_addr.pppoe.sid = 0;
1099+ ret = connect(ses->fd, (struct sockaddr*)&ses->sp,
1100+ sizeof(struct sockaddr_pppox));
1101+
1102+}
1103+
1104+
1105+static int setspeed_pppoe(const char *cp)
1106+{
1107+ return 0;
1108+}
1109+
1110+static void init_device_pppoe(void)
1111+{
1112+ struct filter *filt;
1113+ unsigned int size=0;
1114+ ses=(void *)malloc(sizeof(struct session));
1115+ if(!ses){
1116+ fatal("No memory for new PPPoE session");
1117+ }
1118+ memset(ses,0,sizeof(struct session));
1119+
1120+ if ((ses->filt=malloc(sizeof(struct filter))) == NULL) {
1121+ poe_error (ses,"failed to malloc for Filter ");
1122+ poe_die (-1);
1123+ }
1124+
1125+ filt=ses->filt; /* makes the code more readable */
1126+ memset(filt,0,sizeof(struct filter));
1127+
1128+ if (pppoe_ac_name !=NULL) {
1129+ if (strlen (pppoe_ac_name) > 255) {
1130+ poe_error (ses," AC name too long (maximum allowed 256 chars)");
1131+ poe_die(-1);
1132+ }
1133+ ses->filt->ntag = make_filter_tag(PTT_AC_NAME,
1134+ strlen(pppoe_ac_name),
1135+ pppoe_ac_name);
1136+
1137+ if ( ses->filt->ntag== NULL) {
1138+ poe_error (ses,"failed to malloc for AC name");
1139+ poe_die(-1);
1140+ }
1141+
1142+ }
1143+
1144+
1145+ if (pppoe_srv_name !=NULL) {
1146+ if (strlen (pppoe_srv_name) > 255) {
1147+ poe_error (ses," Service name too long
1148+ (maximum allowed 256 chars)");
1149+ poe_die(-1);
1150+ }
1151+ ses->filt->stag = make_filter_tag(PTT_SRV_NAME,
1152+ strlen(pppoe_srv_name),
1153+ pppoe_srv_name);
1154+ if ( ses->filt->stag == NULL) {
1155+ poe_error (ses,"failed to malloc for service name");
1156+ poe_die(-1);
1157+ }
1158+ }
1159+
1160+ if (hostuniq) {
1161+ ses->filt->htag = make_filter_tag(PTT_HOST_UNIQ,
1162+ strlen(hostuniq),
1163+ hostuniq);
1164+ if ( ses->filt->htag == NULL) {
1165+ poe_error (ses,"failed to malloc for Uniq Host Id ");
1166+ poe_die(-1);
1167+ }
1168+ }
1169+
1170+ if (retries) {
1171+ ses->retries=retries;
1172+ }
1173+
1174+ memcpy( ses->name, devnam, IFNAMSIZ);
1175+ ses->opt_debug=1;
1176+}
1177+
1178+static void pppoe_extra_options()
1179+{
1180+ int ret;
1181+ char buf[256];
1182+ snprintf(buf, 256, _PATH_ETHOPT "%s",devnam);
1183+ if(!options_from_file(buf, 0, 0, 1))
1184+ exit(EXIT_OPTION_ERROR);
1185+
1186+}
1187+
1188+
1189+
1190+static void send_config_pppoe(int mtu,
1191+ u_int32_t asyncmap,
1192+ int pcomp,
1193+ int accomp)
1194+{
1195+ int sock;
1196+ struct ifreq ifr;
1197+
1198+ if (mtu > PPPOE_MTU)
1199+ warn("Couldn't increase MTU to %d", mtu);
1200+ sock = socket(AF_INET, SOCK_DGRAM, 0);
1201+ if (sock < 0)
1202+ fatal("Couldn't create IP socket: %m");
1203+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1204+ ifr.ifr_mtu = mtu;
1205+ if (ioctl(sock, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1206+ fatal("ioctl(SIOCSIFMTU): %m");
1207+ (void) close (sock);
1208+}
1209+
1210+
1211+static void recv_config_pppoe(int mru,
1212+ u_int32_t asyncmap,
1213+ int pcomp,
1214+ int accomp)
1215+{
1216+ if (mru > PPPOE_MTU)
1217+ error("Couldn't increase MRU to %d", mru);
1218+}
1219+
1220+static void set_xaccm_pppoe(int unit, ext_accm accm)
1221+{
1222+ /* NOTHING */
1223+}
1224+
1225+
1226+
1227+struct channel pppoe_channel;
1228+/* Check is cp is a valid ethernet device
1229+ * return either 1 if "cp" is a reasonable thing to name a device
1230+ * or die.
1231+ * Note that we don't actually open the device at this point
1232+ * We do need to fill in:
1233+ * devnam: a string representation of the device
1234+ */
1235+
1236+int (*old_setdevname_hook)(const char* cp) = NULL;
1237+int setdevname_pppoe(const char *cp)
1238+{
1239+ int ret;
1240+ char dev[IFNAMSIZ+1];
1241+ int addr[ETH_ALEN];
1242+ int sid;
1243+
1244+ char **a;
1245+ ret =sscanf(cp, FMTSTRING(IFNAMSIZ),addr, addr+1, addr+2,
1246+ addr+3, addr+4, addr+5,&sid,dev);
1247+ if( ret != 8 ){
1248+
1249+ ret = get_sockaddr_ll(cp,NULL);
1250+ if (ret < 0)
1251+ fatal("PPPoE: Cannot create PF_PACKET socket for PPPoE discovery\n");
1252+ if (ret == 1)
1253+ strncpy(devnam, cp, sizeof(devnam));
1254+ }else{
1255+ /* long form parsed */
1256+ ret = get_sockaddr_ll(dev,NULL);
1257+ if (ret < 0)
1258+ fatal("PPPoE: Cannot create PF_PACKET socket for PPPoE discovery\n");
1259+
1260+ strncpy(devnam, cp, sizeof(devnam));
1261+ ret = 1;
1262+ }
1263+
1264+
1265+ if( ret == 1 && the_channel != &pppoe_channel ){
1266+
1267+ the_channel = &pppoe_channel;
1268+
1269+ {
1270+ char **a;
1271+ for (a = bad_options; *a != NULL; a++)
1272+ remove_option(*a);
1273+ }
1274+ modem = 0;
1275+
1276+ lcp_allowoptions[0].neg_accompression = 0;
1277+ lcp_wantoptions[0].neg_accompression = 0;
1278+
1279+ lcp_allowoptions[0].neg_asyncmap = 0;
1280+ lcp_wantoptions[0].neg_asyncmap = 0;
1281+
1282+ lcp_allowoptions[0].neg_pcompression = 0;
1283+ lcp_wantoptions[0].neg_pcompression = 0;
1284+
1285+ ccp_allowoptions[0].deflate = 0 ;
1286+ ccp_wantoptions[0].deflate = 0 ;
1287+
1288+ ipcp_allowoptions[0].neg_vj=0;
1289+ ipcp_wantoptions[0].neg_vj=0;
1290+
1291+ ccp_allowoptions[0].bsd_compress = 0;
1292+ ccp_wantoptions[0].bsd_compress = 0;
1293+
1294+ init_device_pppoe();
1295+ }
1296+ return ret;
1297+}
1298+
1299+
1300+
1301+void plugin_init(void)
1302+{
1303+/*
1304+ fatal("PPPoE plugin loading...");
1305+*/
1306+
1307+#if _linux_
1308+ if (!ppp_available() && !new_style_driver)
1309+ fatal("Kernel doesn't support ppp_generic needed for PPPoE");
1310+#else
1311+ fatal("No PPPoE support on this OS");
1312+#endif
1313+ add_options(pppoe_options);
1314+
1315+
1316+ info("PPPoE Plugin Initialized");
1317+}
1318+
1319+struct channel pppoe_channel = {
1320+ options: pppoe_options,
1321+ process_extra_options: &pppoe_extra_options,
1322+ check_options: NULL,
1323+ connect: &connect_pppoe_ses,
1324+ disconnect: &disconnect_pppoe_ses,
1325+ establish_ppp: &generic_establish_ppp,
1326+ disestablish_ppp: &generic_disestablish_ppp,
1327+ send_config: &send_config_pppoe,
1328+ recv_config: &recv_config_pppoe,
1329+ close: NULL,
1330+ cleanup: NULL
1331+};
1332+
1333diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.h ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.h
1334--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.h Wed Dec 31 19:00:00 1969
1335+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.h Sat Mar 31 19:20:14 2001
1336@@ -0,0 +1,273 @@
1337+/* PPPoE support library "libpppoe"
1338+ *
1339+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
1340+ * Jamal Hadi Salim <hadi@cyberus.ca>
1341+ *
1342+ * This program is free software; you can redistribute it and/or
1343+ * modify it under the terms of the GNU General Public License
1344+ * as published by the Free Software Foundation; either version
1345+ * 2 of the License, or (at your option) any later version.
1346+ */
1347+
1348+#ifndef PPPOE_H
1349+#define PPPOE_H 1
1350+#include <stdio.h> /* stdio */
1351+#include <stdlib.h> /* strtoul(), realloc() */
1352+#include <unistd.h> /* STDIN_FILENO,exec */
1353+#include <string.h> /* memcpy() */
1354+#include <errno.h> /* errno */
1355+#include <signal.h>
1356+#include <getopt.h>
1357+#include <stdarg.h>
1358+#include <syslog.h>
1359+#include <paths.h>
1360+
1361+#include <sys/types.h> /* socket types */
1362+#include <asm/types.h>
1363+#include <sys/time.h>
1364+#include <sys/wait.h>
1365+#include <sys/fcntl.h>
1366+#include <sys/ioctl.h> /* ioctl() */
1367+#include <sys/select.h>
1368+#include <sys/socket.h> /* socket() */
1369+#include <net/if.h> /* ifreq struct */
1370+#include <net/if_arp.h>
1371+#include <netinet/in.h>
1372+
1373+#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
1374+#include <netpacket/packet.h>
1375+//#include <net/ethernet.h>
1376+#else
1377+#include <asm/types.h>
1378+#include <linux/if_packet.h>
1379+#include <linux/if_ether.h>
1380+#endif
1381+
1382+
1383+#include <asm/byteorder.h>
1384+
1385+/*
1386+ jamal: we really have to change this
1387+ to make it compatible to the 2.2 and
1388+ 2.3 kernel
1389+*/
1390+
1391+#include <linux/if_pppox.h>
1392+
1393+
1394+#define CONNECTED 1
1395+#define DISCONNECTED 0
1396+
1397+#ifndef _PATH_PPPD
1398+#define _PATH_PPPD "/usr/sbin/pppd"
1399+#endif
1400+
1401+#ifndef LOG_PPPOE
1402+#define LOG_PPPOE LOG_DAEMON
1403+#endif
1404+
1405+
1406+#define VERSION_MAJOR 0
1407+#define VERSION_MINOR 4
1408+#define VERSION_DATE 991120
1409+
1410+/* Bigger than the biggest ethernet packet we'll ever see, in bytes */
1411+#define MAX_PACKET 2000
1412+
1413+/* references: RFC 2516 */
1414+/* ETHER_TYPE fields for PPPoE */
1415+
1416+#define ETH_P_PPPOE_DISC 0x8863 /* discovery stage */
1417+#define ETH_P_PPPOE_SESS 0x8864
1418+
1419+/* ethernet broadcast address */
1420+#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff"
1421+
1422+/* Format for parsing long device-name */
1423+#define _STR(x) #x
1424+#define FMTSTRING(size) "%x:%x:%x:%x:%x:%x/%x/%" _STR(size) "s"
1425+
1426+/* maximum payload length */
1427+#define MAX_PAYLOAD 1484
1428+
1429+
1430+
1431+/* PPPoE tag types */
1432+#define MAX_TAGS 11
1433+
1434+
1435+/* PPPoE packet; includes Ethernet headers and such */
1436+struct pppoe_packet{
1437+ struct sockaddr_ll addr;
1438+ struct pppoe_tag *tags[MAX_TAGS];
1439+ struct pppoe_hdr *hdr;
1440+ char buf[MAX_PAYLOAD]; /* buffer in which tags are held */
1441+};
1442+/* Defines meaning of each "tags" element */
1443+
1444+#define TAG_SRV_NAME 0
1445+#define TAG_AC_NAME 1
1446+#define TAG_HOST_UNIQ 2
1447+#define TAG_AC_COOKIE 3
1448+#define TAG_VENDOR 4
1449+#define TAG_RELAY_SID 5
1450+#define TAG_SRV_ERR 6
1451+#define TAG_SYS_ERR 7
1452+#define TAG_GEN_ERR 8
1453+#define TAG_EOL 9
1454+
1455+static int tag_map[] = { PTT_SRV_NAME,
1456+ PTT_AC_NAME,
1457+ PTT_HOST_UNIQ,
1458+ PTT_AC_COOKIE,
1459+ PTT_VENDOR,
1460+ PTT_RELAY_SID,
1461+ PTT_SRV_ERR,
1462+ PTT_SYS_ERR,
1463+ PTT_GEN_ERR,
1464+ PTT_EOL
1465+};
1466+
1467+
1468+/* Debug flags */
1469+int DEB_DISC,DEB_DISC2;
1470+/*
1471+ #define DEB_DISC (opt_debug & 0x0002)
1472+ #define DEB_DISC2 (opt_debug & 0x0004)
1473+*/
1474+#define MAX_FNAME 256
1475+
1476+
1477+struct session;
1478+
1479+/* return <0 --> fatal error; abor
1480+ return =0 --> ok, proceed
1481+ return >0 --> ok, qui
1482+*/
1483+typedef int (*packet_cb_t)(struct session* ses,
1484+ struct pppoe_packet *p_in,
1485+ struct pppoe_packet **p_out);
1486+
1487+/* various override filter tags */
1488+struct filter {
1489+ struct pppoe_tag *stag; /* service name tag override */
1490+ struct pppoe_tag *ntag; /*AC name override */
1491+ struct pppoe_tag *htag; /* hostuniq override */
1492+ int num_restart;
1493+ int peermode;
1494+ char *fname;
1495+ char *pppd;
1496+} __attribute__ ((packed));
1497+
1498+
1499+struct pppoe_tag *make_filter_tag(short type, short length, char* data);
1500+
1501+/* Session type definitions */
1502+#define SESSION_CLIENT 0
1503+#define SESSION_SERVER 1
1504+#define SESSION_RELAY 2
1505+
1506+struct session {
1507+
1508+ /* Administrative */
1509+ int type;
1510+ int opt_debug;
1511+ int detached;
1512+ int np;
1513+ int log_to_fd;
1514+ int ifindex; /* index of device */
1515+ char name[IFNAMSIZ]; /*dev name */
1516+ struct pppoe_packet curr_pkt;
1517+
1518+ packet_cb_t init_disc;
1519+ packet_cb_t rcv_pado;
1520+ packet_cb_t rcv_padi;
1521+ packet_cb_t rcv_pads;
1522+ packet_cb_t rcv_padr;
1523+ packet_cb_t rcv_padt;
1524+ packet_cb_t timeout;
1525+
1526+
1527+ /* Generic */
1528+ struct filter *filt;
1529+ struct sockaddr_ll local;
1530+ struct sockaddr_ll remote;
1531+ struct sockaddr_pppox sp;
1532+ int fd; /* fd of PPPoE socket */
1533+
1534+
1535+ /* For client */
1536+ int retransmits; /* Number of retransmission performed
1537+ if < 0 , retransmissions disabled */
1538+ int retries;
1539+ int state;
1540+ int opt_daemonize;
1541+
1542+ /* For server */
1543+ int fork;
1544+
1545+ /* For forwarding */
1546+ int fwd_sock;
1547+ char fwd_name[IFNAMSIZ]; /* Name of device to forward to */
1548+} __attribute__ ((packed));
1549+
1550+/*
1551+ retransmit retries for the PADR and PADI packets
1552+ during discovery
1553+*/
1554+int PADR_ret;
1555+int PADI_ret;
1556+
1557+int log_to_fd;
1558+int ctrl_fd;
1559+int opt_debug;
1560+int opt_daemonize;
1561+
1562+
1563+/* Structure for keeping track of connection relays */
1564+struct pppoe_con{
1565+ struct pppoe_con *next;
1566+ int id;
1567+ int connected;
1568+ int cl_sock;
1569+ int sv_sock;
1570+ int ref_count;
1571+ char client[ETH_ALEN];
1572+ char server[ETH_ALEN];
1573+ char key_len;
1574+ char key[32];
1575+};
1576+
1577+/* Functions exported from utils.c. */
1578+
1579+/* Functions exported from pppoehash.c */
1580+struct pppoe_con *get_con(int len, char *key);
1581+int store_con(struct pppoe_con *pc);
1582+struct pppoe_con *delete_con(unsigned long len, char *key);
1583+
1584+/* exported by lib.c */
1585+
1586+extern int init_lib();
1587+
1588+extern int get_sockaddr_ll(const char *devnam,struct sockaddr_ll* sll);
1589+
1590+extern int client_init_ses (struct session *ses, char* devnam);
1591+extern int relay_init_ses(struct session *ses, char* from, char* to);
1592+extern int srv_init_ses(struct session *ses, char* from);
1593+extern int session_connect(struct session *ses);
1594+extern int session_disconnect(struct session*ses);
1595+
1596+extern int verify_packet( struct session *ses, struct pppoe_packet *p);
1597+
1598+extern void copy_tag(struct pppoe_packet *dest, struct pppoe_tag *pt);
1599+extern struct pppoe_tag *get_tag(struct pppoe_hdr *ph, u_int16_t idx);
1600+extern int send_disc(struct session *ses, struct pppoe_packet *p);
1601+
1602+
1603+extern int add_client(char *addr);
1604+
1605+/* Make connections (including spawning pppd) as server/client */
1606+extern ppp_connect(struct session *ses);
1607+
1608+
1609+#endif
1610Binary files ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe.so and ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe.so differ
1611diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_client.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_client.c
1612--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_client.c Wed Dec 31 19:00:00 1969
1613+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_client.c Sun Aug 6 11:39:28 2000
1614@@ -0,0 +1,232 @@
1615+/* PPPoE support library "libpppoe"
1616+ *
1617+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
1618+ * Jamal Hadi Salim <hadi@cyberus.ca>
1619+ *
1620+ * This program is free software; you can redistribute it and/or
1621+ * modify it under the terms of the GNU General Public License
1622+ * as published by the Free Software Foundation; either version
1623+ * 2 of the License, or (at your option) any later version.
1624+ */
1625+
1626+#include "pppoe.h"
1627+
1628+
1629+
1630+static int std_rcv_pado(struct session* ses,
1631+ struct pppoe_packet *p_in,
1632+ struct pppoe_packet **p_out){
1633+
1634+ if( verify_packet(ses, p_in) < 0)
1635+ return -1;
1636+
1637+ if(ses->state != PADO_CODE ){
1638+ poe_error(ses,"Unexpected packet: %P",p_in);
1639+ return 0;
1640+ }
1641+
1642+
1643+ if (DEB_DISC2) {
1644+ poe_dbglog (ses,"PADO received: %P", p_in);
1645+ }
1646+
1647+ memcpy(&ses->remote, &p_in->addr, sizeof(struct sockaddr_ll));
1648+ memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
1649+
1650+ ses->curr_pkt.hdr->code = PADR_CODE;
1651+
1652+ /* The HOST_UNIQ has been verified already... there's no "if" about this */
1653+ /* if(ses->filt->htag) */
1654+ copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_HOST_UNIQ));
1655+
1656+ if (ses->filt->ntag) {
1657+ ses->curr_pkt.tags[TAG_AC_NAME]=NULL;
1658+ }
1659+// copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_AC_NAME));
1660+
1661+ if(ses->filt->stag) {
1662+ ses->curr_pkt.tags[TAG_SRV_NAME]=NULL;
1663+ }
1664+ copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_SRV_NAME));
1665+
1666+ copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_AC_COOKIE));
1667+ copy_tag(&ses->curr_pkt,get_tag(p_in->hdr,PTT_RELAY_SID));
1668+
1669+ ses->state = PADS_CODE;
1670+
1671+ ses->retransmits = 0;
1672+
1673+ send_disc(ses, &ses->curr_pkt);
1674+ (*p_out) = &ses->curr_pkt;
1675+
1676+ if (ses->np)
1677+ return 1;
1678+
1679+ return 0;
1680+}
1681+
1682+static int std_init_disc(struct session* ses,
1683+ struct pppoe_packet *p_in,
1684+ struct pppoe_packet **p_out){
1685+
1686+ memset(&ses->curr_pkt,0, sizeof(struct pppoe_packet));
1687+
1688+
1689+ /* Check if already connected */
1690+ if( ses->state != PADO_CODE ){
1691+ return 1;
1692+ }
1693+
1694+ ses->curr_pkt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
1695+ ses->curr_pkt.hdr->ver = 1;
1696+ ses->curr_pkt.hdr->type = 1;
1697+ ses->curr_pkt.hdr->code = PADI_CODE;
1698+
1699+
1700+ memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
1701+
1702+ poe_info (ses,"Sending PADI");
1703+ if (DEB_DISC)
1704+ poe_dbglog (ses,"Sending PADI");
1705+
1706+ ses->retransmits = 0 ;
1707+
1708+ if(ses->filt->ntag) {
1709+ ses->curr_pkt.tags[TAG_AC_NAME]=ses->filt->ntag;
1710+ poe_info(ses,"overriding AC name\n");
1711+ }
1712+
1713+ if(ses->filt->stag)
1714+ ses->curr_pkt.tags[TAG_SRV_NAME]=ses->filt->stag;
1715+
1716+ if(ses->filt->htag)
1717+ ses->curr_pkt.tags[TAG_HOST_UNIQ]=ses->filt->htag;
1718+
1719+ send_disc(ses, &ses->curr_pkt);
1720+ (*p_out)= &ses->curr_pkt;
1721+ return 0;
1722+}
1723+
1724+
1725+static int std_rcv_pads(struct session* ses,
1726+ struct pppoe_packet *p_in,
1727+ struct pppoe_packet **p_out){
1728+ if( verify_packet(ses, p_in) < 0)
1729+ return -1;
1730+
1731+ if (DEB_DISC)
1732+ poe_dbglog (ses,"Got connection: %x",
1733+ ntohs(p_in->hdr->sid));
1734+ poe_info (ses,"Got connection: %x", ntohs(p_in->hdr->sid));
1735+
1736+ ses->sp.sa_family = AF_PPPOX;
1737+ ses->sp.sa_protocol = PX_PROTO_OE;
1738+ ses->sp.sa_addr.pppoe.sid = p_in->hdr->sid;
1739+ memcpy(ses->sp.sa_addr.pppoe.dev,ses->name, IFNAMSIZ);
1740+ memcpy(ses->sp.sa_addr.pppoe.remote, p_in->addr.sll_addr, ETH_ALEN);
1741+
1742+
1743+ return 1;
1744+}
1745+
1746+static int std_rcv_padt(struct session* ses,
1747+ struct pppoe_packet *p_in,
1748+ struct pppoe_packet **p_out){
1749+ ses->state = PADO_CODE;
1750+ return 0;
1751+}
1752+
1753+
1754+extern int disc_sock;
1755+int client_init_ses (struct session *ses, char* devnam)
1756+{
1757+ int i=0;
1758+ int retval;
1759+ char dev[IFNAMSIZ+1];
1760+ int addr[ETH_ALEN];
1761+ int sid;
1762+
1763+ /* do error checks here; session name etc are valid */
1764+// poe_info (ses,"init_ses: creating socket");
1765+
1766+ /* Make socket if necessary */
1767+ if( disc_sock < 0 ){
1768+
1769+ disc_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
1770+ if( disc_sock < 0 ){
1771+ poe_fatal(ses,
1772+ "Cannot create PF_PACKET socket for PPPoE discovery\n");
1773+ }
1774+
1775+ }
1776+
1777+ /* Check for long format */
1778+ retval =sscanf(devnam, FMTSTRING(IFNAMSIZ),addr, addr+1, addr+2,
1779+ addr+3, addr+4, addr+5,&sid,dev);
1780+ if( retval != 8 ){
1781+ /* Verify the device name , construct ses->local */
1782+ retval = get_sockaddr_ll(devnam,&ses->local);
1783+ if (retval < 0)
1784+ poe_fatal(ses, "client_init_ses: "
1785+ "Cannot create PF_PACKET socket for PPPoE discovery\n");
1786+
1787+
1788+ ses->state = PADO_CODE;
1789+ memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
1790+
1791+ memset( ses->remote.sll_addr, 0xff, ETH_ALEN);
1792+ }else{
1793+ /* long form parsed */
1794+
1795+ /* Verify the device name , construct ses->local */
1796+ retval = get_sockaddr_ll(dev,&ses->local);
1797+ if (retval < 0)
1798+ poe_fatal(ses,"client_init_ses(2): "
1799+ "Cannot create PF_PACKET socket for PPPoE discovery\n");
1800+ ses->state = PADS_CODE;
1801+ ses->sp.sa_family = AF_PPPOX;
1802+ ses->sp.sa_protocol = PX_PROTO_OE;
1803+ ses->sp.sa_addr.pppoe.sid = sid;
1804+
1805+ memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
1806+
1807+ for(; i < ETH_ALEN ; ++i ){
1808+ ses->sp.sa_addr.pppoe.remote[i] = addr[i];
1809+ ses->remote.sll_addr[i]=addr[i];
1810+ }
1811+ memcpy(ses->sp.sa_addr.pppoe.dev, dev, IFNAMSIZ);
1812+
1813+
1814+
1815+ }
1816+ if( retval < 0 )
1817+ error("bad device name: %s",devnam);
1818+
1819+
1820+ retval = bind( disc_sock ,
1821+ (struct sockaddr*)&ses->local,
1822+ sizeof(struct sockaddr_ll));
1823+
1824+
1825+ if( retval < 0 ){
1826+ error("bind to PF_PACKET socket failed: %m");
1827+ }
1828+
1829+ ses->fd = socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_OE);
1830+ if(ses->fd < 0)
1831+ {
1832+ poe_fatal(ses,"Failed to create PPPoE socket: %m");
1833+ }
1834+
1835+
1836+ ses->init_disc = std_init_disc;
1837+ ses->rcv_pado = std_rcv_pado;
1838+ ses->rcv_pads = std_rcv_pads;
1839+ ses->rcv_padt = std_rcv_padt;
1840+
1841+ /* this should be filter overridable */
1842+ ses->retries = 10;
1843+
1844+ return ses->fd;
1845+}
1846+
1847diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_relay.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_relay.c
1848--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_relay.c Wed Dec 31 19:00:00 1969
1849+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_relay.c Sun Aug 6 11:39:28 2000
1850@@ -0,0 +1,260 @@
1851+/* PPPoE support library "libpppoe"
1852+ *
1853+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
1854+ * Jamal Hadi Salim <hadi@cyberus.ca>
1855+ *
1856+ * This program is free software; you can redistribute it and/or
1857+ * modify it under the terms of the GNU General Public License
1858+ * as published by the Free Software Foundation; either version
1859+ * 2 of the License, or (at your option) any later version.
1860+ */
1861+
1862+#include "pppoe.h"
1863+
1864+static int relay_init_disc(struct session* ses,
1865+ struct pppoe_packet *p_in,
1866+ struct pppoe_packet **p_out){
1867+
1868+ ses->state = 0;
1869+ ses->retransmits = -1 ;
1870+ ses->retries = -1;
1871+
1872+ (*p_out) = NULL;
1873+ return 0;
1874+}
1875+
1876+static int pcid=0;
1877+static int relay_rcv_padi(struct session* ses,
1878+ struct pppoe_packet *p_in,
1879+ struct pppoe_packet **p_out){
1880+ char tag_buf[32];
1881+ struct pppoe_con *newpc = NULL;
1882+ struct pppoe_tag *tag = (struct pppoe_tag *) tag_buf;
1883+
1884+
1885+ tag->tag_type = PTT_RELAY_SID;
1886+ tag->tag_len = htons(ETH_ALEN + sizeof(struct session *));
1887+
1888+ memcpy(tag->tag_data, p_in->addr.sll_addr, ETH_ALEN);
1889+ memcpy(tag->tag_data + ETH_ALEN, &ses, sizeof(struct session *));
1890+
1891+ if(! p_in->tags[TAG_RELAY_SID] ){
1892+ copy_tag(p_in, tag);
1893+ }
1894+
1895+
1896+ poe_dbglog(ses, "Recv'd PADI: %P",p_in);
1897+ poe_dbglog(ses, "Recv'd packet: %P",p_in);
1898+ newpc = get_con( ntohs(tag->tag_len), tag->tag_data );
1899+ if(!newpc){
1900+
1901+ newpc = (struct pppoe_con *) malloc(sizeof(struct pppoe_con));
1902+ memset(newpc , 0, sizeof(struct pppoe_con));
1903+
1904+ newpc->id = pcid++;
1905+
1906+ newpc->key_len = ntohs(p_in->tags[TAG_RELAY_SID]->tag_len);
1907+ memcpy(newpc->key, p_in->tags[TAG_RELAY_SID]->tag_data, newpc->key_len);
1908+ memcpy(newpc->client, p_in->addr.sll_addr, ETH_ALEN);
1909+
1910+ memcpy(newpc->server, MAC_BCAST_ADDR, ETH_ALEN);
1911+
1912+ store_con(newpc);
1913+
1914+ }
1915+
1916+ ++newpc->ref_count;
1917+
1918+ memset(p_in->addr.sll_addr, 0xff, ETH_ALEN);
1919+
1920+ p_in->addr.sll_ifindex = ses->remote.sll_ifindex;
1921+
1922+ send_disc(ses, p_in);
1923+ return 0;
1924+}
1925+
1926+static int relay_rcv_pkt(struct session* ses,
1927+ struct pppoe_packet *p_in,
1928+ struct pppoe_packet **p_out){
1929+ struct pppoe_con *pc;
1930+ char tag_buf[32];
1931+ struct pppoe_tag *tag = p_in->tags[TAG_RELAY_SID];
1932+
1933+ if( !tag ) return 0;
1934+
1935+ pc = get_con(ntohs(tag->tag_len),tag->tag_data);
1936+
1937+ if( !pc ) return 0;
1938+
1939+ poe_dbglog(ses, "Recv'd packet: %P",p_in);
1940+
1941+ if( memcmp(pc->client , p_in->addr.sll_addr , ETH_ALEN ) == 0 ){
1942+
1943+ memcpy(p_in->addr.sll_addr, pc->server, ETH_ALEN);
1944+ p_in->addr.sll_ifindex = ses->remote.sll_ifindex;
1945+
1946+ }else{
1947+ if( memcmp(pc->server, MAC_BCAST_ADDR, ETH_ALEN) == 0 ){
1948+ memcpy(pc->server, p_in->addr.sll_addr, ETH_ALEN);
1949+
1950+ }else if( memcmp(pc->server, p_in->addr.sll_addr, ETH_ALEN) !=0){
1951+ return 0;
1952+ }
1953+
1954+ memcpy(p_in->addr.sll_addr, pc->client, ETH_ALEN);
1955+ p_in->addr.sll_ifindex = ses->local.sll_ifindex;
1956+
1957+
1958+ }
1959+
1960+
1961+ send_disc(ses, p_in);
1962+ return 0;
1963+}
1964+
1965+static int relay_rcv_pads(struct session* ses,
1966+ struct pppoe_packet *p_in,
1967+ struct pppoe_packet **p_out){
1968+
1969+ struct pppoe_con *pc;
1970+ char tag_buf[32];
1971+ struct pppoe_tag *tag = p_in->tags[TAG_RELAY_SID];
1972+ struct sockaddr_pppox sp_cl= { AF_PPPOX, PX_PROTO_OE,
1973+ { p_in->hdr->sid, {0,},{0,}}};
1974+
1975+ struct sockaddr_pppox sp_sv= { AF_PPPOX, PX_PROTO_OE,
1976+ { p_in->hdr->sid, {0,},{0,}}};
1977+
1978+ int ret;
1979+
1980+
1981+ if( !tag ) return 0;
1982+
1983+ pc = get_con(ntohs(tag->tag_len),tag->tag_data);
1984+
1985+ if( !pc ) return 0;
1986+
1987+
1988+ if(!pc->connected){
1989+
1990+ pc->sv_sock = socket( AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
1991+ if( pc->sv_sock < 0){
1992+ poe_fatal(ses,"Cannot open PPPoE socket: %i",errno);
1993+ }
1994+
1995+ pc->cl_sock = socket( AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
1996+ if( pc->cl_sock < 0){
1997+ poe_fatal(ses,"Cannot open PPPoE socket: %i",errno);
1998+ }
1999+
2000+ memcpy( sp_sv.sa_addr.pppoe.dev, ses->fwd_name, IFNAMSIZ);
2001+ memcpy( sp_sv.sa_addr.pppoe.remote, pc->server, ETH_ALEN);
2002+
2003+ ret = connect( pc->sv_sock,
2004+ (struct sockaddr*)&sp_sv,
2005+ sizeof(struct sockaddr_pppox));
2006+ if( ret < 0){
2007+ poe_fatal(ses,"Cannot connect PPPoE socket: %i",errno);
2008+ }
2009+
2010+ memcpy( sp_cl.sa_addr.pppoe.dev, ses->name, IFNAMSIZ);
2011+ memcpy( sp_cl.sa_addr.pppoe.remote, pc->client, ETH_ALEN);
2012+
2013+ ret = connect( pc->cl_sock,
2014+ (struct sockaddr*)&sp_cl,
2015+ sizeof(struct sockaddr_pppox));
2016+ if( ret < 0){
2017+ poe_fatal(ses,"Cannot connect PPPoE socket: %i",errno);
2018+ }
2019+
2020+
2021+ ret = ioctl( pc->sv_sock, PPPOEIOCSFWD, &sp_cl);
2022+ if( ret < 0){
2023+ poe_fatal(ses,"Cannot set forwarding on PPPoE socket: %i",errno);
2024+ }
2025+
2026+ ret = ioctl( pc->cl_sock, PPPOEIOCSFWD, &sp_sv);
2027+ if( ret < 0){
2028+ poe_fatal(ses,"Cannot set forwarding on PPPoE socket: %i",errno);
2029+ }
2030+
2031+ pc->connected = 1;
2032+ }
2033+
2034+ poe_info(ses,"PPPoE relay for %E established to %E (sid=%04x)\n",
2035+ pc->client,pc->server, p_in->hdr->sid);
2036+
2037+ return relay_rcv_pkt(ses,p_in,p_out);
2038+}
2039+
2040+
2041+static int relay_rcv_padt(struct session* ses,
2042+ struct pppoe_packet *p_in,
2043+ struct pppoe_packet **p_out){
2044+
2045+ int ret;
2046+ struct pppoe_con *pc;
2047+ char tag_buf[32];
2048+ struct pppoe_tag *tag = p_in->tags[TAG_RELAY_SID];
2049+
2050+ if( !tag ) return 0;
2051+
2052+ pc = get_con(ntohs(tag->tag_len),tag->tag_data);
2053+
2054+ if( !pc ) return 0;
2055+
2056+ ret = relay_rcv_pkt(ses,p_in,p_out);
2057+
2058+
2059+ if(pc->cl_sock>0){
2060+ close(pc->cl_sock);
2061+ }
2062+
2063+ if(pc->sv_sock>0){
2064+ close(pc->sv_sock);
2065+ }
2066+
2067+ --pc->ref_count;
2068+ if( pc->ref_count == 0 ){
2069+ delete_con(pc->key_len, pc->key);
2070+
2071+ free(pc);
2072+ }
2073+}
2074+
2075+
2076+int relay_init_ses(struct session *ses, char* from, char* to)
2077+{
2078+ int retval = client_init_ses(ses, from);
2079+
2080+ if(retval<0) return retval;
2081+
2082+ ses->fwd_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
2083+ if( ses->fwd_sock < 0 ) {
2084+ poe_fatal(ses,"Cannot create PF_PACKET socket for PPPoE forwarding\n");
2085+ }
2086+
2087+ /* Verify the device name , construct ses->local */
2088+ retval = get_sockaddr_ll(to, &ses->remote);
2089+ if (retval < 0)
2090+ poe_fatal(ses,"relay_init_ses:get_sockaddr_ll failed %m");
2091+
2092+ retval = bind( ses->fwd_sock ,
2093+ (struct sockaddr*)&ses->remote,
2094+ sizeof(struct sockaddr_ll));
2095+
2096+ if( retval < 0 ){
2097+ poe_fatal(ses,"bind to PF_PACKET socket failed: %m");
2098+ }
2099+
2100+ memcpy(ses->fwd_name, to, IFNAMSIZ);
2101+ memcpy(ses->name, from, IFNAMSIZ);
2102+
2103+
2104+ ses->init_disc = relay_init_disc;
2105+ ses->rcv_padi = relay_rcv_padi;
2106+ ses->rcv_pado = relay_rcv_pkt;
2107+ ses->rcv_padr = relay_rcv_pkt;
2108+ ses->rcv_pads = relay_rcv_pads;
2109+ ses->rcv_padt = relay_rcv_padt;
2110+}
2111diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_server.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_server.c
2112--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoe_server.c Wed Dec 31 19:00:00 1969
2113+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoe_server.c Sun Aug 6 11:39:28 2000
2114@@ -0,0 +1,143 @@
2115+/* PPPoE support library "libpppoe"
2116+ *
2117+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
2118+ * Jamal Hadi Salim <hadi@cyberus.ca>
2119+ *
2120+ * This program is free software; you can redistribute it and/or
2121+ * modify it under the terms of the GNU General Public License
2122+ * as published by the Free Software Foundation; either version
2123+ * 2 of the License, or (at your option) any later version.
2124+ */
2125+#include "pppoe.h"
2126+#include <unistd.h>
2127+
2128+static unsigned int pcid=1111;
2129+static int srv_rcv_padi(struct session* ses,
2130+ struct pppoe_packet *p_in,
2131+ struct pppoe_packet **p_out){
2132+ struct pppoe_con *newpc = NULL;
2133+ struct pppoe_tag *tag;
2134+
2135+ poe_dbglog(ses,"Srv Recv'd packet: %P\n",p_in);
2136+
2137+
2138+ ses->curr_pkt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
2139+ ses->curr_pkt.hdr->ver = 1;
2140+ ses->curr_pkt.hdr->type = 1;
2141+
2142+ tag = get_tag(p_in->hdr,PTT_SRV_NAME);
2143+
2144+ if(!tag )
2145+ return 0;
2146+
2147+ if( ntohs(tag->tag_len)==0 ){
2148+ ses->curr_pkt.tags[TAG_SRV_NAME] = ses->filt->stag ;
2149+ }else if( tag->tag_len != ses->filt->stag->tag_len
2150+ || !memcmp( tag+1, ses->filt->stag, ntohs(tag->tag_len)) ){
2151+ return 0;
2152+ }else{
2153+ ses->curr_pkt.tags[TAG_SRV_NAME] = tag;
2154+ }
2155+
2156+ ses->curr_pkt.tags[ TAG_AC_NAME] = ses->filt->ntag ;
2157+ ses->curr_pkt.tags[ TAG_HOST_UNIQ ] = get_tag(p_in->hdr,PTT_HOST_UNIQ);
2158+
2159+ memcpy(&ses->remote, &p_in->addr, sizeof(struct sockaddr_ll));
2160+ memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
2161+
2162+ ses->curr_pkt.hdr->code = PADO_CODE;
2163+
2164+
2165+ ses->curr_pkt.tags[ TAG_RELAY_SID ] = get_tag(p_in->hdr,PTT_RELAY_SID);
2166+
2167+ send_disc(ses, &ses->curr_pkt);
2168+ poe_dbglog(ses,"Srv Sent packet: %P\n",&ses->curr_pkt);
2169+
2170+ return 0;
2171+}
2172+
2173+
2174+static int srv_rcv_padr(struct session* ses,
2175+ struct pppoe_packet *p_in,
2176+ struct pppoe_packet **p_out){
2177+ struct pppoe_tag *tag;
2178+
2179+ poe_dbglog(ses,"Recv'd packet: %P\n",p_in);
2180+
2181+
2182+
2183+ /* Run checks to ensure this packets asks for
2184+ what we're willing to offer */
2185+
2186+ tag = get_tag(p_in->hdr,PTT_SRV_NAME);
2187+
2188+ if(!tag || tag->tag_len == 0 ){
2189+ p_in->tags[TAG_SRV_NAME] = ses->filt->stag;
2190+
2191+ }else if( tag->tag_len != ses->filt->stag->tag_len
2192+ || !memcmp(tag + 1 , ses->filt->stag, ntohs(tag->tag_len)) ){
2193+ return 0;
2194+ }else{
2195+ p_in->tags[TAG_SRV_NAME] = tag;
2196+ }
2197+
2198+ tag = get_tag(p_in->hdr,PTT_AC_NAME);
2199+ if( !tag || tag->tag_len==0 ){
2200+ p_in->tags[TAG_AC_NAME] = ses->filt->ntag;
2201+ }else if( tag->tag_len != ses->filt->ntag->tag_len
2202+ || !memcmp(tag + 1, ses->filt->ntag, ntohs(tag->tag_len)) ){
2203+ return 0;
2204+ }else{
2205+ p_in->tags[TAG_AC_NAME] = tag;
2206+ }
2207+
2208+
2209+
2210+
2211+ pcid = ++pcid & 0x0000ffff ;
2212+ if(pcid == 0 ){
2213+ pcid = 1111;
2214+ }
2215+
2216+ p_in->hdr->sid = ntohs(pcid);
2217+
2218+ p_in->hdr->code = PADS_CODE;
2219+ send_disc(ses, p_in);
2220+
2221+ poe_dbglog(ses,"Sent packet: %P\n",p_in);
2222+
2223+ ses->sp.sa_family = AF_PPPOX;
2224+ ses->sp.sa_protocol=PX_PROTO_OE;
2225+ ses->sp.sa_addr.pppoe.sid = p_in->hdr->sid;
2226+ memcpy(ses->sp.sa_addr.pppoe.dev, ses->name, IFNAMSIZ);
2227+ memcpy(ses->sp.sa_addr.pppoe.remote, p_in->addr.sll_addr, ETH_ALEN);
2228+ memcpy(&ses->remote, &p_in->addr, sizeof(struct sockaddr_ll));
2229+ return 1;
2230+}
2231+
2232+static int srv_rcv_padt(struct session* ses,
2233+ struct pppoe_packet *p_in,
2234+ struct pppoe_packet **p_out){
2235+ return 0;
2236+}
2237+
2238+
2239+
2240+int srv_init_ses(struct session *ses, char* from)
2241+{
2242+ int retval;
2243+ retval = client_init_ses(ses, from);
2244+ ses->init_disc = NULL;
2245+ ses->rcv_pado = NULL;
2246+ ses->rcv_pads = NULL;
2247+ ses->rcv_padi = srv_rcv_padi;
2248+ ses->rcv_padr = srv_rcv_padr;
2249+ ses->rcv_padt = srv_rcv_padt;
2250+
2251+ /* retries forever */
2252+ ses->retries = -1;
2253+
2254+ return retval;
2255+}
2256+
2257+
2258Binary files ppp-2.4.1.orig/pppd/plugins/pppoe/pppoed and ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoed differ
2259diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoed.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoed.c
2260--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoed.c Wed Dec 31 19:00:00 1969
2261+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoed.c Sun Aug 6 11:39:28 2000
2262@@ -0,0 +1,283 @@
2263+/* PPPoE support library "libpppoe"
2264+ *
2265+ * Copyright 2000 Jamal Hadi Salim <hadi@cyberus.ca>
2266+ *
2267+ * This program is free software; you can redistribute it and/or
2268+ * modify it under the terms of the GNU General Public License
2269+ * as published by the Free Software Foundation; either version
2270+ * 2 of the License, or (at your option) any later version.
2271+ */
2272+
2273+#include "pppoe.h"
2274+
2275+int detached=1;
2276+void
2277+sigproc (int src)
2278+{
2279+ int i;
2280+ fprintf (stderr,"Received signal %d", src);
2281+}
2282+
2283+void
2284+sigchild (int src)
2285+{
2286+ pid_t pid;
2287+ int status;
2288+ int i;
2289+ pid = waitpid (-1, &status, WNOHANG);
2290+
2291+ if (!detached)
2292+ fprintf (stderr,"Child received signal %d PID %d, status %d", src, pid, status);
2293+ if (pid < 1) {
2294+ return;
2295+ }
2296+}
2297+
2298+void
2299+print_help ()
2300+{
2301+
2302+ fprintf (stdout,"\npppoe version %d.%d build %d", VERSION_MAJOR, VERSION_MINOR,
2303+ VERSION_DATE);
2304+ fprintf (stdout,"\nrecognized options are:");
2305+ fprintf (stdout,"\n -I <interface> : overrides the default interface of eth0");
2306+ fprintf (stdout,"\n -S : starts pppoed in server mode");
2307+ fprintf (stdout,"\n -R <num_retries>: forces pppoed to be restarted num_retries");
2308+ fprintf (stdout,"\n should the other end be detected to be dead.");
2309+ fprintf (stdout,"\n Needs lcp_echo. Read the INSTALL file instructions");
2310+ fprintf (stdout,"\n -F <filename> : specifies additional ppp options file");
2311+ fprintf (stdout,"\n -C <filename> : ppp options file in /etc/ppp/peers/");
2312+ fprintf (stdout,"\n -d <level> : sets debug level");
2313+ fprintf (stdout,"\n -D : prevents pppoed from detaching itself and running in the background");
2314+ fprintf (stdout,"\n -P <path to pppd> : selects a different pppd. Defaults to " _PATH_PPPD);
2315+ fprintf (stdout,"\n -A <AC name> to select a specific AC by name");
2316+ fprintf (stdout,"\n -E <AC service name> to select a specific AC service by name");
2317+ fprintf (stdout,"\n -G Do service discovery only");
2318+ fprintf (stdout,"\n -H Do service discovery and connection (no pppd)\n");
2319+}
2320+
2321+
2322+int
2323+get_args (int argc, char **argv,struct session *sess)
2324+{
2325+ struct filter *filt;
2326+ struct host_tag *tg;
2327+ int opt;
2328+
2329+
2330+ sess->opt_debug = 0;
2331+ DEB_DISC=0;
2332+ DEB_DISC2=0;
2333+ sess->log_to_fd = 1;
2334+ sess->np = 0;
2335+ sess->opt_daemonize = 0;
2336+
2337+ sess->log_to_fd = fileno (stdout);
2338+
2339+/* defaults to eth0 */
2340+ strcpy (sess->name, "eth0");
2341+
2342+
2343+ if ((sess->filt=malloc(sizeof(struct filter))) == NULL) {
2344+ poe_error (sess,"failed to malloc for Filter ");
2345+ poe_die (-1);
2346+ }
2347+
2348+ filt=sess->filt; /* makes the code more readable */
2349+ memset(filt,0,sizeof(struct filter));
2350+
2351+ filt->num_restart=1;
2352+
2353+/* set default filters; move this to routine */
2354+ /* parse options */
2355+
2356+ while ((opt = getopt (argc, argv, "A:C:E:d:DR:I:F:L:V:P:SN:GH")) != -1)
2357+
2358+ switch (opt) {
2359+ case 'R': /* sets number of retries */
2360+ filt->num_restart = strtol (optarg, (char **) NULL, 10);
2361+ filt->num_restart += 1;
2362+ break;
2363+ case 'I': /* sets interface */
2364+ if (strlen (optarg) >= IFNAMSIZ) {
2365+ poe_error (sess,"interface name cannot exceed %d characters", IFNAMSIZ - 1);
2366+ return (-1);
2367+ }
2368+ strncpy (sess->name, optarg, strlen(optarg)+1);
2369+ break;
2370+ case 'C': /* name of the file in /etc/ppp/peers */
2371+ if (NULL != filt->fname) {
2372+ poe_error (sess,"-F can not be used with -C");
2373+ return (-1);
2374+ }
2375+ if (strlen(optarg) > MAX_FNAME) {
2376+ poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
2377+ return (-1);
2378+ }
2379+ filt->fname=malloc(strlen(optarg));
2380+ strncpy (filt->fname, optarg, strlen(optarg));
2381+ filt->peermode=1;
2382+ break;
2383+ case 'F': /* sets the options file */
2384+ if (NULL != filt->fname) {
2385+ poe_error (sess,"-F can not be used with -C");
2386+ return (-1);
2387+ }
2388+
2389+ if (strlen(optarg) > MAX_FNAME) {
2390+ poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
2391+ return (-1);
2392+ }
2393+ filt->fname=malloc(strlen(optarg)+1);
2394+ strncpy (filt->fname, optarg, strlen(optarg)+1);
2395+
2396+ poe_info (sess,"selected %s as filename\n",filt->fname);
2397+ break;
2398+ case 'D': /* don't daemonize */
2399+ sess->opt_daemonize = 1;
2400+ detached=0;
2401+ break;
2402+ case 'd': /* debug level */
2403+ sess->opt_debug = strtol (optarg, (char **) NULL, 10);
2404+ if (sess->opt_debug & 0x0002)
2405+ DEB_DISC=1;
2406+ if (sess->opt_debug & 0x0004)
2407+ DEB_DISC2=1;
2408+ break;
2409+ case 'P': /* sets the pppd binary */
2410+ if (strlen(optarg) > MAX_FNAME) {
2411+ poe_error (sess,"pppd binary cant exceed %d characters", MAX_FNAME - 1);
2412+ return (-1);
2413+ }
2414+ filt->pppd=malloc(strlen(optarg));
2415+ strncpy (filt->pppd, optarg, strlen(optarg));
2416+ break;
2417+ case 'H':
2418+ sess->np = 2;
2419+ break;
2420+ case 'G':
2421+ sess->np = 1;
2422+ break;
2423+ case 'V': /* version */
2424+ fprintf (stdout,"pppoe version %d.%d build %d", VERSION_MAJOR,
2425+ VERSION_MINOR, VERSION_DATE);
2426+ return (0);
2427+ case 'S': /* server mode */
2428+ sess->type = SESSION_SERVER;
2429+ break;
2430+ case 'A': /* AC override */
2431+ poe_info (sess,"AC name override to %s", optarg);
2432+ if (strlen (optarg) > 255) {
2433+ poe_error (sess," AC name too long
2434+ (maximum allowed 256 chars)");
2435+ poe_die(-1);
2436+ }
2437+ if ((sess->filt->ntag= malloc (sizeof (struct pppoe_tag) +
2438+ strlen (optarg)))== NULL) {
2439+ poe_error (sess,"failed to malloc for AC name");
2440+ poe_die(-1);
2441+ }
2442+ sess->filt->ntag->tag_len=htons(strlen(optarg));
2443+ sess->filt->ntag->tag_type=PTT_AC_NAME;
2444+ poe_error (sess," pppoe_ac_name: AC name Override %p\n",
2445+ sess->filt->ntag);
2446+ strcpy(sess->filt->ntag->tag_data,optarg);
2447+ break;
2448+ case 'E': /* AC service name override */
2449+ poe_info (sess,"AC service name override to %s", optarg);
2450+ if (strlen (optarg) > 255) {
2451+ poe_error (sess," Service name too long
2452+ (maximum allowed 256 chars)");
2453+ poe_die(-1);
2454+ }
2455+
2456+ if ((filt->stag = malloc (strlen (optarg) + sizeof (struct pppoe_tag))) == NULL) {
2457+ poe_error (sess,"failed to malloc for service name: %m");
2458+ return (-1);
2459+ }
2460+
2461+ filt->stag->tag_len = htons (strlen (optarg));
2462+ filt->stag->tag_type = PTT_SRV_NAME;
2463+ strcpy ((char *) (filt->stag->tag_data), optarg);
2464+ break;
2465+ default:
2466+ poe_error (sess,"Unknown option '%c'", optopt);
2467+ print_help ();
2468+ return (-1);
2469+ }
2470+
2471+
2472+ return (1);
2473+
2474+}
2475+
2476+
2477+int main(int argc, char** argv){
2478+ int ret;
2479+ struct filter *filt;
2480+ struct session *ses = (struct session *)malloc(sizeof(struct session));
2481+ char buf[256];
2482+ ses=(void *)malloc(sizeof(struct session));
2483+
2484+ if(!ses){
2485+ return -1;
2486+ }
2487+ memset(ses,0,sizeof(struct session));
2488+
2489+
2490+
2491+ openlog ("pppoed", LOG_PID | LOG_NDELAY, LOG_PPPOE);
2492+ setlogmask (LOG_UPTO (ses->opt_debug ? LOG_DEBUG : LOG_INFO));
2493+
2494+
2495+ if ((get_args (argc,(char **) argv,ses)) <1)
2496+ poe_die(-1);
2497+
2498+ filt=ses->filt; /* makes the code more readable */
2499+
2500+ if (!ses->np) {
2501+ poe_create_pidfile (ses);
2502+// signal (SIGINT, &sigproc);
2503+// signal (SIGTERM, &sigproc);
2504+ signal (SIGCHLD, &sigchild);
2505+ }
2506+
2507+ if(ses->type == SESSION_CLIENT){
2508+
2509+ poe_info(ses,"calling client_init_ses\n");
2510+ ret = client_init_ses(ses,ses->name);
2511+
2512+ if( ret < 0 ){
2513+ return -1;
2514+ }
2515+
2516+ while (ses->filt->num_restart > 0)
2517+ {
2518+ poe_info(ses,"Restart number %d ",ses->filt->num_restart);
2519+ ppp_connect (ses);
2520+ ses->filt->num_restart--;
2521+ }
2522+
2523+ }else if( ses->type == SESSION_SERVER ){
2524+
2525+ poe_info(ses,"calling srv_init_ses\n");
2526+ ret = srv_init_ses(ses,ses->name);
2527+
2528+ if( ret < 0 ){
2529+ return -1;
2530+ }
2531+
2532+ ret = 1;
2533+ while(ret>=0)
2534+ ret = ppp_connect(ses);
2535+
2536+ }
2537+
2538+
2539+
2540+
2541+ poe_info(ses,"ppp_connect came back! %d",ret);
2542+
2543+ exit(0);
2544+
2545+}
2546diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoefwd.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoefwd.c
2547--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoefwd.c Wed Dec 31 19:00:00 1969
2548+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoefwd.c Sun Aug 6 11:39:28 2000
2549@@ -0,0 +1,61 @@
2550+#include "pppoe.h"
2551+
2552+void fatal (char *fmt, ...)
2553+{
2554+ va_list pvar;
2555+
2556+#if defined(__STDC__)
2557+ va_start(pvar, fmt);
2558+#else
2559+ char *fmt;
2560+ va_start(pvar);
2561+ fmt = va_arg(pvar, char *);
2562+#endif
2563+
2564+ vprintf( fmt, pvar);
2565+ va_end(pvar);
2566+
2567+ exit(1); /* as promised */
2568+}
2569+
2570+void info (char *fmt, ...)
2571+{
2572+ va_list pvar;
2573+
2574+#if defined(__STDC__)
2575+ va_start(pvar, fmt);
2576+#else
2577+ char *fmt;
2578+ va_start(pvar);
2579+ fmt = va_arg(pvar, char *);
2580+#endif
2581+
2582+ vprintf( fmt, pvar);
2583+ va_end(pvar);
2584+
2585+}
2586+
2587+
2588+int main(int argc, char** argv){
2589+ int ret;
2590+ struct session *ses = (struct session *)malloc(sizeof(struct session));
2591+
2592+ if(!ses) return -1;
2593+
2594+ ret = relay_init_ses(ses,argv[1],argv[2]);
2595+
2596+ if( ret < 0 ){
2597+ return -1;
2598+ }
2599+
2600+ ses->log_to_fd = 1;
2601+ ses->opt_debug=1;
2602+ while(1)
2603+ ret = session_connect(ses);
2604+
2605+
2606+
2607+ return ret;
2608+
2609+
2610+}
2611diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/pppoehash.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoehash.c
2612--- ppp-2.4.1.orig/pppd/plugins/pppoe/pppoehash.c Wed Dec 31 19:00:00 1969
2613+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/pppoehash.c Sun Aug 6 11:39:28 2000
2614@@ -0,0 +1,91 @@
2615+/* PPPoE support library "libpppoe"
2616+ *
2617+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
2618+ * Jamal Hadi Salim <hadi@cyberus.ca>
2619+ *
2620+ * This program is free software; you can redistribute it and/or
2621+ * modify it under the terms of the GNU General Public License
2622+ * as published by the Free Software Foundation; either version
2623+ * 2 of the License, or (at your option) any later version.
2624+ */
2625+#include "pppoe.h"
2626+
2627+
2628+#define PPPOE_HASH_SIZE 16
2629+
2630+
2631+static inline int keycmp(char *a, char *b, int x, int y){
2632+ return x==y && !memcmp(a,b,x);
2633+}
2634+
2635+static int hash_con(int key_len, char* key)
2636+{
2637+ int i = 0;
2638+ char hash[sizeof(int)]={0,};
2639+
2640+ for (i = 0; i < key_len ; ++i)
2641+ hash[i% sizeof(int)] = hash[i%sizeof(int)] ^ key[i];
2642+
2643+ i = (*((int*)hash)) ;
2644+ i &= PPPOE_HASH_SIZE - 1;
2645+
2646+ return i;
2647+}
2648+
2649+static struct pppoe_con *con_ht[PPPOE_HASH_SIZE] = { 0, };
2650+
2651+struct pppoe_con *get_con(int len, char *key)
2652+{
2653+ int hash = hash_con(len, key);
2654+ struct pppoe_con *ret;
2655+
2656+ ret = con_ht[hash];
2657+
2658+ while (ret && !keycmp(ret->key,key, ret->key_len, len))
2659+ ret = ret->next;
2660+
2661+ return ret;
2662+}
2663+
2664+int store_con(struct pppoe_con *pc)
2665+{
2666+ int hash = hash_con(pc->key_len, pc->key);
2667+ struct pppoe_con *ret;
2668+
2669+ ret = con_ht[hash];
2670+ while (ret) {
2671+ if (!keycmp(ret->key, pc->key, ret->key_len, pc->key_len))
2672+ return -EALREADY;
2673+
2674+ ret = ret->next;
2675+ }
2676+
2677+ if (!ret) {
2678+ pc->next = con_ht[hash];
2679+ con_ht[hash] = pc;
2680+ }
2681+
2682+ return 0;
2683+}
2684+
2685+struct pppoe_con *delete_con(unsigned long len, char *key)
2686+{
2687+ int hash = hash_con(len, key);
2688+ struct pppoe_con *ret, **src;
2689+
2690+ ret = con_ht[hash];
2691+ src = &con_ht[hash];
2692+
2693+ while (ret) {
2694+ if (keycmp(ret->key,key, ret->key_len, len)) {
2695+ *src = ret->next;
2696+ break;
2697+ }
2698+
2699+ src = &ret->next;
2700+ ret = ret->next;
2701+ }
2702+
2703+ return ret;
2704+}
2705+
2706diff -r -N -u -b -B ppp-2.4.1.orig/pppd/plugins/pppoe/utils.c ppp-2.4.1.pppoe2/pppd/plugins/pppoe/utils.c
2707--- ppp-2.4.1.orig/pppd/plugins/pppoe/utils.c Wed Dec 31 19:00:00 1969
2708+++ ppp-2.4.1.pppoe2/pppd/plugins/pppoe/utils.c Sun Aug 6 11:39:28 2000
2709@@ -0,0 +1,667 @@
2710+
2711+/*
2712+ * utils.c - various utility functions used in pppoed.
2713+ *
2714+ * mostly stolen from ppp-2.3.10 by Marc Boucher <marc@mbsi.ca>
2715+ *
2716+ * Feb 18/2000 Made fully re-entrant (JHS)
2717+ *
2718+ * Copyright (c) 1999 The Australian National University.
2719+ * All rights reserved.
2720+ *
2721+ * Redistribution and use in source and binary forms are permitted
2722+ * provided that the above copyright poe_notice and this paragraph are
2723+ * duplicated in all such forms and that any documentation,
2724+ * advertising materials, and other materials related to such
2725+ * distribution and use acknowledge that the software was developed
2726+ * by the Australian National University. The name of the University
2727+ * may not be used to endorse or promote products derived from this
2728+ * software without specific prior written permission.
2729+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2730+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2731+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2732+ */
2733+
2734+#include <stdio.h> /* stdio */
2735+#include <stdlib.h> /* strtoul(), realloc() */
2736+#include <string.h> /* memcpy() */
2737+#include <unistd.h> /* STDIN_FILENO,exec */
2738+#include <errno.h> /* errno */
2739+
2740+#include <sys/time.h>
2741+
2742+#include <net/ethernet.h>
2743+#include <netinet/in.h>
2744+
2745+#include <stdarg.h>
2746+#include <ctype.h>
2747+#include <syslog.h>
2748+#include <limits.h>
2749+#include <paths.h>
2750+
2751+#include "pppoe.h"
2752+
2753+static char pidfilename[PATH_MAX]; /* name of pid file */
2754+
2755+/*
2756+static int detached = 0;
2757+ log_to_fd = -1;
2758+ */
2759+
2760+static void vslp_printer (void *, char *,...);
2761+static void format_packet (struct pppoe_packet *, int, void (*)(void *, char *,...), void *);
2762+static void format_tag (struct pppoe_tag *, void (*)(void *, char *,...), void *);
2763+struct buffer_poe_info {
2764+ char *ptr;
2765+ int len;
2766+};
2767+
2768+void poe_die (int status);
2769+
2770+
2771+/*
2772+ * vpoe_slprintf - like vsprintf, except we
2773+ * also specify the length of the output buffer, and we handle
2774+ * %r (recursive format), %m (poe_error message), %v (visible string),
2775+ * %q (quoted string), %t (current time) and %E (Ether address) formats.
2776+ * Doesn't do floating-point formats.
2777+ * Returns the number of chars put into buf.
2778+ */
2779+#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
2780+
2781+int
2782+vpoe_slprintf (char *buf, int buflen, char *fmt, va_list args)
2783+{
2784+ int c, i, n;
2785+ int width, prec, fillch;
2786+ int base, len, neg, quoted;
2787+ unsigned long val = 0;
2788+ char *str, *f, *buf0;
2789+ unsigned char *p;
2790+ char num[32];
2791+ time_t t;
2792+ static char hexchars[] = "0123456789abcdef";
2793+ struct buffer_poe_info bufpoe_info;
2794+
2795+ buf0 = buf;
2796+ --buflen;
2797+ while (buflen > 0) {
2798+ for (f = fmt; *f != '%' && *f != 0; ++f);
2799+ if (f > fmt) {
2800+ len = f - fmt;
2801+ if (len > buflen)
2802+ len = buflen;
2803+ memcpy (buf, fmt, len);
2804+ buf += len;
2805+ buflen -= len;
2806+ fmt = f;
2807+ }
2808+ if (*fmt == 0)
2809+ break;
2810+ c = *++fmt;
2811+ width = 0;
2812+ prec = -1;
2813+ fillch = ' ';
2814+ if (c == '0') {
2815+ fillch = '0';
2816+ c = *++fmt;
2817+ }
2818+ if (c == '*') {
2819+ width = va_arg (args, int);
2820+ c = *++fmt;
2821+ }
2822+ else {
2823+ while (isdigit (c)) {
2824+ width = width * 10 + c - '0';
2825+ c = *++fmt;
2826+ }
2827+ }
2828+ if (c == '.') {
2829+ c = *++fmt;
2830+ if (c == '*') {
2831+ prec = va_arg (args, int);
2832+ c = *++fmt;
2833+ }
2834+ else {
2835+ prec = 0;
2836+ while (isdigit (c)) {
2837+ prec = prec * 10 + c - '0';
2838+ c = *++fmt;
2839+ }
2840+ }
2841+ }
2842+ str = 0;
2843+ base = 0;
2844+ neg = 0;
2845+ ++fmt;
2846+ switch (c) {
2847+ case 'd':
2848+ i = va_arg (args, int);
2849+ if (i < 0) {
2850+ neg = 1;
2851+ val = -i;
2852+ }
2853+ else
2854+ val = i;
2855+ base = 10;
2856+ break;
2857+ case 'o':
2858+ val = va_arg (args, unsigned int);
2859+ base = 8;
2860+ break;
2861+ case 'x':
2862+ case 'X':
2863+ val = va_arg (args, unsigned int);
2864+ base = 16;
2865+ break;
2866+ case 'p':
2867+ val = (unsigned long) va_arg (args, void *);
2868+ base = 16;
2869+ neg = 2;
2870+ break;
2871+ case 's':
2872+ str = va_arg (args, char *);
2873+ break;
2874+ case 'c':
2875+ num[0] = va_arg (args, int);
2876+ num[1] = 0;
2877+ str = num;
2878+ break;
2879+ case 'm':
2880+ str = strerror (errno);
2881+ break;
2882+ case 'E':
2883+ p = va_arg (args, unsigned char *);
2884+ for (n = ETH_ALEN; n > 0; --n) {
2885+ c = *p++;
2886+ OUTCHAR (hexchars[(c >> 4) & 0xf]);
2887+ OUTCHAR (hexchars[c & 0xf]);
2888+ if (n > 1)
2889+ OUTCHAR (':');
2890+ }
2891+ continue;
2892+ case 'r':
2893+ f = va_arg (args, char *);
2894+#ifndef __powerpc__
2895+ n = vpoe_slprintf (buf, buflen + 1, f, va_arg (args, va_list));
2896+#else
2897+ /* On the powerpc, a va_list is an array of 1 structure */
2898+ n = vpoe_slprintf (buf, buflen + 1, f, va_arg (args, void *));
2899+#endif
2900+ buf += n;
2901+ buflen -= n;
2902+ continue;
2903+ case 't':
2904+ time (&t);
2905+ str = ctime (&t);
2906+ str += 4; /* chop off the day name */
2907+ str[15] = 0; /* chop off year and newline */
2908+ break;
2909+ case 'v': /* "visible" string */
2910+ case 'q': /* quoted string */
2911+ quoted = c == 'q';
2912+ p = va_arg (args, unsigned char *);
2913+ if (fillch == '0' && prec >= 0) {
2914+ n = prec;
2915+ }
2916+ else {
2917+ n = strlen ((char *) p);
2918+ if (prec >= 0 && n > prec)
2919+ n = prec;
2920+ }
2921+ while (n > 0 && buflen > 0) {
2922+ c = *p++;
2923+ --n;
2924+ if (!quoted && c >= 0x80) {
2925+ OUTCHAR ('M');
2926+ OUTCHAR ('-');
2927+ c -= 0x80;
2928+ }
2929+ if (quoted && (c == '"' || c == '\\'))
2930+ OUTCHAR ('\\');
2931+ if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
2932+ if (quoted) {
2933+ OUTCHAR ('\\');
2934+ switch (c) {
2935+ case '\t':
2936+ OUTCHAR ('t');
2937+ break;
2938+ case '\n':
2939+ OUTCHAR ('n');
2940+ break;
2941+ case '\b':
2942+ OUTCHAR ('b');
2943+ break;
2944+ case '\f':
2945+ OUTCHAR ('f');
2946+ break;
2947+ default:
2948+ OUTCHAR ('x');
2949+ OUTCHAR (hexchars[c >> 4]);
2950+ OUTCHAR (hexchars[c & 0xf]);
2951+ }
2952+ }
2953+ else {
2954+ if (c == '\t')
2955+ OUTCHAR (c);
2956+ else {
2957+ OUTCHAR ('^');
2958+ OUTCHAR (c ^ 0x40);
2959+ }
2960+ }
2961+ }
2962+ else
2963+ OUTCHAR (c);
2964+ }
2965+ continue;
2966+ case 'P': /* print PPPoE packet */
2967+ bufpoe_info.ptr = buf;
2968+ bufpoe_info.len = buflen + 1;
2969+ p = va_arg (args, unsigned char *);
2970+ n = va_arg (args, int);
2971+ format_packet ((struct pppoe_packet *) p, n, vslp_printer, &bufpoe_info);
2972+ buf = bufpoe_info.ptr;
2973+ buflen = bufpoe_info.len - 1;
2974+ continue;
2975+ case 'T': /* print PPPoE tag */
2976+ bufpoe_info.ptr = buf;
2977+ bufpoe_info.len = buflen + 1;
2978+ p = va_arg (args, unsigned char *);
2979+ format_tag ((struct pppoe_tag *) p, vslp_printer, &bufpoe_info);
2980+ buf = bufpoe_info.ptr;
2981+ buflen = bufpoe_info.len - 1;
2982+ continue;
2983+ case 'B':
2984+ p = va_arg (args, unsigned char *);
2985+ for (n = prec; n > 0; --n) {
2986+ c = *p++;
2987+ if (fillch == ' ')
2988+ OUTCHAR (' ');
2989+ OUTCHAR (hexchars[(c >> 4) & 0xf]);
2990+ OUTCHAR (hexchars[c & 0xf]);
2991+ }
2992+ continue;
2993+ default:
2994+ *buf++ = '%';
2995+ if (c != '%')
2996+ --fmt; /* so %z outputs %z etc. */
2997+ --buflen;
2998+ continue;
2999+ }
3000+ if (base != 0) {
3001+ str = num + sizeof (num);
3002+ *--str = 0;
3003+ while (str > num + neg) {
3004+ *--str = hexchars[val % base];
3005+ val = val / base;
3006+ if (--prec <= 0 && val == 0)
3007+ break;
3008+ }
3009+ switch (neg) {
3010+ case 1:
3011+ *--str = '-';
3012+ break;
3013+ case 2:
3014+ *--str = 'x';
3015+ *--str = '0';
3016+ break;
3017+ }
3018+ len = num + sizeof (num) - 1 - str;
3019+ }
3020+ else {
3021+ len = strlen (str);
3022+ if (prec >= 0 && len > prec)
3023+ len = prec;
3024+ }
3025+ if (width > 0) {
3026+ if (width > buflen)
3027+ width = buflen;
3028+ if ((n = width - len) > 0) {
3029+ buflen -= n;
3030+ for (; n > 0; --n)
3031+ *buf++ = fillch;
3032+ }
3033+ }
3034+ if (len > buflen)
3035+ len = buflen;
3036+ memcpy (buf, str, len);
3037+ buf += len;
3038+ buflen -= len;
3039+ }
3040+ *buf = 0;
3041+ return buf - buf0;
3042+}
3043+
3044+/*
3045+ * vslp_printer - used in processing a %P format
3046+ */
3047+static void
3048+vslp_printer (void *arg, char *fmt,...)
3049+{
3050+ int n;
3051+ va_list pvar;
3052+ struct buffer_poe_info *bi;
3053+
3054+ va_start (pvar, fmt);
3055+
3056+ bi = (struct buffer_poe_info *) arg;
3057+ n = vpoe_slprintf (bi->ptr, bi->len, fmt, pvar);
3058+ va_end (pvar);
3059+
3060+ bi->ptr += n;
3061+ bi->len -= n;
3062+}
3063+
3064+/*
3065+ * format_packet - make a readable representation of a packet,
3066+ * calling `printer(arg, format, ...)' to output it.
3067+ */
3068+static void
3069+format_packet (struct pppoe_packet *p,
3070+ int len,
3071+ void (*printer) (void *, char *,...),
3072+ void *arg)
3073+{
3074+ struct pppoe_tag *t;
3075+
3076+ printer (arg, "Ether addr: %E\n", p->addr.sll_addr);
3077+
3078+ switch ((unsigned) ntohs (p->addr.sll_protocol)) {
3079+ case ETH_P_PPPOE_DISC:
3080+ printer (arg, " (PPPOE Discovery)\n");
3081+ break;
3082+ case ETH_P_PPPOE_SESS:
3083+ printer (arg, " (PPPOE Session)\n");
3084+ break;
3085+ }
3086+
3087+ printer (arg, " PPPoE hdr: ver=0x%01x type=0x%01x code=0x%02x "
3088+ "sid=0x%04x length=0x%04x ", (unsigned) p->hdr->ver,
3089+ (unsigned) p->hdr->type, (unsigned) p->hdr->code, (unsigned) p->hdr->sid,
3090+ (unsigned) ntohs (p->hdr->length));
3091+
3092+ switch (p->hdr->code) {
3093+ case PADI_CODE:
3094+ printer (arg, "(PADI)\n");
3095+ break;
3096+ case PADO_CODE:
3097+ printer (arg, "(PADO)\n");
3098+ break;
3099+ case PADR_CODE:
3100+ printer (arg, "(PADR)\n");
3101+ break;
3102+ case PADS_CODE:
3103+ printer (arg, "(PADS)\n");
3104+ break;
3105+ case PADT_CODE:
3106+ printer (arg, "(PADT)\n");
3107+ break;
3108+ default:
3109+ printer (arg, "(Unknown)\n");
3110+ }
3111+
3112+#if 0
3113+ if (ntohs (p->addr.sll_protocol) != ETH_P_PPPOE_DISC) {
3114+ len = ntohs (p->length);
3115+
3116+ if (len > 64)
3117+ printer (arg, " %.64B ...", (p + 1));
3118+ else
3119+ printer (arg, " %.*B", len, p + 1);
3120+
3121+ return;
3122+ }
3123+#endif
3124+
3125+ for(t = (struct pppoe_tag *) (&p->hdr->tag);
3126+ (t < (struct pppoe_tag *) ((char *) (&p->hdr->tag) + ntohs (p->hdr->length))) &&
3127+ ntohs (t->tag_type) != PTT_EOL;
3128+ t = (struct pppoe_tag *) ((char *) (t + 1) + ntohs (t->tag_len))) {
3129+ format_tag (t, printer, arg);
3130+ }
3131+}
3132+
3133+/*
3134+ * format_tag - make a readable representation of a tag,
3135+ * calling `printer(arg, format, ...)' to output it.
3136+ */
3137+static void
3138+format_tag (struct pppoe_tag *t,
3139+ void (*printer) (void *, char *,...),
3140+ void *arg)
3141+{
3142+ printer (arg, " PPPoE tag: type=%04x length=%04x ",
3143+ ntohs (t->tag_type), ntohs (t->tag_len));
3144+ switch ( t->tag_type ) {
3145+ case PTT_EOL:
3146+ printer (arg, "(End of list)");
3147+ break;
3148+ case PTT_SRV_NAME:
3149+ printer (arg, "(Service name)");
3150+ break;
3151+ case PTT_AC_NAME:
3152+ printer (arg, "(AC Name)");
3153+ break;
3154+ case PTT_HOST_UNIQ:
3155+ printer (arg, "(Host Uniq)");
3156+ break;
3157+ case PTT_AC_COOKIE:
3158+ printer (arg, "(AC Cookie)");
3159+ break;
3160+ case PTT_VENDOR:
3161+ printer (arg, "(Vendor Specific)");
3162+ break;
3163+ case PTT_RELAY_SID:
3164+ printer (arg, "(Relay Session ID)");
3165+ break;
3166+ case PTT_SRV_ERR:
3167+ printer (arg, "(Service Name Error)");
3168+ break;
3169+ case PTT_SYS_ERR:
3170+ printer (arg, "(AC System Error)");
3171+ break;
3172+ case PTT_GEN_ERR:
3173+ printer (arg, "(Generic Error)");
3174+ break;
3175+ default:
3176+ printer (arg, "(Unknown)");
3177+ }
3178+ if (ntohs (t->tag_len) > 0)
3179+ switch ( t->tag_type ) {
3180+ case PTT_SRV_NAME:
3181+ case PTT_AC_NAME:
3182+ case PTT_SRV_ERR:
3183+ case PTT_SYS_ERR:
3184+ case PTT_GEN_ERR: /* ascii data */
3185+ {
3186+ char *buf;
3187+ buf = malloc (ntohs (t->tag_len) + 1);
3188+ memset (buf, 0, ntohs (t->tag_len) + 1);
3189+ strncpy (buf, (char *) (t + 1), ntohs (t->tag_len));
3190+// buf[ntohs (t->tag_len)] = '\0';
3191+ printer (arg, " data (UTF-8): %s", buf);
3192+ free (buf);
3193+ break;
3194+ }
3195+
3196+ case PTT_HOST_UNIQ:
3197+ case PTT_AC_COOKIE:
3198+ case PTT_RELAY_SID:
3199+ printer (arg, " data (bin): %.*B", ntohs (t->tag_len), (char *) (t + 1));
3200+ break;
3201+
3202+ default:
3203+ printer (arg, " unrecognized data");
3204+ }
3205+}
3206+
3207+/*
3208+ * poe_logit - does the hard work for poe_fatal et al.
3209+ */
3210+static void
3211+poe_logit (struct session *ses,int level, char *fmt, va_list args)
3212+{
3213+ int n;
3214+ char buf[256];
3215+
3216+ n = vpoe_slprintf (buf, sizeof (buf), fmt, args);
3217+ syslog (level, "%s", buf);
3218+ if (log_to_fd >= 0 && (level != LOG_DEBUG || ses->opt_debug)) {
3219+ if (buf[n - 1] != '\n')
3220+ buf[n++] = '\n';
3221+ if (write (log_to_fd, buf, n) != n)
3222+ log_to_fd = -1;
3223+ }
3224+}
3225+
3226+/*
3227+ * poe_fatal - log an poe_error message and poe_die horribly.
3228+ */
3229+void
3230+poe_fatal (struct session *ses, char *fmt,...)
3231+{
3232+ va_list pvar;
3233+
3234+ va_start (pvar, fmt);
3235+
3236+ poe_logit (ses,LOG_ERR, fmt, pvar);
3237+ va_end (pvar);
3238+
3239+ poe_die(1); /* as promised */
3240+}
3241+
3242+/*
3243+ * poe_error - log an poe_error message.
3244+ */
3245+void
3246+poe_error (struct session *ses,char *fmt,...)
3247+{
3248+ va_list pvar;
3249+
3250+ va_start (pvar, fmt);
3251+
3252+ poe_logit (ses,LOG_ERR, fmt, pvar);
3253+ va_end (pvar);
3254+}
3255+
3256+/*
3257+ * poe_warn - log a poe_warning message.
3258+ */
3259+void
3260+poe_warn (struct session *ses,char *fmt,...)
3261+{
3262+ va_list pvar;
3263+
3264+ va_start (pvar, fmt);
3265+
3266+ poe_logit (ses,LOG_WARNING, fmt, pvar);
3267+ va_end (pvar);
3268+}
3269+
3270+#if 0
3271+/*
3272+ * poe_notice - log a poe_notice-level message.
3273+ */
3274+void
3275+poe_notice (int log_to_fd ,char *fmt,...)
3276+{
3277+ va_list pvar;
3278+
3279+ va_start (pvar, fmt);
3280+
3281+ poe_logit (log_to_fd,LOG_NOTICE, fmt, pvar);
3282+ va_end (pvar);
3283+}
3284+
3285+#endif
3286+/*
3287+ * poe_info - log an poe_informational message.
3288+ */
3289+void
3290+poe_info (struct session *ses,char *fmt,...)
3291+{
3292+ va_list pvar;
3293+
3294+ va_start (pvar, fmt);
3295+
3296+ poe_logit (ses,LOG_INFO, fmt, pvar);
3297+ va_end (pvar);
3298+}
3299+
3300+/*
3301+ * poe_dbglog - log a debug message.
3302+ */
3303+void
3304+poe_dbglog (struct session *ses ,char *fmt,...)
3305+{
3306+ va_list pvar;
3307+
3308+ va_start (pvar, fmt);
3309+
3310+ poe_logit (ses,LOG_DEBUG, fmt, pvar);
3311+ va_end (pvar);
3312+}
3313+
3314+/*
3315+ * Create a file containing our process ID.
3316+ */
3317+void
3318+poe_create_pidfile (struct session *ses)
3319+{
3320+ FILE *pidfile;
3321+
3322+ sprintf (pidfilename, "%s%s.pid", _PATH_VARRUN, "pppoed");
3323+ if ((pidfile = fopen (pidfilename, "w")) != NULL) {
3324+ fprintf (pidfile, "%d\n", getpid ());
3325+ (void) fclose (pidfile);
3326+ }
3327+ else {
3328+ poe_error (ses,"Failed to create pid file %s: %m", pidfilename);
3329+ pidfilename[0] = 0;
3330+ }
3331+}
3332+
3333+/*
3334+ * detach - detach us from the controlling terminal.
3335+ */
3336+void
3337+poe_detach (struct session *ses)
3338+{
3339+ if (ses->detached)
3340+ return;
3341+
3342+ if ((daemon (0, 0)) < 0) {
3343+ poe_error (ses,"Couldn't detach (daemon failed: %m)");
3344+#if 0
3345+ poe_die (1); /* or just return? */
3346+#endif
3347+ }
3348+ ses->detached = 1;
3349+ ses->log_to_fd = -1;
3350+ /* update pid files if they have been written already */
3351+ if (pidfilename[0])
3352+ poe_create_pidfile (ses);
3353+}
3354+
3355+/*
3356+ * cleanup - restore anything which needs to be restored before we exit
3357+ */
3358+/* ARGSUSED */
3359+static void
3360+cleanup ()
3361+{
3362+ if (pidfilename[0] != 0 && unlink (pidfilename) < 0 && errno != ENOENT)
3363+ syslog (LOG_INFO,"unable to delete pid file ");
3364+ pidfilename[0] = 0;
3365+}
3366+
3367+/*
3368+ * poe_die - clean up state and exit with the specified status.
3369+ */
3370+void
3371+poe_die (int status)
3372+{
3373+ cleanup ();
3374+ syslog (LOG_INFO, "Exit.");
3375+ exit (status);
3376+}
3377diff -r -N -u -b -B ppp-2.4.1.orig/pppd/pppd.h ppp-2.4.1.pppoe2/pppd/pppd.h
3378--- ppp-2.4.1.orig/pppd/pppd.h Tue Mar 13 00:54:37 2001
3379+++ ppp-2.4.1.pppoe2/pppd/pppd.h Sun Apr 1 15:06:17 2001
3380@@ -496,6 +496,8 @@
3381 int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
3382 int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */
3383 void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */
3384+void generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */
3385+int generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */
3386 void make_new_bundle __P((int, int, int, int)); /* Create new bundle */
3387 int bundle_attach __P((int)); /* Attach link to existing bundle */
3388 void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */
3389@@ -587,6 +589,7 @@
3390 /* Simplified number_option for decimal ints */
3391 void add_options __P((option_t *)); /* Add extra options */
3392 void check_options __P((void)); /* check values after all options parsed */
3393+int remove_option __P((char *)); /* Disable the specified option */
3394 int override_value __P((const char *, int, const char *));
3395 /* override value if permitted by priority */
3396 void print_options __P((void (*) __P((void *, char *, ...)), void *));
3397diff -r -N -u -b -B ppp-2.4.1.orig/pppd/sys-linux.c ppp-2.4.1.pppoe2/pppd/sys-linux.c
3398--- ppp-2.4.1.orig/pppd/sys-linux.c Tue Mar 13 00:54:41 2001
3399+++ ppp-2.4.1.pppoe2/pppd/sys-linux.c Sun Apr 1 15:44:53 2001
3400@@ -141,7 +141,7 @@
3401 static int restore_term = 0; /* 1 => we've munged the terminal */
3402 static struct termios inittermios; /* Initial TTY termios */
3403
3404-static int new_style_driver = 0;
3405+int new_style_driver = 0;
3406
3407 static char loop_name[20];
3408 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
3409@@ -352,23 +352,14 @@
3410 return (1);
3411 }
3412
3413+
3414 /********************************************************************
3415 *
3416- * tty_establish_ppp - Turn the serial port into a ppp interface.
3417+ * generic_establish_ppp - Turn the fd into a ppp interface.
3418 */
3419-
3420-int tty_establish_ppp (int tty_fd)
3421+int generic_establish_ppp (int fd)
3422 {
3423 int x;
3424- int fd = -1;
3425-
3426-/*
3427- * Ensure that the tty device is in exclusive mode.
3428- */
3429- if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
3430- if ( ! ok_error ( errno ))
3431- warn("Couldn't make tty exclusive: %m");
3432- }
3433 /*
3434 * Demand mode - prime the old ppp device to relinquish the unit.
3435 */
3436@@ -377,26 +368,13 @@
3437 error("ioctl(transfer ppp unit): %m");
3438 return -1;
3439 }
3440-/*
3441- * Set the current tty to the PPP discpline
3442- */
3443
3444-#ifndef N_SYNC_PPP
3445-#define N_SYNC_PPP 14
3446-#endif
3447- ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
3448- if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
3449- if ( ! ok_error (errno) ) {
3450- error("Couldn't set tty to PPP discipline: %m");
3451- return -1;
3452- }
3453- }
3454
3455 if (new_style_driver) {
3456 /* Open another instance of /dev/ppp and connect the channel to it */
3457 int flags;
3458
3459- if (ioctl(tty_fd, PPPIOCGCHAN, &chindex) == -1) {
3460+ if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
3461 error("Couldn't get channel number: %m");
3462 goto err;
3463 }
3464@@ -440,8 +419,8 @@
3465 /*
3466 * Old-style driver: find out which interface we were given.
3467 */
3468- set_ppp_fd (tty_fd);
3469- if (ioctl(tty_fd, PPPIOCGUNIT, &x) < 0) {
3470+ set_ppp_fd (fd);
3471+ if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
3472 if (ok_error (errno))
3473 goto err;
3474 fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
3475@@ -454,9 +433,9 @@
3476 /*
3477 * Fetch the initial file flags and reset blocking mode on the file.
3478 */
3479- initfdflags = fcntl(tty_fd, F_GETFL);
3480+ initfdflags = fcntl(fd, F_GETFL);
3481 if (initfdflags == -1 ||
3482- fcntl(tty_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
3483+ fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
3484 if ( ! ok_error (errno))
3485 warn("Couldn't set device to non-blocking mode: %m");
3486 }
3487@@ -470,13 +450,6 @@
3488 if (!looped)
3489 set_kdebugflag (kdebugflag);
3490
3491-#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
3492-#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
3493- | SC_LOG_FLUSH)
3494-
3495- set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))
3496- | ((kdebugflag * SC_DEBUG) & SC_LOGB)));
3497-
3498 SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
3499 driver_version, driver_modification, driver_patch));
3500
3501@@ -485,22 +458,86 @@
3502 err_close:
3503 close(fd);
3504 err:
3505- if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
3506+ if (ioctl(fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
3507 warn("Couldn't reset tty to normal line discipline: %m");
3508 return -1;
3509 }
3510
3511 /********************************************************************
3512 *
3513- * tty_disestablish_ppp - Restore the serial port to normal operation,
3514- * and reconnect the ppp unit to the loopback if in demand mode.
3515+ * tty_establish_ppp - Turn the serial port into a ppp interface.
3516+ */
3517+
3518+int tty_establish_ppp (int tty_fd)
3519+{
3520+ int ret_fd;
3521+/*
3522+ * Ensure that the tty device is in exclusive mode.
3523+ */
3524+ if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
3525+ if ( ! ok_error ( errno ))
3526+ warn("Couldn't make tty exclusive: %m");
3527+ }
3528+/*
3529+ * Set the current tty to the PPP discpline
3530+ */
3531+
3532+#ifndef N_SYNC_PPP
3533+#define N_SYNC_PPP 14
3534+#endif
3535+ ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
3536+ if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
3537+ if ( ! ok_error (errno) ) {
3538+ error("Couldn't set tty to PPP discipline: %m");
3539+ return -1;
3540+ }
3541+ }
3542+
3543+ ret_fd = generic_establish_ppp(tty_fd);
3544+#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
3545+#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
3546+ | SC_LOG_FLUSH)
3547+
3548+ set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))
3549+ | ((kdebugflag * SC_DEBUG) & SC_LOGB)));
3550+
3551+ return ret_fd;
3552+}
3553+
3554+/********************************************************************
3555+ *
3556+ * generic_disestablish_ppp - Restore device components to normal
3557+ * operation, and reconnect the ppp unit to the loopback if in demand
3558+ * mode. This shouldn't call die() because it's called from die().
3559+*/
3560+void generic_disestablish_ppp(int dev_fd){
3561+ /* Restore loop if needed */
3562+ if(demand)
3563+ restore_loop();
3564+
3565+ /* Finally detach the device */
3566+ initfdflags = -1;
3567+
3568+ if (new_style_driver) {
3569+ close(ppp_fd);
3570+ ppp_fd = -1;
3571+ if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
3572+ error("Couldn't release PPP unit: %m");
3573+ if (!multilink)
3574+ remove_fd(ppp_dev_fd);
3575+ }
3576+}
3577+
3578+/********************************************************************
3579+ *
3580+ * tty_disestablish_ppp - Restore the serial port to normal operation.
3581 * This shouldn't call die() because it's called from die().
3582 */
3583
3584 void tty_disestablish_ppp(int tty_fd)
3585 {
3586- if (demand)
3587- restore_loop();
3588+ generic_disestablish_ppp(tty_fd);
3589+
3590 if (!hungup) {
3591 /*
3592 * Flush the tty output buffer so that the TIOCSETD doesn't hang.
3593@@ -526,16 +563,6 @@
3594 warn("Couldn't restore device fd flags: %m");
3595 }
3596 }
3597- initfdflags = -1;
3598-
3599- if (new_style_driver) {
3600- close(ppp_fd);
3601- ppp_fd = -1;
3602- if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0)
3603- error("Couldn't release PPP unit: %m");
3604- if (!multilink)
3605- remove_fd(ppp_dev_fd);
3606- }
3607 }
3608
3609 /*
3610@@ -2567,7 +2594,7 @@
3611 * Just to be sure, set the real serial port to the normal discipline.
3612 */
3613
3614-static void
3615+void
3616 restore_loop(void)
3617 {
3618 looped = 1;
3619diff -r -N -u -b -B ppp-2.4.1.orig/sunos4/Makefile ppp-2.4.1.pppoe2/sunos4/Makefile
3620--- ppp-2.4.1.orig/sunos4/Makefile Tue Mar 24 22:09:35 1998
3621+++ ppp-2.4.1.pppoe2/sunos4/Makefile Wed Dec 31 19:00:00 1969
3622@@ -1,57 +0,0 @@
3623-#
3624-# Makefile for STREAMS modules for SunOS 4.
3625-#
3626-# $Id$
3627-#
3628-
3629-include Makedefs
3630-
3631-LD = /usr/bin/ld # make sure we don't get gnu ld
3632-
3633-# Defining __$(ARCH)__ is for gcc's broken version of sun/vddrv.h.
3634-ARCH = `/bin/arch -k`
3635-DEFINES= -DKERNEL -D_KERNEL -DSUNOS4 -D$(ARCH) -D__$(ARCH)__ \
3636- -DDEBUG -DNO_DLPI -DSNIT_SUPPORT
3637-CFLAGS= $(DEFINES) -I../include $(COPTS)
3638-
3639-MODULES= ppp_mod.o ppp_ahdl_mod.o ppp_comp_mod.o if_ppp_mod.o
3640-
3641-all: $(MODULES)
3642-
3643-ppp_mod.o: ppp.o ppp_vdcmd.o
3644- $(LD) -r -o ppp_mod.o ppp.o ppp_vdcmd.o
3645-
3646-ppp_ahdl_mod.o: ppp_ahdlc.o ppp_ahdlc_vdcmd.o
3647- $(LD) -r -o ppp_ahdl_mod.o ppp_ahdlc.o ppp_ahdlc_vdcmd.o
3648-
3649-COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \
3650- ppp_comp_vdcmd.o
3651-ppp_comp_mod.o: $(COMP_OBJS)
3652- $(LD) -r -o $@ $(COMP_OBJS)
3653-
3654-if_ppp.o: ../modules/if_ppp.c
3655- $(CC) $(CFLAGS) -c $?
3656-bsd-comp.o: ../modules/bsd-comp.c
3657- $(CC) $(CFLAGS) -c $?
3658-deflate.o: ../modules/deflate.c
3659- $(CC) $(CFLAGS) -c $?
3660-ppp.o: ../modules/ppp.c
3661- $(CC) $(CFLAGS) -c $?
3662-ppp_ahdlc.o: ../modules/ppp_ahdlc.c
3663- $(CC) $(CFLAGS) -c $?
3664-ppp_comp.o: ../modules/ppp_comp.c
3665- $(CC) $(CFLAGS) -c $?
3666-vjcompress.o: ../modules/vjcompress.c
3667- $(CC) $(CFLAGS) -c $?
3668-zlib.o: ../common/zlib.c
3669- $(CC) $(CFLAGS) -c $?
3670-
3671-if_ppp_mod.o: if_ppp.o if_ppp_vdcmd.o
3672- $(LD) -r -o if_ppp_mod.o if_ppp.o if_ppp_vdcmd.o
3673-
3674-install: all
3675- $(INSTALL) $(MODULES) $(BINDIR)
3676- ./ppp.INSTALL
3677-
3678-clean:
3679- rm -f ppp ppp_comp ppp_ahdl *.o *~ core
This page took 0.423058 seconds and 4 git commands to generate.