diff -NurpP ppp-2.4.2.orig/pppd/options.c ppp-2.4.2/pppd/options.c --- ppp-2.4.2.orig/pppd/options.c 2005-08-04 21:37:28 +0500 +++ ppp-2.4.2/pppd/options.c 2005-08-04 21:39:38 +0500 @@ -109,6 +109,8 @@ char linkname[MAXPATHLEN]; /* logical na bool tune_kernel; /* may alter kernel settings */ int connect_delay = 1000; /* wait this many ms after connect script */ int req_unit = -1; /* requested interface unit */ +int req_unit_min = -1; /* requested interface unit min number */ +int req_unit_max = -1; /* requested interface unit max number */ bool multilink = 0; /* Enable multilink operation */ char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ @@ -271,6 +273,14 @@ option_t general_options[] = { "PPP interface unit number to use if possible", OPT_PRIO | OPT_LLIMIT, 0, 0 }, + { "unit_min", o_int, &req_unit_min, + "PPP interface minimum unit number to use if possible", + OPT_PRIO | OPT_LLIMIT, 0, 0 }, + + { "unit_max", o_int, &req_unit_max, + "PPP interface maximum unit number to use if possible", + OPT_PRIO | OPT_LLIMIT, 0, 0 }, + { "dump", o_bool, &dump_options, "Print out option values after parsing all options", 1 }, { "dryrun", o_bool, &dryrun, diff -NurpP ppp-2.4.2.orig/pppd/pppd.h ppp-2.4.2/pppd/pppd.h --- ppp-2.4.2.orig/pppd/pppd.h 2005-08-04 21:37:28 +0500 +++ ppp-2.4.2/pppd/pppd.h 2005-08-04 21:40:19 +0500 @@ -307,6 +307,8 @@ extern bool tune_kernel; /* May alter ke extern int connect_delay; /* Time to delay after connect script */ extern int max_data_rate; /* max bytes/sec through charshunt */ extern int req_unit; /* interface unit number to use */ +extern int req_unit_min; /* interface unit minimum number to use */ +extern int req_unit_max; /* interface unit maximum number to use */ extern bool multilink; /* enable multilink operation */ extern bool noendpoint; /* don't send or accept endpt. discrim. */ extern char *bundle_name; /* bundle name for multilink */ diff -NurpP ppp-2.4.2.orig/pppd/sys-linux.c ppp-2.4.2/pppd/sys-linux.c --- ppp-2.4.2.orig/pppd/sys-linux.c 2005-08-04 21:37:28 +0500 +++ ppp-2.4.2/pppd/sys-linux.c 2005-08-04 21:48:29 +0500 @@ -638,13 +638,45 @@ static int make_ppp_unit() || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("Couldn't set /dev/ppp to nonblock: %m"); - ifunit = req_unit; - x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); - if (x < 0 && req_unit >= 0 && errno == EEXIST) { - warn("Couldn't allocate PPP unit %d as it is already in use", req_unit); - ifunit = -1; + if (req_unit >= 0 && req_unit_min < 0 && req_unit_max < 0) { + ifunit = req_unit; + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + if (x < 0 && req_unit >= 0 && errno == EEXIST) { + warn("Couldn't allocate PPP unit %d as it is already in use", req_unit); + ifunit = -1; + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + } + } + else if (req_unit_min >= 0 ) { + if (req_unit_min >= req_unit_max) { + int tmp; + /* Swap it */ + tmp = req_unit_max; + req_unit_max = req_unit_min; + req_unit_min = tmp; + } + /* Try 16 interfaces by default */ + if (req_unit_max < 0) + req_unit_max = req_unit_min + 0xF; + + for (ifunit = req_unit_min; ifunit <= req_unit_max; ifunit++) { + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + if (x < 0 && errno == EEXIST) { + warn("Couldn't allocate PPP unit %d as it is already in use", ifunit); + } + if ( x >= 0 ) + break; + } + if (x < 0) + { + warn("Couldn't allocate PPP unit from %d to %d as all range is already in use", req_unit_min, req_unit_max); + ifunit = -1; + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); + } } + + if (x < 0) error("Couldn't create new ppp unit: %m"); return x;