attached is a revised patch for bezeq support, relative to current pptp cvs. bezeq support is now a run time mechanism, via a --quirks=BEZEQ_ISRAEL switch. for this, i implemented a general quirks mechanism, which allows overriding the out_call_rqst packet construction, start_ctrl_conn packet construction and the set_link_info packet construction.
comments are welcome, of course. * the quirks mechanism is general enough to be useful to other people, but not too general to be cumbersome to use. i added hooks for the exact places i need them, other hooks can be added later, if needed. * i'm not too happy with the interface to the quirks mechanism, nor with hardware/isp distinction. perhaphs there should be --hardware-quirks and --isp-quirks? for now, i index the quirks table based on isp (bezeq) only, since the fix has been shown to work even with non quirky hardware. * this is only a rough patch. It Works For Me(tm). diff -ur --new-file pptp-linux/Makefile pptp-mulix/Makefile --- pptp-linux/Makefile Fri May 11 10:48:14 2001 +++ pptp-mulix/Makefile Wed Nov 14 12:12:40 2001 @@ -17,12 +17,18 @@ PPTP_BIN = pptp PPTP_OBJS = pptp.o pptp_gre.o ppp_fcs.o \ pptp_ctrl.o dirutil.o vector.o \ - inststr.o util.o version.o -PPTP_DEPS = pptp_callmgr.h pptp_gre.h ppp_fcs.h util.h + inststr.o util.o version.o \ + pptp_quirks.o orckit_quirks.o + +PPTP_DEPS = pptp_callmgr.h pptp_gre.h ppp_fcs.h util.h \ + pptp_quirks.h orckit_quirks.h CALLMGR_BIN = pptp_callmgr -CALLMGR_OBJS = pptp_callmgr.o pptp_ctrl.o dirutil.o util.o vector.o version.o -CALLMGR_DEPS = pptp_callmgr.h pptp_ctrl.h dirutil.h pptp_msg.h vector.h +CALLMGR_OBJS = pptp_callmgr.o pptp_ctrl.o dirutil.o util.o \ + vector.o version.o pptp_quirks.o orckit_quirks.o +CALLMGR_DEPS = pptp_callmgr.h pptp_ctrl.h dirutil.h pptp_msg.h vector.h \ + pptp_quirks.h orckit_quirks.h + all: $(PPTP_BIN) $(CALLMGR_BIN) diff -ur --new-file pptp-linux/orckit_quirks.c pptp-mulix/orckit_quirks.c --- pptp-linux/orckit_quirks.c Thu Jan 1 02:00:00 1970 +++ pptp-mulix/orckit_quirks.c Wed Nov 14 13:21:14 2001 @@ -0,0 +1,86 @@ +/* orckit_quirks.c ...... fix quirks in orckit adsl modems + * mulix <[EMAIL PROTECTED]> + * + * $Id$ + */ + +#include <string.h> +#include <netinet/in.h> +#include "pptp_msg.h" +#include "pptp_options.h" +#include "pptp_ctrl.h" +#include "util.h" + + + +/* return 0 on success, non zero otherwise */ +int +orckit_atur3_build_hook(struct pptp_out_call_rqst* packet) +{ + + unsigned int length = 10; + + struct pptp_out_call_rqst fixed_packet = { + PPTP_HEADER_CTRL(PPTP_OUT_CALL_RQST), + 0, /* hton16(call->callid) */ + 0, /* hton16(call->sernum) */ + hton32(PPTP_BPS_MIN), hton32(PPTP_BPS_MAX), + hton32(PPTP_BEARER_DIGITAL), hton32(PPTP_FRAME_ANY), + hton16(PPTP_WINDOW), 0, hton16(length), 0, + {'R','E','L','A','Y','_','P','P','P','1',0}, {0} + }; + + if (!packet) + return -1; + + memcpy(packet, &fixed_packet, sizeof(*packet)); + + log("%s called\n", __FUNCTION__); + return 0; +} + +/* return 0 on success, non zero otherwise */ +int +orckit_atur3_set_link_hook(struct pptp_set_link_info* packet, + int peer_call_id) +{ + struct pptp_set_link_info fixed_packet = { + PPTP_HEADER_CTRL(PPTP_SET_LINK_INFO), + hton16(peer_call_id), + 0, + 0xffffffff, + 0xffffffff}; + + if (!packet) + return -1; + + memcpy(packet, &fixed_packet, sizeof(*packet)); + return 0; +} + +int +orckit_atur3_start_ctrl_conn(struct pptp_start_ctrl_conn* packet) +{ + struct pptp_start_ctrl_conn fixed_packet = { + {0}, /* we'll set the header later */ + hton16(PPTP_VERSION), 0, 0, + hton32(PPTP_FRAME_ASYNC), hton32(PPTP_BEARER_ANALOG), + hton16(0) /* max channels */, + hton16(0x6021), + {'R','E','L','A','Y','_','P','P','P','1',0}, /* hostname */ + {'M','S',' ','W','i','n',' ','N','T',0} /* vendor */ + }; + + if (!packet) + return -1; + + /* grab the header from the original packet, since we dont + know if this is a request or a reply */ + memcpy(&fixed_packet.header, &packet->header, sizeof(struct pptp_header)); + + /* and now overwrite the full packet, effectively preserving the header */ + memcpy(packet, &fixed_packet, sizeof(*packet)); + return 0; +} + + diff -ur --new-file pptp-linux/orckit_quirks.h pptp-mulix/orckit_quirks.h --- pptp-linux/orckit_quirks.h Thu Jan 1 02:00:00 1970 +++ pptp-mulix/orckit_quirks.h Wed Nov 14 12:34:21 2001 @@ -0,0 +1,27 @@ +/* orckit_quirks.h ...... fix quirks in orckit adsl modems + * mulix <[EMAIL PROTECTED]> + * + * $Id$ + */ + +#ifndef INC_ORCKIT_QUIRKS_H_ +#define INC_ORCKIT_QUIRKS_H_ + +#include "pptp_options.h" +#include "pptp_ctrl.h" +#include "pptp_msg.h" + +/* return 0 on success, non zero otherwise */ +int +orckit_atur3_build_hook(struct pptp_out_call_rqst* packt); + +/* return 0 on success, non zero otherwise */ +int +orckit_atur3_set_link_hook(struct pptp_set_link_info* packet, + int peer_call_id); + +/* return 0 on success, non zero otherwise */ +int +orckit_atur3_start_ctrl_conn(struct pptp_start_ctrl_conn* packet); + +#endif /* INC_ORCKIT_QUIRKS_H_ */ Binary files pptp-linux/pptp and pptp-mulix/pptp differ diff -ur --new-file pptp-linux/pptp.c pptp-mulix/pptp.c --- pptp-linux/pptp.c Mon Aug 6 10:31:50 2001 +++ pptp-mulix/pptp.c Wed Nov 14 12:58:55 2001 @@ -34,6 +34,7 @@ #include "version.h" #include "inststr.h" #include "util.h" +#include "pptp_quirks.h" #ifndef PPPD_BINARY #define PPPD_BINARY "pppd" @@ -49,11 +50,13 @@ void usage(char *progname) { fprintf(stderr, "%s\n" - "Usage:\n" - " %s hostname [[--phone <phone number>] -- ][ pppd options]\n" - "\nOr using pppd option pty: \n" - " pty \" %s hostname --nolaunchpppd [--phone <phone number>]\"\n" , - version, progname, progname); + "patched by mulix <[EMAIL PROTECTED]> for Bezeq, Israel\n" + "Usage:\n" + " %s hostname [[--phone <phone number>] [--quirks ISP_NAME] -- ][ pppd +options]\n" + "\nOr using pppd option pty: \n" + " pty \" %s hostname --nolaunchpppd [--phone <phone number>]\"\n" + "Currently recognized ISP_NAMEs for quirks are BEZEQ_ISRAEL\n", + version, progname, progname); log("%s called with wrong arguments, program not started.", progname); exit(1); @@ -98,6 +101,7 @@ static struct option long_options[] = { {"phone", 1, 0, 0}, {"nolaunchpppd", 0, 0, 0}, + {"quirks", 1, 0, 0}, {0, 0, 0, 0} }; int option_index = 0; @@ -114,9 +118,13 @@ strncpy(phonenrbuf,optarg,sizeof(phonenrbuf)); phonenrbuf[sizeof(phonenrbuf)-1]='\0'; phonenr=phonenrbuf; - }else if(option_index == 1) /* --nolaunchpppd specified */ + }else if(option_index == 1) {/* --nolaunchpppd specified */ launchpppd=0; - /* other pptp options come here */ + }else if(option_index == 2) {/* --quirks specified */ + if (set_quirk_index(find_quirk(optarg))) + usage(argv[0]); + } + /* other pptp options come here */ break; case '?': /* unrecognised option, treat it as the first pppd option */ /* fall through */ Binary files pptp-linux/pptp_callmgr and pptp-mulix/pptp_callmgr differ diff -ur --new-file pptp-linux/pptp_ctrl.c pptp-mulix/pptp_ctrl.c --- pptp-linux/pptp_ctrl.c Mon Apr 30 06:42:36 2001 +++ pptp-mulix/pptp_ctrl.c Wed Nov 14 12:59:42 2001 @@ -21,6 +21,7 @@ #include "pptp_options.h" #include "vector.h" #include "util.h" +#include "pptp_quirks.h" /* BECAUSE OF SIGNAL LIMITATIONS, EACH PROCESS CAN ONLY MANAGE ONE * CONNECTION. SO THIS 'PPTP_CONN' STRUCTURE IS A BIT MISLEADING. @@ -118,6 +119,8 @@ void pptp_dispatch_packet(PPTP_CONN * conn, void * buffer, size_t size); /* Dispatch packets (control messages) */ void pptp_dispatch_ctrl_packet(PPTP_CONN * conn, void * buffer, size_t size); +/* Set link info, for pptp servers that need it */ +void pptp_set_link(PPTP_CONN * conn, int peer_call_id); /*----------------------------------------------------------------------*/ /* Constructors and Destructors. */ @@ -159,6 +162,12 @@ hton16(PPTP_MAX_CHANNELS), hton16(PPTP_FIRMWARE_VERSION), PPTP_HOSTNAME, PPTP_VENDOR }; + + /* fix this packet, if necessary */ + int idx; + if ((idx = get_quirk_index()) != -1 && pptp_fixups[idx].start_ctrl_conn) + pptp_fixups[idx].start_ctrl_conn(&packet); + if (pptp_send_ctrl_packet(conn, &packet, sizeof(packet))) conn->conn_state = CONN_WAIT_CTL_REPLY; else return NULL; /* could not send initial start request. */ @@ -213,6 +222,11 @@ hton16(PPTP_WINDOW), 0, 0, 0, {0}, {0} }; + int idx; + /* if we have a quirk, build a new packet to fit it */ + if ((idx = get_quirk_index()) != -1 && pptp_fixups[idx].out_call_rqst_hook) + pptp_fixups[idx].out_call_rqst_hook(&packet); + /* fill in the phone number if it was specified */ if( phonenr ){ strncpy(packet.phone_num, phonenr, sizeof(packet.phone_num)); @@ -500,6 +514,12 @@ hton32(PPTP_FRAME_CAP), hton32(PPTP_BEARER_CAP), hton16(PPTP_MAX_CHANNELS), hton16(PPTP_FIRMWARE_VERSION), PPTP_HOSTNAME, PPTP_VENDOR }; + + /* fix this packet, if necessary */ + int idx; + if ((idx = get_quirk_index()) != -1 && pptp_fixups[idx].start_ctrl_conn) + pptp_fixups[idx].start_ctrl_conn(&reply); + if (conn->conn_state == CONN_IDLE) { if (ntoh16(packet->version) < PPTP_VERSION) { /* Can't support this (earlier) PPTP_VERSION */ @@ -639,8 +659,21 @@ if (call->state.pns == PNS_WAIT_REPLY) { /* check for errors */ if (packet->result_code!=1) { - /* An error. Log it. */ - log("Error opening call. [callid %d]", (int) callid); + /* An error. Log it verbosely. */ + unsigned int legal_error_value = + sizeof(pptp_general_errors)/sizeof(pptp_general_errors[0]); + int err = packet->error_code; + log("Error '%d' opening call. [callid %d]", + packet->result_code, (int) callid); + log("Error code is '%d', Cause code is '%d'", err, + packet->cause_code); + if ((err > 0) && (err < legal_error_value)){ + log("Error is '%s', Error message: '%s'", + pptp_general_errors[err].name, + pptp_general_errors[err].desc); + } + + call->state.pns = PNS_IDLE; if (call->callback!=NULL) call->callback(conn, call, CALL_OPEN_FAIL); pptp_call_destroy(conn, call); @@ -650,6 +683,8 @@ call->peer_call_id = ntoh16(packet->call_id); call->speed = ntoh32(packet->speed); pptp_reset_timer(); + pptp_set_link(conn, call->peer_call_id); + if (call->callback!=NULL) call->callback(conn, call, CALL_OPEN_DONE); log("Outgoing call established (call ID %u, peer's call ID %u).\n", call->call_id, call->peer_call_id); @@ -720,6 +755,23 @@ pptp_conn_close(conn, close_reason); } +void +pptp_set_link(PPTP_CONN* conn, int peer_call_id) +{ + int idx; + + /* if we need to send a set_link packet because of buggy + hardware or pptp server, do it now */ + if ((idx = get_quirk_index()) != -1 && pptp_fixups[idx].set_link_hook) { + struct pptp_set_link_info packet; + pptp_fixups[idx].set_link_hook(&packet, peer_call_id); + + if (pptp_send_ctrl_packet(conn, &packet, sizeof(packet))) { + log("pptp_set_link() packet sending succesfull"); + pptp_reset_timer(); + } + } +} /********************* Get info from call structure *******************/ diff -ur --new-file pptp-linux/pptp_quirks.c pptp-mulix/pptp_quirks.c --- pptp-linux/pptp_quirks.c Thu Jan 1 02:00:00 1970 +++ pptp-mulix/pptp_quirks.c Wed Nov 14 13:34:48 2001 @@ -0,0 +1,54 @@ +/* pptp_quirks.c ...... various options to fix quirks found in buggy adsl modems + * mulix <[EMAIL PROTECTED]> + * + * $Id$ + */ + +#include <string.h> +#include "orckit_quirks.h" +#include "pptp_quirks.h" + +static int quirk_index = -1; + +struct pptp_fixup pptp_fixups[] = { + {BEZEQ_ISRAEL, ORCKIT, ORCKIT_ATUR3, + orckit_atur3_build_hook, + orckit_atur3_start_ctrl_conn, + orckit_atur3_set_link_hook} +}; + +static int fixups_sz = sizeof(pptp_fixups)/sizeof(pptp_fixups[0]); + +/* return 0 on success, non 0 otherwise */ +int set_quirk_index(int index) +{ + if (index >= 0 && index < fixups_sz) { + quirk_index = index; + return 0; + } + + return -1; +} + +int get_quirk_index() +{ + return quirk_index; +} + +/* return the index for this isp in the quirks table, -1 if not found */ +int find_quirk(const char* isp_name) +{ + int i = 0; + if (isp_name) { + while (i < fixups_sz && pptp_fixups[i].isp) { + if (!strcmp(pptp_fixups[i].isp, isp_name)) { + return i; + } + ++i; + } + } + + return -1; +} + + diff -ur --new-file pptp-linux/pptp_quirks.h pptp-mulix/pptp_quirks.h --- pptp-linux/pptp_quirks.h Thu Jan 1 02:00:00 1970 +++ pptp-mulix/pptp_quirks.h Wed Nov 14 13:01:39 2001 @@ -0,0 +1,59 @@ +/* pptp_quirks.h ...... various options to fix quirks found in buggy adsl modems + * mulix <[EMAIL PROTECTED]> + * + * $Id$ + */ + +#ifndef INC_PPTP_QUIRKS_H +#define INC_PPTP_QUIRKS_H + +/* isp defs - correspond to slots in the fixups table */ +#define BEZEQ_ISRAEL "BEZEQ_ISRAEL" + +/* vendor defs */ + +#define ORCKIT 1 +#define ALCATEL 2 + +/* device defs */ + +#define ORCKIT_ATUR2 1 +#define ORCKIT_ATUR3 2 + +#include "pptp_msg.h" +#include "pptp_ctrl.h" + +struct pptp_fixup { + const char* isp; /* which isp? e.g. Bezeq in Israel */ + int vendor; /* which vendor? e.g. Orckit */ + int device; /* which device? e.g. Orckit Atur3 */ + + /* use this hook to build your own out call request packet */ + int (*out_call_rqst_hook)(struct pptp_out_call_rqst* packet); + + /* use this hook to build your own start control connection packet */ + /* note that this hook is called from two different places, depending + on whether this is a request or reply */ + int (*start_ctrl_conn)(struct pptp_start_ctrl_conn* packet); + + /* use this hook if you need to send a 'set_link' packet once + the connection is established */ + int (*set_link_hook)(struct pptp_set_link_info* packet, + int peer_call_id); +}; + +extern struct pptp_fixup pptp_fixups[]; + +/* find the index for this isp in the quirks table */ +/* return the index on success, -1 if not found */ +int find_quirk(const char* isp_name); + +/* set the global quirk index. return 0 on success, non 0 otherwise */ +int set_quirk_index(int index); + +/* get the global quirk index. return the index on success, + -1 if no quirk is defined */ +int get_quirk_index(); + + +#endif /* INC_PPTP_QUIRKS_H */ -- mulix http://www.pointer.co.il/~mulix/ http://syscalltrack.sf.net/ ================================================================= To unsubscribe, send mail to [EMAIL PROTECTED] with the word "unsubscribe" in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]