diff --git a/ipppd/auth.c b/ipppd/auth.c index 6fea5de6..1f07209a 100644 --- a/ipppd/auth.c +++ b/ipppd/auth.c @@ -8,6 +8,8 @@ * Copyright (c) 1993 The Australian National University. * All rights reserved. * + * 2000-07-25 Callback improvements by richard.kunze@web.de + * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, @@ -36,7 +38,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -char auth_rcsid[] = "$Id: auth.c,v 1.16 2000/06/21 09:01:54 keil Exp $"; +char auth_rcsid[] = "$Id: auth.c,v 1.17 2000/07/25 20:23:51 kai Exp $"; #include #include @@ -444,18 +446,26 @@ static void network_phase(int linkunit) */ static void callback_phase(int linkunit) { - lcp_options *wo = &lcp_wantoptions[ lns[linkunit].lcp_unit ]; - -/* hack here: remote is always the server for callback */ - if (wo->neg_cbcp && !(lns[linkunit].pci.calltype & CALLTYPE_INCOMING) ) { - lns[linkunit].phase = PHASE_CALLBACK; - lns[linkunit].cbcp_unit = linkunit; /* cbcp always corresponds to a link */ - cbcp[ lns[linkunit].cbcp_unit ].us_unit = linkunit; - (*cbcp_protent.lowerup)(lns[linkunit].cbcp_unit); - (*cbcp_protent.open)(lns[linkunit].cbcp_unit); - } - else - network_phase(linkunit); + lcp_options *go = &lcp_gotoptions[ lns[linkunit].lcp_unit ]; + + /* hack here: remote is always the server for callback */ + if (go->neg_callback && !(lns[linkunit].pci.calltype & CALLTYPE_INCOMING)) { + /* Do CBCP if we did negotiate CBCP, take the lionk + down and wait for callback if we negotiated RFC + 1570 style callback */ + if (go->cbopt.type == CB_CBCP) { + lns[linkunit].phase = PHASE_CALLBACK; + /* cbcp always corresponds to a link */ + lns[linkunit].cbcp_unit = linkunit; + cbcp[ lns[linkunit].cbcp_unit ].us_unit = linkunit; + (*cbcp_protent.lowerup)(lns[linkunit].cbcp_unit); + (*cbcp_protent.open)(lns[linkunit].cbcp_unit); + } else { + lns[linkunit].phase = PHASE_TERMINATE; + } + } else { + network_phase(linkunit); + } } /* diff --git a/ipppd/cbcp.c b/ipppd/cbcp.c index f2e24480..8748f528 100644 --- a/ipppd/cbcp.c +++ b/ipppd/cbcp.c @@ -4,6 +4,8 @@ * Copyright (c) 1995 Pedro Roque Marques * All rights reserved. * + * 2000-07-25 Callback improvements by richard.kunze@web.de + * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, @@ -42,7 +44,7 @@ in the developr/rfc directory. #define PPP_CBCP 0xc029 /* Callback Control Protocol */ -char cbcp_rcsid[] = "$Id: cbcp.c,v 1.6 2000/02/08 16:24:55 kai Exp $"; +char cbcp_rcsid[] = "$Id: cbcp.c,v 1.7 2000/07/25 20:23:51 kai Exp $"; #include #include @@ -107,11 +109,11 @@ static void cbcp_init(int cbcp_unit) us = &cbcp[cbcp_unit]; memset(us, 0, sizeof(cbcp_state)); - us->us_unit = -1; + us->us_unit = -1; us->us_type |= (1 << CB_CONF_NO); - us->us_type |= (1 << CB_CONF_USER); - us->us_type |= (1 << CB_CONF_ADMIN); - us->us_type |= (1 << CB_CONF_LIST); + us->us_type |= (1 << CB_CONF_USER); + us->us_type |= (1 << CB_CONF_LIST); + us->us_type |= (1 << CB_CONF_ADMIN); } /* lower layer is up */ @@ -332,34 +334,51 @@ void cbcp_resp(cbcp_state *us) u_char buf[256]; u_char *bufp = buf; int len = 0; - struct cbcp *cbcp; + struct callback_opts *cbopt; + cbopt = &lcp_wantoptions[ lns[us->us_unit].lcp_unit ].cbopt; + + /* Always allow "no callback" and admin defined callback */ + us->us_type |= (1 << CB_CONF_NO); + us->us_type |= (1 << CB_CONF_ADMIN); + + /* Only go for user defined or choode from a list callback if + we do have a phone number to be called back at */ + if (cbopt->message && cbopt->mlen) { + us->us_type |= (1 << CB_CONF_USER); + us->us_type |= (1 << CB_CONF_LIST); + } cb_type = us->us_allowed & us->us_type; syslog(LOG_DEBUG, "cbcp_resp: cb_type=%d", cb_type); - cbcp = &lcp_wantoptions[ lns[us->us_unit].lcp_unit ].cbcp; if (!cb_type) { - syslog(LOG_DEBUG, "Your remote side wanted a callback-type you don't allow -> doing no callback"); + syslog(LOG_INFO, "Your remote side wanted a callback-type you don't allow -> doing no callback"); cb_type = 1 << CB_CONF_NO; } if (cb_type & ( 1 << CB_CONF_USER ) ) { syslog(LOG_DEBUG, "cbcp_resp CONF_USER"); PUTCHAR(CB_CONF_USER, bufp); - len = 3 + 1 + strlen(cbcp->message) + 1; + len = 3 + 1 + cbopt->mlen + 1; PUTCHAR(len , bufp); - PUTCHAR(5, bufp); /* delay */ - PUTCHAR(1, bufp); - BCOPY(cbcp->message, bufp, strlen(cbcp->message) + 1); + PUTCHAR(cbopt->delay, bufp); /* delay */ + PUTCHAR(1, bufp); /* Message type. Always 1 + according to the protocol specs, + but you never know with MS + protocols ;-/ */ + BCOPY(cbopt->message, bufp, cbopt->mlen + 1); cbcp_send(us, CBCP_RESP, buf, len); return; } + /* XXX: Callback to one number from a server defined list not yet + implemented */ + if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { PUTCHAR(CB_CONF_ADMIN, bufp); len = 3; PUTCHAR(len , bufp); - PUTCHAR(0, bufp); + PUTCHAR(cbopt->delay, bufp); cbcp_send(us, CBCP_RESP, buf, len); return; } @@ -367,9 +386,8 @@ void cbcp_resp(cbcp_state *us) if (cb_type & ( 1 << CB_CONF_NO ) ) { syslog(LOG_DEBUG, "cbcp_resp CONF_NO"); PUTCHAR(CB_CONF_NO, bufp); - len = 3; + len = 2; PUTCHAR(len , bufp); - PUTCHAR(0, bufp); cbcp_send(us, CBCP_RESP, buf, len); #if 0 /* diff --git a/ipppd/ipppd.h b/ipppd/ipppd.h index 2afb687f..55f2c8bf 100644 --- a/ipppd/ipppd.h +++ b/ipppd/ipppd.h @@ -4,6 +4,8 @@ * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * + * 2000-07-25 Callback improvements by richard.kunze@web.de + * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, @@ -16,7 +18,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipppd.h,v 1.19 2000/04/29 08:57:23 kai Exp $ + * $Id: ipppd.h,v 1.20 2000/07/25 20:23:51 kai Exp $ */ /* @@ -324,7 +326,7 @@ int sifproxyarp (int unit, u_int32_t his_adr); int cifproxyarp (int unit, u_int32_t his_adr); int sipxfaddr (int unit, u_int32_t network, unsigned char * node ); int cipxfaddr (int linkunit); -int ppp_available(void); +int ppp_available(char *dev); int logwtmputmp (int unit,char *line, char *name, char *host); int lock (char *dev); void unlock(void); diff --git a/ipppd/ipppd.man.in b/ipppd/ipppd.man.in index 6bff4677..7f7f2d6c 100644 --- a/ipppd/ipppd.man.in +++ b/ipppd/ipppd.man.in @@ -1,6 +1,6 @@ .\" manual page [] for ipppd 2.0 -.\" $Id: ipppd.man.in,v 1.9 2000/04/29 08:57:23 kai Exp $ -.\" CHECKIN $Date: 2000/04/29 08:57:23 $ +.\" $Id: ipppd.man.in,v 1.10 2000/07/25 20:23:51 kai Exp $ +.\" CHECKIN $Date: 2000/07/25 20:23:51 $ .\" SH section heading .\" SS subsection heading .\" LP paragraph @@ -115,6 +115,57 @@ compression in the corresponding direction. Disables compression; \fIipppd\fR will not request or agree to compress packets using the BSD-Compress scheme. .TP +.B callback \fI +Request the peer to call back at the location given in +. Ususally this is a phone number, but it may be interpreted +differently (or ignored) depending on the \fBcallback-type\fR option. +If is the empty string, \fIipppd\fR automatically tries to +negotiate a callback type that does not need a location to be specified. +.TP +.B callback-delay \fI +Callback delay for CBCP in seconds. If callback is negotiated using +CBCP, request that the peer waits at least seconds before calling +back. Ignored if callback is negotiated as specified in RFC +1570. Legal range is 0..255, default is 5. +.TP +.B callback-cbcp +Enable callback negotiation via CBCB (default). +.TP +.B -callback-cbcp +Disable callback negotiation via CBCB. +.TP +.B no-callback-cbcp +Disable callback negotiation via CBCB. +.TP +.B callback-cbcp-preferred +If both CBCP and RFC 1570 style callback negotiation is enabled, CBCP +is preferred (default) +.TP +.B callback-rfc1570-preferred +If both CBCP and RFC 1570 style callback negotiation is enabled, RFC +1570 style is preferred. +.TP +.B callback-rfc1570 +Enable RFC 1570 style callback negotiation (default). +.TP +.B -callback-rfc1570 +Disable RFC 1570 style callback negotiation. +.TP +.B no-callback-rfc1570 +Disable RFC 1570 style callback negotiation (default). +.TP +.B callback-type \fI +Specifies how to interpret the location identifier given as +parameter of the \fBcallback\fR option. Legal values are 0..4. A value +of 0 means that only callback types should be negotiated that need no +extra location id. No location id is sent to the peer in this case. +For RFC 1570 style callback negotiation, the values 1..4 +indicate how the peer should interpret the location identifier: +1 - id is a system specific dial string, 2 - id is used for database +lookup by the peer, 3 - id is a phone number, and 4 id is a name. For +CBCP callback negotiation, the location id is always interpreted as a +phone number. +.TP .B -ccp Necessary for a few netblazers on the remote side. .TP diff --git a/ipppd/lcp.c b/ipppd/lcp.c index bb9460cc..ea7ec468 100644 --- a/ipppd/lcp.c +++ b/ipppd/lcp.c @@ -8,6 +8,8 @@ * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * + * 2000-07-25 Callback improvements by richard.kunze@web.de + * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, @@ -21,7 +23,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -char lcp_rcsid[] = "$Id: lcp.c,v 1.10 2000/04/29 08:57:23 kai Exp $"; +char lcp_rcsid[] = "$Id: lcp.c,v 1.11 2000/07/25 20:23:51 kai Exp $"; /* * TODO: @@ -169,7 +171,7 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL; #define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ #define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ #define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ -#define CILEN_CBCP 3 +#define CILEN_CB 3 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") @@ -218,7 +220,12 @@ static void lcp_init(int unit) wo->neg_pcompression = 1; wo->neg_accompression = 1; wo->neg_lqr = 0; /* no LQR implementation yet */ - wo->neg_cbcp = 0; + wo->neg_callback = 0; + wo->cbopt.neg_cbcp = 1; + wo->cbopt.neg_rfc = 1; + wo->cbopt.rfc_preferred = 0; + wo->cbopt.type = CB_CBCP; + wo->cbopt.delay = 5; /* Default to 5 seconds callback delay */ wo->neg_mp = 0; /* we set this later, if nec. */ wo->neg_mpdiscr = 0; wo->neg_mpmrru = 0; @@ -243,7 +250,7 @@ static void lcp_init(int unit) ao->neg_mpmrru = 0; ao->neg_mpdiscr = 1; ao->neg_mpshortseq = 0; - ao->neg_cbcp = 0; + ao->neg_callback = 0; /* Always reject callback requests */ memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); xmit_accm[unit][3] = 0x60000000; @@ -606,7 +613,7 @@ static int lcp_cilen(fsm *f) #define LENCIMPDISCRI(neg,alen) (neg ? 3+alen : 0) #define LENCIMPMRRU(neg) (neg ? CILEN_SHORT : 0) #define LENCIMPSHORTSEQ(neg) (neg ? CILEN_VOID : 0) -#define LENCICB(neg,mlen) (neg ? CILEN_CBCP + mlen : 0) +#define LENCICB(neg,type,mlen) (neg ? CILEN_CB + (type!=CB_CBCP&&type!=CB_AUTH?mlen:0) : 0) /* * NB: we only ask for one of CHAP and UPAP, even if we will @@ -620,10 +627,10 @@ static int lcp_cilen(fsm *f) LENCILONG(go->neg_magicnumber) + LENCIVOID(go->neg_pcompression) + LENCIVOID(go->neg_accompression) + - LENCICB(go->neg_cbcp,go->cbcp.mlen) + - LENCIMPDISCRI(go->neg_mpdiscr,go->mp_alen) + - LENCIMPMRRU(go->neg_mpmrru) + - LENCIMPSHORTSEQ(go->neg_mpshortseq) ); + LENCICB(go->neg_callback,go->cbopt.type,go->cbopt.mlen) + + LENCIMPDISCRI(go->neg_mpdiscr,go->mp_alen) + + LENCIMPMRRU(go->neg_mpmrru) + + LENCIMPSHORTSEQ(go->neg_mpshortseq) ); } @@ -685,10 +692,11 @@ lcp_addci(fsm *f,u_char *ucp,int *lenp) #define ADDCICB(opt,neg,type,aval,alen) \ if(neg) { \ int i; \ + int checklen = ((type)==CB_CBCP||(type==CB_AUTH)?0:(alen)); \ PUTCHAR(opt,ucp); \ - PUTCHAR((alen+3),ucp); \ + PUTCHAR((checklen+3),ucp); \ PUTCHAR(type,ucp); \ - for(i=0;ineg_magicnumber, go->magicnumber); ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - ADDCICB(CI_CALLBACK, go->neg_cbcp, go->cbcp.type, go->cbcp.message,go->cbcp.mlen ); + ADDCICB(CI_CALLBACK, go->neg_callback, go->cbopt.type, + go->cbopt.message, go->cbopt.mlen ); ADDCISHORT(CI_MPMRRU,go->neg_mpmrru,go->mp_mrru); ADDCIVOID(CI_MPSHORTSEQ,go->neg_mpshortseq); ADDCIMPDISCR(CI_MPDISCRIMINATOR,go->neg_mpdiscr,go->mp_class,go->mp_addr,go->mp_alen ); @@ -833,18 +842,23 @@ static int lcp_ackci(fsm *f,u_char *p,int len) #define ACKCICB(opt,neg,type,aval,alen) \ if(neg) { \ int i; \ - if((len -= 3+alen) < 0) \ + int checklen; \ + checklen = (type!=CB_CBCP&&opt!=CB_AUTH?alen:0); \ + LCPDEBUG((LOG_DEBUG, "opt: %d, type: %d, checklen: %d, alen: %d, aval: %s", \ + opt, type, checklen, alen, aval)); \ + if((len -= 3+checklen) < 0) \ goto bad; \ GETCHAR(citype,p); \ GETCHAR(cilen,p); \ GETCHAR(cichar,p); \ - if(cilen != alen+3 || citype != opt || cichar != type) \ + if(cilen != checklen+3 || citype != opt || cichar != type) \ goto bad; \ - for(i=0;ineg_mru, go->mru); @@ -855,7 +869,8 @@ static int lcp_ackci(fsm *f,u_char *p,int len) ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - ACKCICB(CI_CALLBACK, go->neg_cbcp, go->cbcp.type , go->cbcp.message,go->cbcp.mlen ); + ACKCICB(CI_CALLBACK, go->neg_callback, go->cbopt.type , + go->cbopt.message,go->cbopt.mlen ); ACKCISHORT(CI_MPMRRU,go->neg_mpmrru,go->mp_mrru); ACKCIVOID(CI_MPSHORTSEQ,go->neg_mpshortseq); ACKCIMPDISCRI(CI_MPDISCRIMINATOR,go->neg_mpdiscr,go->mp_class,go->mp_addr,go->mp_alen); @@ -980,18 +995,6 @@ static int lcp_nakci(fsm *f,u_char *p,int len) no.neg = 1; \ code \ } -#define NAKCICB(opt,neg,code,alen) \ - if(go->neg && (len >= alen+3) && (p[1] == alen+3) && p[0] == opt) { \ - int i; \ - INCPTR(2,p); \ - len -= alen+3; \ - GETCHAR(cichar,p); \ - for(i=0;icbcp.mlen); - + /* + * If they've nak'd our callback request, see if we can fall + * back to a different method. If not, give up asking for callback. + */ + if(go->neg_callback && len >= CILEN_CB + && p[0] == CI_CALLBACK && p[1] >= CILEN_CB && p[1] <= len) { + int i; + int cb_type; + int mlen = p[1] - CILEN_CB; + INCPTR(2,p); + len -= mlen+CILEN_CB; + GETCHAR(cb_type,p); + for (i=0;icbopt.neg_rfc + && (wo->cbopt.type == CB_AUTH + || (wo->cbopt.type == CB_CBCP && wo->cbopt.mlen == 0)); + break; + case CB_PHONENO: + try.neg_callback = wo->cbopt.neg_rfc + && (wo->cbopt.type == CB_PHONENO + || (wo->cbopt.type == CB_CBCP && wo->cbopt.mlen != 0)); + break; + case CB_CBCP: + try.neg_callback = wo->cbopt.neg_cbcp; + break; + case CB_DIALSTRING: + case CB_LOCATIONID: + case CB_NAME: + try.neg_callback = wo->cbopt.neg_rfc && wo->cbopt.mlen != 0 + && wo->cbopt.type == cb_type; + break; + default: + try.neg_callback = 0; + break; + } + if (try.neg_callback) { + try.cbopt.type = cb_type; + if (cb_type != CB_AUTH && cb_type != CB_CBCP) { + try.cbopt.mlen = wo->cbopt.mlen; + try.cbopt.message = wo->cbopt.message; + } + LCPDEBUG((LOG_DEBUG, "Trying callback type %d", try.cbopt.type)); + } else { + syslog(LOG_INFO, "Requested callback type %d does not match our configuration -> doing no callback", cb_type); + } + } + /* * Check for a looped-back line. */ @@ -1148,6 +1200,10 @@ static int lcp_nakci(fsm *f,u_char *p,int len) if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) goto bad; break; + case CI_CALLBACK: + if (go->neg_callback || no.neg_callback) + goto bad; + break; case CI_MAGICNUMBER: if (go->neg_magicnumber || no.neg_magicnumber || cilen != CILEN_LONG) @@ -1213,7 +1269,7 @@ lcp_rejci(fsm *f,u_char *p,int len) u_char cichar; u_short cishort; u_int32_t cilong; -#ifdef DEBUGALL +#ifdef DEBUGLCP u_char *start = p; int plen = len; #endif @@ -1312,16 +1368,18 @@ lcp_rejci(fsm *f,u_char *p,int len) } \ try.neg = 0; \ } -#define REJCICB(opt,neg,type,aval,alen) \ - if(go->neg && (len >= alen+3) && (p[1] == alen+3) && p[0] == opt) { \ + +#define REJCICB(opt,neg,type,aval,alen) { \ + int checklen = (type!=CB_CBCP&&type!=CB_AUTH?alen:0); \ + if(go->neg && (len >= checklen+3) && (p[1] == checklen+3) && p[0] == opt) { \ int i; \ - len -= alen+3; \ + len -= checklen+3; \ INCPTR(2,p); \ GETCHAR(cichar,p); \ if(cichar != type) { \ syslog(LOG_WARNING , "Lcp-ConfRej, Callback: bad type!\n"); \ goto bad; } \ - for(i=0;imru); @@ -1342,7 +1400,7 @@ lcp_rejci(fsm *f,u_char *p,int len) REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); REJCIVOID(CI_PCOMPRESSION, neg_pcompression); REJCIVOID(CI_ACCOMPRESSION, neg_accompression); - REJCICB(CI_CALLBACK, neg_cbcp, go->cbcp.type, go->cbcp.message, go->cbcp.mlen ); + REJCICB(CI_CALLBACK, neg_callback, go->cbopt.type, go->cbopt.message, go->cbopt.mlen ); REJCISHORT(CI_MPMRRU,neg_mpmrru,go->mp_mrru); REJCIVOID(CI_MPSHORTSEQ,neg_mpshortseq); REJCIMPDISCRI(CI_MPDISCRIMINATOR,neg_mpdiscr,go->mp_class,go->mp_addr,go->mp_alen); diff --git a/ipppd/lcp.h b/ipppd/lcp.h index 2e1803c7..a8fa0f31 100644 --- a/ipppd/lcp.h +++ b/ipppd/lcp.h @@ -16,7 +16,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: lcp.h,v 1.1 1997/03/07 16:01:27 hipp Exp $ + * $Id: lcp.h,v 1.2 2000/07/25 20:23:51 kai Exp $ */ /* @@ -42,12 +42,28 @@ #define ECHOREQ 9 /* Echo Request */ #define ECHOREP 10 /* Echo Reply */ #define DISCREQ 11 /* Discard Request */ -#define CBCP_OPT 6 -struct cbcp { - int type; - unsigned char *message; - int mlen; + +/* + * Type constants for the CI_CALLBACK field. Types 0..4 are RFC 1570 + * callback codes that tell the peer how to interpret the callback + * message. Type 6 requests callback negotiation by CBCP. + */ +#define CB_AUTH 0 /* cb msg is not used */ +#define CB_DIALSTRING 1 /* cb msg is a system specific dial string */ +#define CB_LOCATIONID 2 /* cb msg is a location identifier */ +#define CB_PHONENO 3 /* cb msg is a E.164 (i.e. phone) number */ +#define CB_NAME 4 /* cb msg is a name */ +#define CB_CBCP 6 /* callback will be negotiated via cbcp */ + +struct callback_opts { + int neg_cbcp : 1; /* Enable CBCP callback negotiation */ + int neg_rfc : 1; /* Enable RFC 1570 callback negotiation */ + int rfc_preferred : 1; /* Try RFC 1570 callback negotiation first */ + int type; /* callback type as defined above */ + unsigned char *message; /* callback message (phone number in most cases) */ + int mlen; /* length of callback message */ + int delay; /* callback delay for cbcp */ }; /* @@ -70,14 +86,14 @@ typedef struct lcp_options { int neg_mpdiscr : 1; /* MP protocol ? */ int neg_mpmrru : 1; int neg_mp : 1; - int neg_cbcp : 1; + int neg_callback : 1; /* Negotiate callback */ u_char mp_class; /* MP discri. class */ u_char mp_addr[20]; /* MP discri. addr */ u_char mp_alen; u_short mp_mrru; /* MP mrru */ - u_char cb_type; - u_char cb_num[20]; - u_char cb_numlen; + u_char cb_type; + u_char cb_num[20]; + u_char cb_numlen; u_short mru; /* Value of MRU */ u_char chap_mdtype; /* which MD type (hashing algorithm) */ @@ -85,7 +101,7 @@ typedef struct lcp_options { u_int32_t magicnumber; int numloops; /* Number of loops during magic number neg. */ u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ - struct cbcp cbcp; + struct callback_opts cbopt; /* Callback options */ } lcp_options; extern fsm lcp_fsm[]; diff --git a/ipppd/main.c b/ipppd/main.c index 5a4fd004..965dd049 100644 --- a/ipppd/main.c +++ b/ipppd/main.c @@ -25,7 +25,7 @@ * PATCHLEVEL 9 */ -char main_rcsid[] = "$Id: main.c,v 1.17 2000/04/29 08:57:24 kai Exp $"; +char main_rcsid[] = "$Id: main.c,v 1.18 2000/07/25 20:23:51 kai Exp $"; #include #include @@ -148,6 +148,7 @@ int main(int argc,char **argv) struct timeval timo; sigset_t mask; struct protent *protp; + char *firstdev; if(argc > 1 && !strcmp(argv[1],"-version")) { #ifndef RADIUS @@ -224,7 +225,12 @@ int main(int argc,char **argv) */ make_options_global(0); - if (!ppp_available()) { + /* Use the first configured device to check wheter ppp is enabled */ + if ((firstdev = strrchr(lns[0].devnam, '/'))) + firstdev++; + else + firstdev = lns[0].devnam; + if (!ppp_available(firstdev)) { fprintf(stderr, no_ppp_msg); exit(1); } @@ -244,7 +250,8 @@ int main(int argc,char **argv) sprintf(devstr,"Found %d device%s: ",numdev, numdev==1?"":"s"); for(i=0;i #include @@ -163,7 +163,15 @@ static int noip __P((int)); static int nomagicnumber __P((int)); static int setmru __P((int,char **)); static int setmtu __P((int,char **)); -static int setcbcp __P((int,char **)); +static int setcallbackdelay __P((int,char **)); +static int setcallbackcbcp __P((int)); +static int setcallbacknocbcp __P((int)); +static int setcallbackrfc __P((int)); +static int setcallbacknorfc __P((int)); +static int setcallbackcbcpfirst __P((int)); +static int setcallbackcbcplast __P((int)); +static int setcallbacktype __P((int,char **)); +static int setcallback __P((int,char **)); static int setifmtu __P((int)); static int nomru __P((int)); static int nopcomp __P((int)); @@ -340,7 +348,17 @@ static struct cmd { {"domain", 1, setdomain}, /* Add given domain name to hostname*/ {"mru", 1, setmru}, /* Set MRU value for negotiation */ {"mtu", 1, setmtu}, /* Set our MTU */ - {"callback", 1, setcbcp}, /* Ask for callback */ + {"callback", 1, setcallback}, /* Ask for callback */ + {"callback-delay", 1, setcallbackdelay}, /* Callback delay for CBCP */ + {"callback-cbcp", 0, setcallbackcbcp}, /* Enable CBCP callback negotiation */ + {"callback-rfc1570", 0, setcallbackrfc}, /* Enable RCFC 1570 style callback negotiation */ + {"-callback-cbcp", 0, setcallbacknocbcp}, /* Disable CBCP callbacks */ + {"-callback-rfc1570", 0, setcallbacknorfc}, /* Disable RCFC 1570 style callbacks */ + {"no-callback-cbcp", 0, setcallbacknocbcp}, /* Disable CBCP callbacks */ + {"no-callback-rfc1570", 0, setcallbacknorfc}, /* Disable RCFC 1570 style callbacks */ + {"callback-type", 1, setcallbacktype}, /* Callback type for RFC 1570 style callbacks */ + {"callback-cbcp-preferred", 0, setcallbackcbcpfirst}, /* Prefer CBCP callback negotiation */ + {"callback-rfc1570-preferred", 0, setcallbackcbcplast}, /* Prefer RFC 1570 callback negotiation */ {"useifmtu", 0, setifmtu}, /* get MTU value from attached network device */ {"netmask", 1, setnetmask}, /* set netmask */ {"passive", 0, setpassive}, /* Set passive mode */ @@ -556,7 +574,7 @@ void make_options_global(int slot) ccp_fsm[i] = ccp_fsm[slot]; chap[i] = chap[slot]; upap[i] = upap[slot]; - cbcp[i] = cbcp[slot]; + cbcp[i] = cbcp[slot]; memcpy(xmit_accm[i],xmit_accm[slot],sizeof(xmit_accm[0])); } @@ -1212,30 +1230,101 @@ static int setmtu(int slot,char **argv) return (1); } -static int setcbcp(int slot,char **argv) +static int setcallbackdelay(int slot,char **argv) { - char *a; - int val; + int delay; + if(!int_option(*argv, &delay)) + return 0; + if (delay > 255) { + option_error("callback delay of %d is too large", delay); + return 0; + } + lcp_wantoptions[slot].cbopt.delay = delay; + return 1; +} - lcp_wantoptions[slot].neg_cbcp = 1; +static int setcallbackcbcp(int slot) +{ + lcp_wantoptions[slot].cbopt.neg_cbcp = 1; + cbcp_protent.enabled_flag = 1; + return 1; +} + +static int setcallbacknocbcp(int slot) +{ + lcp_wantoptions[slot].cbopt.neg_cbcp = 0; + cbcp_protent.enabled_flag = 0; + return 1; +} + +static int setcallbackrfc(int slot) +{ + lcp_wantoptions[slot].cbopt.neg_rfc = 1; + return 1; +} + +static int setcallbacknorfc(int slot) +{ + lcp_wantoptions[slot].cbopt.neg_rfc = 0; + return 1; +} + +static int setcallbackcbcpfirst(int slot) +{ + lcp_wantoptions[slot].cbopt.rfc_preferred = 0; + return 1; +} + +static int setcallbackcbcplast(int slot) +{ + lcp_wantoptions[slot].cbopt.rfc_preferred = 1; + return 1; +} + +static int setcallbacktype(int slot,char **argv) +{ + int type; + if(!int_option(*argv, &type)) + return 0; + switch (type) { + case CB_AUTH: + lcp_wantoptions[slot].cbopt.mlen = 0; + lcp_wantoptions[slot].cbopt.message = 0; + break; + case CB_DIALSTRING: + case CB_LOCATIONID: + case CB_PHONENO: + case CB_NAME: + break; + default: + option_error("unkown callback type: %d", type); + return 0; + } + lcp_wantoptions[slot].cbopt.type = type; + return 1; +} + +static int setcallback(int slot,char **argv) +{ + lcp_wantoptions[slot].neg_callback = 1; + if (lcp_wantoptions[slot].cbopt.type != CB_AUTH) { + lcp_wantoptions[slot].cbopt.message = strdup(*argv); + if (lcp_wantoptions[slot].cbopt.message != 0) { + lcp_wantoptions[slot].cbopt.mlen = + strlen(lcp_wantoptions[slot].cbopt.message); + if (!lcp_wantoptions[slot].cbopt.mlen) + lcp_wantoptions[slot].cbopt.message = 0; + } else { + lcp_wantoptions[slot].cbopt.mlen = 0; + } + } else { + lcp_wantoptions[slot].cbopt.mlen = 0; + lcp_wantoptions[slot].cbopt.message = 0; + } + + if (lcp_wantoptions[slot].cbopt.neg_cbcp) cbcp_protent.enabled_flag = 1; -/* change this: CBCP slot != LCP slot !!*/ - if( (a = strchr(*argv,',')) ) { - lcp_wantoptions[slot].cbcp.message = strdup(a+1); - lcp_wantoptions[slot].cbcp.mlen = strlen(a+1); - } - else { - lcp_wantoptions[slot].cbcp.message = ""; - lcp_wantoptions[slot].cbcp.mlen = 0; - } - val = atoi(*argv); - if(val & ~0xff) { - fprintf(stderr,"illegal callback option %d\n",val); - lcp_wantoptions[slot].cbcp.type = 0; - return 0; - } - lcp_wantoptions[slot].cbcp.type = val & 0xff; - return 1; + return 1; } diff --git a/ipppd/patchlevel.h b/ipppd/patchlevel.h index c39bd108..ab638408 100644 --- a/ipppd/patchlevel.h +++ b/ipppd/patchlevel.h @@ -1,4 +1,4 @@ -#define PATCHLEVEL 11 +#define PATCHLEVEL 12 #define VERSION "i2.2" #define IMPLEMENTATION "" diff --git a/ipppd/sys-linux.c b/ipppd/sys-linux.c index b224ffe8..54649f0a 100644 --- a/ipppd/sys-linux.c +++ b/ipppd/sys-linux.c @@ -22,7 +22,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -char sys_rcsid[] = "$Id: sys-linux.c,v 1.24 2000/04/29 08:57:24 kai Exp $"; +char sys_rcsid[] = "$Id: sys-linux.c,v 1.25 2000/07/25 20:23:51 kai Exp $"; #define _LINUX_STRING_H_ @@ -1278,9 +1278,9 @@ static void decode_version (char *buf, int *version, /* * ppp_available - check whether the system has any ppp interfaces - * (in fact we check whether we can do an ioctl on ppp0). + * (in fact we check whether we can do an ioctl on devname). */ -int ppp_available(void) +int ppp_available(char *devname) { int s; struct ifreq ifr; @@ -1293,7 +1293,7 @@ int ppp_available(void) if( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return 0; - strncpy (ifr.ifr_name, "ippp0", sizeof (ifr.ifr_name)); + strncpy (ifr.ifr_name, devname, sizeof (ifr.ifr_name)); if(ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) return 0; @@ -1322,8 +1322,8 @@ int ppp_available(void) sprintf(no_ppp_msg, "Sorry - isdnPPP driver version %d.%d.%d is out of date.\n" - "Maybe ippp0 has no 'syncppp' encapsulation?\n", - driver_version, driver_modification, driver_patch); + "Maybe %s has no 'syncppp' encapsulation?\n", + driver_version, driver_modification, driver_patch, devname); return 0; } return 1;