ipcp.c 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311
  1. /*
  2. * ipcp.c - PPP IP Control Protocol.
  3. *
  4. * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. *
  18. * 3. The name "Carnegie Mellon University" must not be used to
  19. * endorse or promote products derived from this software without
  20. * prior written permission. For permission or any legal
  21. * details, please contact
  22. * Office of Technology Transfer
  23. * Carnegie Mellon University
  24. * 5000 Forbes Avenue
  25. * Pittsburgh, PA 15213-3890
  26. * (412) 268-4387, fax: (412) 268-7395
  27. * tech-transfer@andrew.cmu.edu
  28. *
  29. * 4. Redistributions of any form whatsoever must retain the following
  30. * acknowledgment:
  31. * "This product includes software developed by Computing Services
  32. * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
  33. *
  34. * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
  35. * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  36. * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
  37. * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  38. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  39. * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  40. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  41. */
  42. #define RCSID "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $"
  43. /*
  44. * TODO:
  45. */
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <stdlib.h>
  49. #include <netdb.h>
  50. #include <sys/param.h>
  51. #include <sys/types.h>
  52. #include <sys/socket.h>
  53. #include <netinet/in.h>
  54. #include <arpa/inet.h>
  55. #include "pppd.h"
  56. #include "fsm.h"
  57. #include "ipcp.h"
  58. #include "pathnames.h"
  59. static const char rcsid[] = RCSID;
  60. /* global vars */
  61. ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
  62. ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
  63. ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
  64. ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
  65. u_int32_t netmask = 0; /* IP netmask to set on interface */
  66. bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */
  67. bool noremoteip = 0; /* Let him have no IP address */
  68. /* Hook for a plugin to know when IP protocol has come up */
  69. void (*ip_up_hook) __P((void)) = NULL;
  70. /* Hook for a plugin to know when IP protocol has come down */
  71. void (*ip_down_hook) __P((void)) = NULL;
  72. /* Hook for a plugin to choose the remote IP address */
  73. void (*ip_choose_hook) __P((u_int32_t *)) = NULL;
  74. /* Notifiers for when IPCP goes up and down */
  75. struct notifier *ip_up_notifier = NULL;
  76. struct notifier *ip_down_notifier = NULL;
  77. /* local vars */
  78. static int default_route_set[NUM_PPP]; /* Have set up a default route */
  79. static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */
  80. static bool usepeerdns; /* Ask peer for DNS addrs */
  81. static int ipcp_is_up; /* have called np_up() */
  82. static int ipcp_is_open; /* haven't called np_finished() */
  83. static bool ask_for_local; /* request our address from peer */
  84. static char vj_value[8]; /* string form of vj option value */
  85. static char netmask_str[20]; /* string form of netmask value */
  86. /*
  87. * Callbacks for fsm code. (CI = Configuration Information)
  88. */
  89. static void ipcp_resetci __P((fsm *)); /* Reset our CI */
  90. static int ipcp_cilen __P((fsm *)); /* Return length of our CI */
  91. static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
  92. static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
  93. static int ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */
  94. static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
  95. static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
  96. static void ipcp_up __P((fsm *)); /* We're UP */
  97. static void ipcp_down __P((fsm *)); /* We're DOWN */
  98. static void ipcp_finished __P((fsm *)); /* Don't need lower layer */
  99. fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
  100. static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
  101. ipcp_resetci, /* Reset our Configuration Information */
  102. ipcp_cilen, /* Length of our Configuration Information */
  103. ipcp_addci, /* Add our Configuration Information */
  104. ipcp_ackci, /* ACK our Configuration Information */
  105. ipcp_nakci, /* NAK our Configuration Information */
  106. ipcp_rejci, /* Reject our Configuration Information */
  107. ipcp_reqci, /* Request peer's Configuration Information */
  108. ipcp_up, /* Called when fsm reaches OPENED state */
  109. ipcp_down, /* Called when fsm leaves OPENED state */
  110. NULL, /* Called when we want the lower layer up */
  111. ipcp_finished, /* Called when we want the lower layer down */
  112. NULL, /* Called when Protocol-Reject received */
  113. NULL, /* Retransmission is necessary */
  114. NULL, /* Called to handle protocol-specific codes */
  115. "IPCP" /* String name of protocol */
  116. };
  117. /*
  118. * Command-line options.
  119. */
  120. static int setvjslots __P((char **));
  121. static int setdnsaddr __P((char **));
  122. static int setwinsaddr __P((char **));
  123. static int setnetmask __P((char **));
  124. int setipaddr __P((char *, char **, int));
  125. static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *));
  126. static option_t ipcp_option_list[] = {
  127. { "noip", o_bool, &ipcp_protent.enabled_flag,
  128. "Disable IP and IPCP" },
  129. { "-ip", o_bool, &ipcp_protent.enabled_flag,
  130. "Disable IP and IPCP", OPT_ALIAS },
  131. { "novj", o_bool, &ipcp_wantoptions[0].neg_vj,
  132. "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj },
  133. { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj,
  134. "Disable VJ compression", OPT_ALIAS | OPT_A2CLR,
  135. &ipcp_allowoptions[0].neg_vj },
  136. { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag,
  137. "Disable VJ connection-ID compression", OPT_A2CLR,
  138. &ipcp_allowoptions[0].cflag },
  139. { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,
  140. "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR,
  141. &ipcp_allowoptions[0].cflag },
  142. { "vj-max-slots", o_special, (void *)setvjslots,
  143. "Set maximum VJ header slots",
  144. OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value },
  145. { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,
  146. "Accept peer's address for us", 1 },
  147. { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote,
  148. "Accept peer's address for it", 1 },
  149. { "ipparam", o_string, &ipparam,
  150. "Set ip script parameter", OPT_PRIO },
  151. { "noipdefault", o_bool, &disable_defaultip,
  152. "Don't use name for default IP adrs", 1 },
  153. { "ms-dns", 1, (void *)setdnsaddr,
  154. "DNS address for the peer's use" },
  155. { "ms-wins", 1, (void *)setwinsaddr,
  156. "Nameserver for SMB over TCP/IP for peer" },
  157. { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
  158. "Set timeout for IPCP", OPT_PRIO },
  159. { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits,
  160. "Set max #xmits for term-reqs", OPT_PRIO },
  161. { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits,
  162. "Set max #xmits for conf-reqs", OPT_PRIO },
  163. { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops,
  164. "Set max #conf-naks for IPCP", OPT_PRIO },
  165. { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route,
  166. "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route },
  167. { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route,
  168. "disable defaultroute option", OPT_A2CLR,
  169. &ipcp_wantoptions[0].default_route },
  170. { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
  171. "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
  172. &ipcp_wantoptions[0].default_route },
  173. { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
  174. "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
  175. { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
  176. "disable proxyarp option", OPT_A2CLR,
  177. &ipcp_wantoptions[0].proxy_arp },
  178. { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
  179. "disable proxyarp option", OPT_ALIAS | OPT_A2CLR,
  180. &ipcp_wantoptions[0].proxy_arp },
  181. { "usepeerdns", o_bool, &usepeerdns,
  182. "Ask peer for DNS address(es)", 1 },
  183. { "netmask", o_special, (void *)setnetmask,
  184. "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str },
  185. { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs,
  186. "Disable old-style IP-Addresses usage", OPT_A2CLR,
  187. &ipcp_allowoptions[0].old_addrs },
  188. { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr,
  189. "Disable IP-Address usage", OPT_A2CLR,
  190. &ipcp_allowoptions[0].neg_addr },
  191. #ifdef __linux__
  192. { "noremoteip", o_bool, &noremoteip,
  193. "Allow peer to have no IP address", 1 },
  194. #endif
  195. { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr,
  196. "Don't send our IP address to peer", OPT_A2CLR,
  197. &ipcp_wantoptions[0].old_addrs},
  198. { "IP addresses", o_wild, (void *) &setipaddr,
  199. "set local and remote IP addresses",
  200. OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr },
  201. { NULL }
  202. };
  203. /*
  204. * Protocol entry points from main code.
  205. */
  206. static void ipcp_init __P((int));
  207. static void ipcp_open __P((int));
  208. static void ipcp_close __P((int, char *));
  209. static void ipcp_lowerup __P((int));
  210. static void ipcp_lowerdown __P((int));
  211. static void ipcp_input __P((int, u_char *, int));
  212. static void ipcp_protrej __P((int));
  213. static int ipcp_printpkt __P((u_char *, int,
  214. void (*) __P((void *, char *, ...)), void *));
  215. static void ip_check_options __P((void));
  216. static int ip_demand_conf __P((int));
  217. static int ip_active_pkt __P((u_char *, int));
  218. static void create_resolv __P((u_int32_t, u_int32_t));
  219. struct protent ipcp_protent = {
  220. PPP_IPCP,
  221. ipcp_init,
  222. ipcp_input,
  223. ipcp_protrej,
  224. ipcp_lowerup,
  225. ipcp_lowerdown,
  226. ipcp_open,
  227. ipcp_close,
  228. ipcp_printpkt,
  229. NULL,
  230. 1,
  231. "IPCP",
  232. "IP",
  233. ipcp_option_list,
  234. ip_check_options,
  235. ip_demand_conf,
  236. ip_active_pkt
  237. };
  238. static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
  239. static void ipcp_script __P((char *, int)); /* Run an up/down script */
  240. static void ipcp_script_done __P((void *));
  241. /*
  242. * Lengths of configuration options.
  243. */
  244. #define CILEN_VOID 2
  245. #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
  246. #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
  247. #define CILEN_ADDR 6 /* new-style single address option */
  248. #define CILEN_ADDRS 10 /* old-style dual address option */
  249. #define CODENAME(x) ((x) == CONFACK ? "ACK" : \
  250. (x) == CONFNAK ? "NAK" : "REJ")
  251. /*
  252. * This state variable is used to ensure that we don't
  253. * run an ipcp-up/down script while one is already running.
  254. */
  255. static enum script_state {
  256. s_down,
  257. s_up,
  258. } ipcp_script_state;
  259. static pid_t ipcp_script_pid;
  260. /*
  261. * Make a string representation of a network IP address.
  262. */
  263. char *
  264. ip_ntoa(ipaddr)
  265. u_int32_t ipaddr;
  266. {
  267. static char b[64];
  268. slprintf(b, sizeof(b), "%I", ipaddr);
  269. return b;
  270. }
  271. /*
  272. * Option parsing.
  273. */
  274. /*
  275. * setvjslots - set maximum number of connection slots for VJ compression
  276. */
  277. static int
  278. setvjslots(argv)
  279. char **argv;
  280. {
  281. int value;
  282. if (!int_option(*argv, &value))
  283. return 0;
  284. if (value < 2 || value > 16) {
  285. option_error("vj-max-slots value must be between 2 and 16");
  286. return 0;
  287. }
  288. ipcp_wantoptions [0].maxslotindex =
  289. ipcp_allowoptions[0].maxslotindex = value - 1;
  290. slprintf(vj_value, sizeof(vj_value), "%d", value);
  291. return 1;
  292. }
  293. /*
  294. * setdnsaddr - set the dns address(es)
  295. */
  296. static int
  297. setdnsaddr(argv)
  298. char **argv;
  299. {
  300. u_int32_t dns;
  301. struct hostent *hp;
  302. dns = inet_addr(*argv);
  303. if (dns == (u_int32_t) -1) {
  304. if ((hp = gethostbyname(*argv)) == NULL) {
  305. option_error("invalid address parameter '%s' for ms-dns option",
  306. *argv);
  307. return 0;
  308. }
  309. dns = *(u_int32_t *)hp->h_addr;
  310. }
  311. /* We take the last 2 values given, the 2nd-last as the primary
  312. and the last as the secondary. If only one is given it
  313. becomes both primary and secondary. */
  314. if (ipcp_allowoptions[0].dnsaddr[1] == 0)
  315. ipcp_allowoptions[0].dnsaddr[0] = dns;
  316. else
  317. ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1];
  318. /* always set the secondary address value. */
  319. ipcp_allowoptions[0].dnsaddr[1] = dns;
  320. return (1);
  321. }
  322. /*
  323. * setwinsaddr - set the wins address(es)
  324. * This is primrarly used with the Samba package under UNIX or for pointing
  325. * the caller to the existing WINS server on a Windows NT platform.
  326. */
  327. static int
  328. setwinsaddr(argv)
  329. char **argv;
  330. {
  331. u_int32_t wins;
  332. struct hostent *hp;
  333. wins = inet_addr(*argv);
  334. if (wins == (u_int32_t) -1) {
  335. if ((hp = gethostbyname(*argv)) == NULL) {
  336. option_error("invalid address parameter '%s' for ms-wins option",
  337. *argv);
  338. return 0;
  339. }
  340. wins = *(u_int32_t *)hp->h_addr;
  341. }
  342. /* We take the last 2 values given, the 2nd-last as the primary
  343. and the last as the secondary. If only one is given it
  344. becomes both primary and secondary. */
  345. if (ipcp_allowoptions[0].winsaddr[1] == 0)
  346. ipcp_allowoptions[0].winsaddr[0] = wins;
  347. else
  348. ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1];
  349. /* always set the secondary address value. */
  350. ipcp_allowoptions[0].winsaddr[1] = wins;
  351. return (1);
  352. }
  353. /*
  354. * setipaddr - Set the IP address
  355. * If doit is 0, the call is to check whether this option is
  356. * potentially an IP address specification.
  357. * Not static so that plugins can call it to set the addresses
  358. */
  359. int
  360. setipaddr(arg, argv, doit)
  361. char *arg;
  362. char **argv;
  363. int doit;
  364. {
  365. struct hostent *hp;
  366. char *colon;
  367. u_int32_t local, remote;
  368. ipcp_options *wo = &ipcp_wantoptions[0];
  369. static int prio_local = 0, prio_remote = 0;
  370. /*
  371. * IP address pair separated by ":".
  372. */
  373. if ((colon = strchr(arg, ':')) == NULL)
  374. return 0;
  375. if (!doit)
  376. return 1;
  377. /*
  378. * If colon first character, then no local addr.
  379. */
  380. if (colon != arg && option_priority >= prio_local) {
  381. *colon = '\0';
  382. if ((local = inet_addr(arg)) == (u_int32_t) -1) {
  383. if ((hp = gethostbyname(arg)) == NULL) {
  384. option_error("unknown host: %s", arg);
  385. return 0;
  386. }
  387. local = *(u_int32_t *)hp->h_addr;
  388. }
  389. if (bad_ip_adrs(local)) {
  390. option_error("bad local IP address %s", ip_ntoa(local));
  391. return 0;
  392. }
  393. if (local != 0)
  394. wo->ouraddr = local;
  395. *colon = ':';
  396. prio_local = option_priority;
  397. }
  398. /*
  399. * If colon last character, then no remote addr.
  400. */
  401. if (*++colon != '\0' && option_priority >= prio_remote) {
  402. if ((remote = inet_addr(colon)) == (u_int32_t) -1) {
  403. if ((hp = gethostbyname(colon)) == NULL) {
  404. option_error("unknown host: %s", colon);
  405. return 0;
  406. }
  407. remote = *(u_int32_t *)hp->h_addr;
  408. if (remote_name[0] == 0)
  409. strlcpy(remote_name, colon, sizeof(remote_name));
  410. }
  411. if (bad_ip_adrs(remote)) {
  412. option_error("bad remote IP address %s", ip_ntoa(remote));
  413. return 0;
  414. }
  415. if (remote != 0)
  416. wo->hisaddr = remote;
  417. prio_remote = option_priority;
  418. }
  419. return 1;
  420. }
  421. static void
  422. printipaddr(opt, printer, arg)
  423. option_t *opt;
  424. void (*printer) __P((void *, char *, ...));
  425. void *arg;
  426. {
  427. ipcp_options *wo = &ipcp_wantoptions[0];
  428. if (wo->ouraddr != 0)
  429. printer(arg, "%I", wo->ouraddr);
  430. printer(arg, ":");
  431. if (wo->hisaddr != 0)
  432. printer(arg, "%I", wo->hisaddr);
  433. }
  434. /*
  435. * setnetmask - set the netmask to be used on the interface.
  436. */
  437. static int
  438. setnetmask(argv)
  439. char **argv;
  440. {
  441. u_int32_t mask;
  442. int n;
  443. char *p;
  444. /*
  445. * Unfortunately, if we use inet_addr, we can't tell whether
  446. * a result of all 1s is an error or a valid 255.255.255.255.
  447. */
  448. p = *argv;
  449. n = parse_dotted_ip(p, &mask);
  450. mask = htonl(mask);
  451. if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) {
  452. option_error("invalid netmask value '%s'", *argv);
  453. return 0;
  454. }
  455. netmask = mask;
  456. slprintf(netmask_str, sizeof(netmask_str), "%I", mask);
  457. return (1);
  458. }
  459. int
  460. parse_dotted_ip(p, vp)
  461. char *p;
  462. u_int32_t *vp;
  463. {
  464. int n;
  465. u_int32_t v, b;
  466. char *endp, *p0 = p;
  467. v = 0;
  468. for (n = 3;; --n) {
  469. b = strtoul(p, &endp, 0);
  470. if (endp == p)
  471. return 0;
  472. if (b > 255) {
  473. if (n < 3)
  474. return 0;
  475. /* accept e.g. 0xffffff00 */
  476. *vp = b;
  477. return endp - p0;
  478. }
  479. v |= b << (n * 8);
  480. p = endp;
  481. if (n == 0)
  482. break;
  483. if (*p != '.')
  484. return 0;
  485. ++p;
  486. }
  487. *vp = v;
  488. return p - p0;
  489. }
  490. /*
  491. * ipcp_init - Initialize IPCP.
  492. */
  493. static void
  494. ipcp_init(unit)
  495. int unit;
  496. {
  497. fsm *f = &ipcp_fsm[unit];
  498. ipcp_options *wo = &ipcp_wantoptions[unit];
  499. ipcp_options *ao = &ipcp_allowoptions[unit];
  500. f->unit = unit;
  501. f->protocol = PPP_IPCP;
  502. f->callbacks = &ipcp_callbacks;
  503. fsm_init(&ipcp_fsm[unit]);
  504. /*
  505. * Some 3G modems use repeated IPCP NAKs as a way of stalling
  506. * until they can contact a server on the network, so we increase
  507. * the default number of NAKs we accept before we start treating
  508. * them as rejects.
  509. */
  510. f->maxnakloops = 100;
  511. memset(wo, 0, sizeof(*wo));
  512. memset(ao, 0, sizeof(*ao));
  513. wo->neg_addr = wo->old_addrs = 1;
  514. wo->neg_vj = 1;
  515. wo->vj_protocol = IPCP_VJ_COMP;
  516. wo->maxslotindex = MAX_STATES - 1; /* really max index */
  517. wo->cflag = 1;
  518. /* max slots and slot-id compression are currently hardwired in */
  519. /* ppp_if.c to 16 and 1, this needs to be changed (among other */
  520. /* things) gmc */
  521. ao->neg_addr = ao->old_addrs = 1;
  522. ao->neg_vj = 1;
  523. ao->maxslotindex = MAX_STATES - 1;
  524. ao->cflag = 1;
  525. /*
  526. * XXX These control whether the user may use the proxyarp
  527. * and defaultroute options.
  528. */
  529. ao->proxy_arp = 1;
  530. ao->default_route = 1;
  531. }
  532. /*
  533. * ipcp_open - IPCP is allowed to come up.
  534. */
  535. static void
  536. ipcp_open(unit)
  537. int unit;
  538. {
  539. fsm_open(&ipcp_fsm[unit]);
  540. ipcp_is_open = 1;
  541. }
  542. /*
  543. * ipcp_close - Take IPCP down.
  544. */
  545. static void
  546. ipcp_close(unit, reason)
  547. int unit;
  548. char *reason;
  549. {
  550. fsm_close(&ipcp_fsm[unit], reason);
  551. }
  552. /*
  553. * ipcp_lowerup - The lower layer is up.
  554. */
  555. static void
  556. ipcp_lowerup(unit)
  557. int unit;
  558. {
  559. fsm_lowerup(&ipcp_fsm[unit]);
  560. }
  561. /*
  562. * ipcp_lowerdown - The lower layer is down.
  563. */
  564. static void
  565. ipcp_lowerdown(unit)
  566. int unit;
  567. {
  568. fsm_lowerdown(&ipcp_fsm[unit]);
  569. }
  570. /*
  571. * ipcp_input - Input IPCP packet.
  572. */
  573. static void
  574. ipcp_input(unit, p, len)
  575. int unit;
  576. u_char *p;
  577. int len;
  578. {
  579. fsm_input(&ipcp_fsm[unit], p, len);
  580. }
  581. /*
  582. * ipcp_protrej - A Protocol-Reject was received for IPCP.
  583. *
  584. * Pretend the lower layer went down, so we shut up.
  585. */
  586. static void
  587. ipcp_protrej(unit)
  588. int unit;
  589. {
  590. fsm_lowerdown(&ipcp_fsm[unit]);
  591. }
  592. /*
  593. * ipcp_resetci - Reset our CI.
  594. * Called by fsm_sconfreq, Send Configure Request.
  595. */
  596. static void
  597. ipcp_resetci(f)
  598. fsm *f;
  599. {
  600. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  601. ipcp_options *go = &ipcp_gotoptions[f->unit];
  602. ipcp_options *ao = &ipcp_allowoptions[f->unit];
  603. wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
  604. (ao->neg_addr || ao->old_addrs);
  605. if (wo->ouraddr == 0)
  606. wo->accept_local = 1;
  607. if (wo->hisaddr == 0)
  608. wo->accept_remote = 1;
  609. wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */
  610. wo->req_dns2 = usepeerdns;
  611. *go = *wo;
  612. if (!ask_for_local)
  613. go->ouraddr = 0;
  614. if (ip_choose_hook) {
  615. ip_choose_hook(&wo->hisaddr);
  616. if (wo->hisaddr) {
  617. wo->accept_remote = 0;
  618. }
  619. }
  620. BZERO(&ipcp_hisoptions[f->unit], sizeof(ipcp_options));
  621. }
  622. /*
  623. * ipcp_cilen - Return length of our CI.
  624. * Called by fsm_sconfreq, Send Configure Request.
  625. */
  626. static int
  627. ipcp_cilen(f)
  628. fsm *f;
  629. {
  630. ipcp_options *go = &ipcp_gotoptions[f->unit];
  631. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  632. ipcp_options *ho = &ipcp_hisoptions[f->unit];
  633. #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0)
  634. #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
  635. #define LENCIADDR(neg) (neg ? CILEN_ADDR : 0)
  636. #define LENCIDNS(neg) LENCIADDR(neg)
  637. #define LENCIWINS(neg) LENCIADDR(neg)
  638. /*
  639. * First see if we want to change our options to the old
  640. * forms because we have received old forms from the peer.
  641. */
  642. if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs)
  643. go->neg_addr = 0;
  644. if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
  645. /* try an older style of VJ negotiation */
  646. /* use the old style only if the peer did */
  647. if (ho->neg_vj && ho->old_vj) {
  648. go->neg_vj = 1;
  649. go->old_vj = 1;
  650. go->vj_protocol = ho->vj_protocol;
  651. }
  652. }
  653. return (LENCIADDRS(!go->neg_addr && go->old_addrs) +
  654. LENCIVJ(go->neg_vj, go->old_vj) +
  655. LENCIADDR(go->neg_addr) +
  656. LENCIDNS(go->req_dns1) +
  657. LENCIDNS(go->req_dns2) +
  658. LENCIWINS(go->winsaddr[0]) +
  659. LENCIWINS(go->winsaddr[1])) ;
  660. }
  661. /*
  662. * ipcp_addci - Add our desired CIs to a packet.
  663. * Called by fsm_sconfreq, Send Configure Request.
  664. */
  665. static void
  666. ipcp_addci(f, ucp, lenp)
  667. fsm *f;
  668. u_char *ucp;
  669. int *lenp;
  670. {
  671. ipcp_options *go = &ipcp_gotoptions[f->unit];
  672. int len = *lenp;
  673. #define ADDCIADDRS(opt, neg, val1, val2) \
  674. if (neg) { \
  675. if (len >= CILEN_ADDRS) { \
  676. u_int32_t l; \
  677. PUTCHAR(opt, ucp); \
  678. PUTCHAR(CILEN_ADDRS, ucp); \
  679. l = ntohl(val1); \
  680. PUTLONG(l, ucp); \
  681. l = ntohl(val2); \
  682. PUTLONG(l, ucp); \
  683. len -= CILEN_ADDRS; \
  684. } else \
  685. go->old_addrs = 0; \
  686. }
  687. #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
  688. if (neg) { \
  689. int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
  690. if (len >= vjlen) { \
  691. PUTCHAR(opt, ucp); \
  692. PUTCHAR(vjlen, ucp); \
  693. PUTSHORT(val, ucp); \
  694. if (!old) { \
  695. PUTCHAR(maxslotindex, ucp); \
  696. PUTCHAR(cflag, ucp); \
  697. } \
  698. len -= vjlen; \
  699. } else \
  700. neg = 0; \
  701. }
  702. #define ADDCIADDR(opt, neg, val) \
  703. if (neg) { \
  704. if (len >= CILEN_ADDR) { \
  705. u_int32_t l; \
  706. PUTCHAR(opt, ucp); \
  707. PUTCHAR(CILEN_ADDR, ucp); \
  708. l = ntohl(val); \
  709. PUTLONG(l, ucp); \
  710. len -= CILEN_ADDR; \
  711. } else \
  712. neg = 0; \
  713. }
  714. #define ADDCIDNS(opt, neg, addr) \
  715. if (neg) { \
  716. if (len >= CILEN_ADDR) { \
  717. u_int32_t l; \
  718. PUTCHAR(opt, ucp); \
  719. PUTCHAR(CILEN_ADDR, ucp); \
  720. l = ntohl(addr); \
  721. PUTLONG(l, ucp); \
  722. len -= CILEN_ADDR; \
  723. } else \
  724. neg = 0; \
  725. }
  726. #define ADDCIWINS(opt, addr) \
  727. if (addr) { \
  728. if (len >= CILEN_ADDR) { \
  729. u_int32_t l; \
  730. PUTCHAR(opt, ucp); \
  731. PUTCHAR(CILEN_ADDR, ucp); \
  732. l = ntohl(addr); \
  733. PUTLONG(l, ucp); \
  734. len -= CILEN_ADDR; \
  735. } else \
  736. addr = 0; \
  737. }
  738. ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
  739. go->hisaddr);
  740. ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
  741. go->maxslotindex, go->cflag);
  742. ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
  743. ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
  744. ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
  745. ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]);
  746. ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]);
  747. *lenp -= len;
  748. }
  749. /*
  750. * ipcp_ackci - Ack our CIs.
  751. * Called by fsm_rconfack, Receive Configure ACK.
  752. *
  753. * Returns:
  754. * 0 - Ack was bad.
  755. * 1 - Ack was good.
  756. */
  757. static int
  758. ipcp_ackci(f, p, len)
  759. fsm *f;
  760. u_char *p;
  761. int len;
  762. {
  763. ipcp_options *go = &ipcp_gotoptions[f->unit];
  764. u_short cilen, citype, cishort;
  765. u_int32_t cilong;
  766. u_char cimaxslotindex, cicflag;
  767. /*
  768. * CIs must be in exactly the same order that we sent...
  769. * Check packet length and CI length at each step.
  770. * If we find any deviations, then this packet is bad.
  771. */
  772. #define ACKCIADDRS(opt, neg, val1, val2) \
  773. if (neg) { \
  774. u_int32_t l; \
  775. if ((len -= CILEN_ADDRS) < 0) \
  776. goto bad; \
  777. GETCHAR(citype, p); \
  778. GETCHAR(cilen, p); \
  779. if (cilen != CILEN_ADDRS || \
  780. citype != opt) \
  781. goto bad; \
  782. GETLONG(l, p); \
  783. cilong = htonl(l); \
  784. if (val1 != cilong) \
  785. goto bad; \
  786. GETLONG(l, p); \
  787. cilong = htonl(l); \
  788. if (val2 != cilong) \
  789. goto bad; \
  790. }
  791. #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
  792. if (neg) { \
  793. int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
  794. if ((len -= vjlen) < 0) \
  795. goto bad; \
  796. GETCHAR(citype, p); \
  797. GETCHAR(cilen, p); \
  798. if (cilen != vjlen || \
  799. citype != opt) \
  800. goto bad; \
  801. GETSHORT(cishort, p); \
  802. if (cishort != val) \
  803. goto bad; \
  804. if (!old) { \
  805. GETCHAR(cimaxslotindex, p); \
  806. if (cimaxslotindex != maxslotindex) \
  807. goto bad; \
  808. GETCHAR(cicflag, p); \
  809. if (cicflag != cflag) \
  810. goto bad; \
  811. } \
  812. }
  813. #define ACKCIADDR(opt, neg, val) \
  814. if (neg) { \
  815. u_int32_t l; \
  816. if ((len -= CILEN_ADDR) < 0) \
  817. goto bad; \
  818. GETCHAR(citype, p); \
  819. GETCHAR(cilen, p); \
  820. if (cilen != CILEN_ADDR || \
  821. citype != opt) \
  822. goto bad; \
  823. GETLONG(l, p); \
  824. cilong = htonl(l); \
  825. if (val != cilong) \
  826. goto bad; \
  827. }
  828. #define ACKCIDNS(opt, neg, addr) \
  829. if (neg) { \
  830. u_int32_t l; \
  831. if ((len -= CILEN_ADDR) < 0) \
  832. goto bad; \
  833. GETCHAR(citype, p); \
  834. GETCHAR(cilen, p); \
  835. if (cilen != CILEN_ADDR || citype != opt) \
  836. goto bad; \
  837. GETLONG(l, p); \
  838. cilong = htonl(l); \
  839. if (addr != cilong) \
  840. goto bad; \
  841. }
  842. #define ACKCIWINS(opt, addr) \
  843. if (addr) { \
  844. u_int32_t l; \
  845. if ((len -= CILEN_ADDR) < 0) \
  846. goto bad; \
  847. GETCHAR(citype, p); \
  848. GETCHAR(cilen, p); \
  849. if (cilen != CILEN_ADDR || citype != opt) \
  850. goto bad; \
  851. GETLONG(l, p); \
  852. cilong = htonl(l); \
  853. if (addr != cilong) \
  854. goto bad; \
  855. }
  856. ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
  857. go->hisaddr);
  858. ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
  859. go->maxslotindex, go->cflag);
  860. ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
  861. ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
  862. ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
  863. ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]);
  864. ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]);
  865. /*
  866. * If there are any remaining CIs, then this packet is bad.
  867. */
  868. if (len != 0)
  869. goto bad;
  870. return (1);
  871. bad:
  872. IPCPDEBUG(("ipcp_ackci: received bad Ack!"));
  873. return (0);
  874. }
  875. /*
  876. * ipcp_nakci - Peer has sent a NAK for some of our CIs.
  877. * This should not modify any state if the Nak is bad
  878. * or if IPCP is in the OPENED state.
  879. * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
  880. *
  881. * Returns:
  882. * 0 - Nak was bad.
  883. * 1 - Nak was good.
  884. */
  885. static int
  886. ipcp_nakci(f, p, len, treat_as_reject)
  887. fsm *f;
  888. u_char *p;
  889. int len;
  890. int treat_as_reject;
  891. {
  892. ipcp_options *go = &ipcp_gotoptions[f->unit];
  893. u_char cimaxslotindex, cicflag;
  894. u_char citype, cilen, *next;
  895. u_short cishort;
  896. u_int32_t ciaddr1, ciaddr2, l, cidnsaddr;
  897. ipcp_options no; /* options we've seen Naks for */
  898. ipcp_options try; /* options to request next time */
  899. BZERO(&no, sizeof(no));
  900. try = *go;
  901. /*
  902. * Any Nak'd CIs must be in exactly the same order that we sent.
  903. * Check packet length and CI length at each step.
  904. * If we find any deviations, then this packet is bad.
  905. */
  906. #define NAKCIADDRS(opt, neg, code) \
  907. if ((neg) && \
  908. (cilen = p[1]) == CILEN_ADDRS && \
  909. len >= cilen && \
  910. p[0] == opt) { \
  911. len -= cilen; \
  912. INCPTR(2, p); \
  913. GETLONG(l, p); \
  914. ciaddr1 = htonl(l); \
  915. GETLONG(l, p); \
  916. ciaddr2 = htonl(l); \
  917. no.old_addrs = 1; \
  918. code \
  919. }
  920. #define NAKCIVJ(opt, neg, code) \
  921. if (go->neg && \
  922. ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
  923. len >= cilen && \
  924. p[0] == opt) { \
  925. len -= cilen; \
  926. INCPTR(2, p); \
  927. GETSHORT(cishort, p); \
  928. no.neg = 1; \
  929. code \
  930. }
  931. #define NAKCIADDR(opt, neg, code) \
  932. if (go->neg && \
  933. (cilen = p[1]) == CILEN_ADDR && \
  934. len >= cilen && \
  935. p[0] == opt) { \
  936. len -= cilen; \
  937. INCPTR(2, p); \
  938. GETLONG(l, p); \
  939. ciaddr1 = htonl(l); \
  940. no.neg = 1; \
  941. code \
  942. }
  943. #define NAKCIDNS(opt, neg, code) \
  944. if (go->neg && \
  945. ((cilen = p[1]) == CILEN_ADDR) && \
  946. len >= cilen && \
  947. p[0] == opt) { \
  948. len -= cilen; \
  949. INCPTR(2, p); \
  950. GETLONG(l, p); \
  951. cidnsaddr = htonl(l); \
  952. no.neg = 1; \
  953. code \
  954. }
  955. /*
  956. * Accept the peer's idea of {our,his} address, if different
  957. * from our idea, only if the accept_{local,remote} flag is set.
  958. */
  959. NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
  960. if (treat_as_reject) {
  961. try.old_addrs = 0;
  962. } else {
  963. if (go->accept_local && ciaddr1) {
  964. /* take his idea of our address */
  965. try.ouraddr = ciaddr1;
  966. }
  967. if (go->accept_remote && ciaddr2) {
  968. /* take his idea of his address */
  969. try.hisaddr = ciaddr2;
  970. }
  971. }
  972. );
  973. /*
  974. * Accept the peer's value of maxslotindex provided that it
  975. * is less than what we asked for. Turn off slot-ID compression
  976. * if the peer wants. Send old-style compress-type option if
  977. * the peer wants.
  978. */
  979. NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
  980. if (treat_as_reject) {
  981. try.neg_vj = 0;
  982. } else if (cilen == CILEN_VJ) {
  983. GETCHAR(cimaxslotindex, p);
  984. GETCHAR(cicflag, p);
  985. if (cishort == IPCP_VJ_COMP) {
  986. try.old_vj = 0;
  987. if (cimaxslotindex < go->maxslotindex)
  988. try.maxslotindex = cimaxslotindex;
  989. if (!cicflag)
  990. try.cflag = 0;
  991. } else {
  992. try.neg_vj = 0;
  993. }
  994. } else {
  995. if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
  996. try.old_vj = 1;
  997. try.vj_protocol = cishort;
  998. } else {
  999. try.neg_vj = 0;
  1000. }
  1001. }
  1002. );
  1003. NAKCIADDR(CI_ADDR, neg_addr,
  1004. if (treat_as_reject) {
  1005. try.neg_addr = 0;
  1006. try.old_addrs = 0;
  1007. } else if (go->accept_local && ciaddr1) {
  1008. /* take his idea of our address */
  1009. try.ouraddr = ciaddr1;
  1010. }
  1011. );
  1012. NAKCIDNS(CI_MS_DNS1, req_dns1,
  1013. if (treat_as_reject) {
  1014. try.req_dns1 = 0;
  1015. } else {
  1016. try.dnsaddr[0] = cidnsaddr;
  1017. }
  1018. );
  1019. NAKCIDNS(CI_MS_DNS2, req_dns2,
  1020. if (treat_as_reject) {
  1021. try.req_dns2 = 0;
  1022. } else {
  1023. try.dnsaddr[1] = cidnsaddr;
  1024. }
  1025. );
  1026. /*
  1027. * There may be remaining CIs, if the peer is requesting negotiation
  1028. * on an option that we didn't include in our request packet.
  1029. * If they want to negotiate about IP addresses, we comply.
  1030. * If they want us to ask for compression, we refuse.
  1031. * If they want us to ask for ms-dns, we do that, since some
  1032. * peers get huffy if we don't.
  1033. */
  1034. while (len >= CILEN_VOID) {
  1035. GETCHAR(citype, p);
  1036. GETCHAR(cilen, p);
  1037. if ( cilen < CILEN_VOID || (len -= cilen) < 0 )
  1038. goto bad;
  1039. next = p + cilen - 2;
  1040. switch (citype) {
  1041. case CI_COMPRESSTYPE:
  1042. if (go->neg_vj || no.neg_vj ||
  1043. (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
  1044. goto bad;
  1045. no.neg_vj = 1;
  1046. break;
  1047. case CI_ADDRS:
  1048. if ((!go->neg_addr && go->old_addrs) || no.old_addrs
  1049. || cilen != CILEN_ADDRS)
  1050. goto bad;
  1051. try.neg_addr = 0;
  1052. GETLONG(l, p);
  1053. ciaddr1 = htonl(l);
  1054. if (ciaddr1 && go->accept_local)
  1055. try.ouraddr = ciaddr1;
  1056. GETLONG(l, p);
  1057. ciaddr2 = htonl(l);
  1058. if (ciaddr2 && go->accept_remote)
  1059. try.hisaddr = ciaddr2;
  1060. no.old_addrs = 1;
  1061. break;
  1062. case CI_ADDR:
  1063. if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
  1064. goto bad;
  1065. try.old_addrs = 0;
  1066. GETLONG(l, p);
  1067. ciaddr1 = htonl(l);
  1068. if (ciaddr1 && go->accept_local)
  1069. try.ouraddr = ciaddr1;
  1070. if (try.ouraddr != 0)
  1071. try.neg_addr = 1;
  1072. no.neg_addr = 1;
  1073. break;
  1074. case CI_MS_DNS1:
  1075. if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR)
  1076. goto bad;
  1077. GETLONG(l, p);
  1078. try.dnsaddr[0] = htonl(l);
  1079. try.req_dns1 = 1;
  1080. no.req_dns1 = 1;
  1081. break;
  1082. case CI_MS_DNS2:
  1083. if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR)
  1084. goto bad;
  1085. GETLONG(l, p);
  1086. try.dnsaddr[1] = htonl(l);
  1087. try.req_dns2 = 1;
  1088. no.req_dns2 = 1;
  1089. break;
  1090. case CI_MS_WINS1:
  1091. case CI_MS_WINS2:
  1092. if (cilen != CILEN_ADDR)
  1093. goto bad;
  1094. GETLONG(l, p);
  1095. ciaddr1 = htonl(l);
  1096. if (ciaddr1)
  1097. try.winsaddr[citype == CI_MS_WINS2] = ciaddr1;
  1098. break;
  1099. }
  1100. p = next;
  1101. }
  1102. /*
  1103. * OK, the Nak is good. Now we can update state.
  1104. * If there are any remaining options, we ignore them.
  1105. */
  1106. if (f->state != OPENED)
  1107. *go = try;
  1108. return 1;
  1109. bad:
  1110. IPCPDEBUG(("ipcp_nakci: received bad Nak!"));
  1111. return 0;
  1112. }
  1113. /*
  1114. * ipcp_rejci - Reject some of our CIs.
  1115. * Callback from fsm_rconfnakrej.
  1116. */
  1117. static int
  1118. ipcp_rejci(f, p, len)
  1119. fsm *f;
  1120. u_char *p;
  1121. int len;
  1122. {
  1123. ipcp_options *go = &ipcp_gotoptions[f->unit];
  1124. u_char cimaxslotindex, ciflag, cilen;
  1125. u_short cishort;
  1126. u_int32_t cilong;
  1127. ipcp_options try; /* options to request next time */
  1128. try = *go;
  1129. /*
  1130. * Any Rejected CIs must be in exactly the same order that we sent.
  1131. * Check packet length and CI length at each step.
  1132. * If we find any deviations, then this packet is bad.
  1133. */
  1134. #define REJCIADDRS(opt, neg, val1, val2) \
  1135. if ((neg) && \
  1136. (cilen = p[1]) == CILEN_ADDRS && \
  1137. len >= cilen && \
  1138. p[0] == opt) { \
  1139. u_int32_t l; \
  1140. len -= cilen; \
  1141. INCPTR(2, p); \
  1142. GETLONG(l, p); \
  1143. cilong = htonl(l); \
  1144. /* Check rejected value. */ \
  1145. if (cilong != val1) \
  1146. goto bad; \
  1147. GETLONG(l, p); \
  1148. cilong = htonl(l); \
  1149. /* Check rejected value. */ \
  1150. if (cilong != val2) \
  1151. goto bad; \
  1152. try.old_addrs = 0; \
  1153. }
  1154. #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
  1155. if (go->neg && \
  1156. p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
  1157. len >= p[1] && \
  1158. p[0] == opt) { \
  1159. len -= p[1]; \
  1160. INCPTR(2, p); \
  1161. GETSHORT(cishort, p); \
  1162. /* Check rejected value. */ \
  1163. if (cishort != val) \
  1164. goto bad; \
  1165. if (!old) { \
  1166. GETCHAR(cimaxslotindex, p); \
  1167. if (cimaxslotindex != maxslot) \
  1168. goto bad; \
  1169. GETCHAR(ciflag, p); \
  1170. if (ciflag != cflag) \
  1171. goto bad; \
  1172. } \
  1173. try.neg = 0; \
  1174. }
  1175. #define REJCIADDR(opt, neg, val) \
  1176. if (go->neg && \
  1177. (cilen = p[1]) == CILEN_ADDR && \
  1178. len >= cilen && \
  1179. p[0] == opt) { \
  1180. u_int32_t l; \
  1181. len -= cilen; \
  1182. INCPTR(2, p); \
  1183. GETLONG(l, p); \
  1184. cilong = htonl(l); \
  1185. /* Check rejected value. */ \
  1186. if (cilong != val) \
  1187. goto bad; \
  1188. try.neg = 0; \
  1189. }
  1190. #define REJCIDNS(opt, neg, dnsaddr) \
  1191. if (go->neg && \
  1192. ((cilen = p[1]) == CILEN_ADDR) && \
  1193. len >= cilen && \
  1194. p[0] == opt) { \
  1195. u_int32_t l; \
  1196. len -= cilen; \
  1197. INCPTR(2, p); \
  1198. GETLONG(l, p); \
  1199. cilong = htonl(l); \
  1200. /* Check rejected value. */ \
  1201. if (cilong != dnsaddr) \
  1202. goto bad; \
  1203. try.neg = 0; \
  1204. }
  1205. #define REJCIWINS(opt, addr) \
  1206. if (addr && \
  1207. ((cilen = p[1]) == CILEN_ADDR) && \
  1208. len >= cilen && \
  1209. p[0] == opt) { \
  1210. u_int32_t l; \
  1211. len -= cilen; \
  1212. INCPTR(2, p); \
  1213. GETLONG(l, p); \
  1214. cilong = htonl(l); \
  1215. /* Check rejected value. */ \
  1216. if (cilong != addr) \
  1217. goto bad; \
  1218. try.winsaddr[opt == CI_MS_WINS2] = 0; \
  1219. }
  1220. REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
  1221. go->ouraddr, go->hisaddr);
  1222. REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
  1223. go->maxslotindex, go->cflag);
  1224. REJCIADDR(CI_ADDR, neg_addr, go->ouraddr);
  1225. REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
  1226. REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
  1227. REJCIWINS(CI_MS_WINS1, go->winsaddr[0]);
  1228. REJCIWINS(CI_MS_WINS2, go->winsaddr[1]);
  1229. /*
  1230. * If there are any remaining CIs, then this packet is bad.
  1231. */
  1232. if (len != 0)
  1233. goto bad;
  1234. /*
  1235. * Now we can update state.
  1236. */
  1237. if (f->state != OPENED)
  1238. *go = try;
  1239. return 1;
  1240. bad:
  1241. IPCPDEBUG(("ipcp_rejci: received bad Reject!"));
  1242. return 0;
  1243. }
  1244. /*
  1245. * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
  1246. * Callback from fsm_rconfreq, Receive Configure Request
  1247. *
  1248. * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
  1249. * appropriately. If reject_if_disagree is non-zero, doesn't return
  1250. * CONFNAK; returns CONFREJ if it can't return CONFACK.
  1251. */
  1252. static int
  1253. ipcp_reqci(f, inp, len, reject_if_disagree)
  1254. fsm *f;
  1255. u_char *inp; /* Requested CIs */
  1256. int *len; /* Length of requested CIs */
  1257. int reject_if_disagree;
  1258. {
  1259. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  1260. ipcp_options *ho = &ipcp_hisoptions[f->unit];
  1261. ipcp_options *ao = &ipcp_allowoptions[f->unit];
  1262. u_char *cip, *next; /* Pointer to current and next CIs */
  1263. u_short cilen, citype; /* Parsed len, type */
  1264. u_short cishort; /* Parsed short value */
  1265. u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */
  1266. int rc = CONFACK; /* Final packet return code */
  1267. int orc; /* Individual option return code */
  1268. u_char *p; /* Pointer to next char to parse */
  1269. u_char *ucp = inp; /* Pointer to current output char */
  1270. int l = *len; /* Length left */
  1271. u_char maxslotindex, cflag;
  1272. int d;
  1273. /*
  1274. * Reset all his options.
  1275. */
  1276. BZERO(ho, sizeof(*ho));
  1277. /*
  1278. * Process all his options.
  1279. */
  1280. next = inp;
  1281. while (l) {
  1282. orc = CONFACK; /* Assume success */
  1283. cip = p = next; /* Remember begining of CI */
  1284. if (l < 2 || /* Not enough data for CI header or */
  1285. p[1] < 2 || /* CI length too small or */
  1286. p[1] > l) { /* CI length too big? */
  1287. IPCPDEBUG(("ipcp_reqci: bad CI length!"));
  1288. orc = CONFREJ; /* Reject bad CI */
  1289. cilen = l; /* Reject till end of packet */
  1290. l = 0; /* Don't loop again */
  1291. goto endswitch;
  1292. }
  1293. GETCHAR(citype, p); /* Parse CI type */
  1294. GETCHAR(cilen, p); /* Parse CI length */
  1295. l -= cilen; /* Adjust remaining length */
  1296. next += cilen; /* Step to next CI */
  1297. switch (citype) { /* Check CI type */
  1298. case CI_ADDRS:
  1299. if (!ao->old_addrs || ho->neg_addr ||
  1300. cilen != CILEN_ADDRS) { /* Check CI length */
  1301. orc = CONFREJ; /* Reject CI */
  1302. break;
  1303. }
  1304. /*
  1305. * If he has no address, or if we both have his address but
  1306. * disagree about it, then NAK it with our idea.
  1307. * In particular, if we don't know his address, but he does,
  1308. * then accept it.
  1309. */
  1310. GETLONG(tl, p); /* Parse source address (his) */
  1311. ciaddr1 = htonl(tl);
  1312. if (ciaddr1 != wo->hisaddr
  1313. && (ciaddr1 == 0 || !wo->accept_remote)) {
  1314. orc = CONFNAK;
  1315. if (!reject_if_disagree) {
  1316. DECPTR(sizeof(u_int32_t), p);
  1317. tl = ntohl(wo->hisaddr);
  1318. PUTLONG(tl, p);
  1319. }
  1320. } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
  1321. /*
  1322. * If neither we nor he knows his address, reject the option.
  1323. */
  1324. orc = CONFREJ;
  1325. wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
  1326. break;
  1327. }
  1328. /*
  1329. * If he doesn't know our address, or if we both have our address
  1330. * but disagree about it, then NAK it with our idea.
  1331. */
  1332. GETLONG(tl, p); /* Parse desination address (ours) */
  1333. ciaddr2 = htonl(tl);
  1334. if (ciaddr2 != wo->ouraddr) {
  1335. if (ciaddr2 == 0 || !wo->accept_local) {
  1336. orc = CONFNAK;
  1337. if (!reject_if_disagree) {
  1338. DECPTR(sizeof(u_int32_t), p);
  1339. tl = ntohl(wo->ouraddr);
  1340. PUTLONG(tl, p);
  1341. }
  1342. } else {
  1343. wo->ouraddr = ciaddr2; /* accept peer's idea */
  1344. }
  1345. }
  1346. ho->old_addrs = 1;
  1347. ho->hisaddr = ciaddr1;
  1348. ho->ouraddr = ciaddr2;
  1349. break;
  1350. case CI_ADDR:
  1351. if (!ao->neg_addr || ho->old_addrs ||
  1352. cilen != CILEN_ADDR) { /* Check CI length */
  1353. orc = CONFREJ; /* Reject CI */
  1354. break;
  1355. }
  1356. /*
  1357. * If he has no address, or if we both have his address but
  1358. * disagree about it, then NAK it with our idea.
  1359. * In particular, if we don't know his address, but he does,
  1360. * then accept it.
  1361. */
  1362. GETLONG(tl, p); /* Parse source address (his) */
  1363. ciaddr1 = htonl(tl);
  1364. if (ciaddr1 != wo->hisaddr
  1365. && (ciaddr1 == 0 || !wo->accept_remote)) {
  1366. orc = CONFNAK;
  1367. if (!reject_if_disagree) {
  1368. DECPTR(sizeof(u_int32_t), p);
  1369. tl = ntohl(wo->hisaddr);
  1370. PUTLONG(tl, p);
  1371. }
  1372. } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
  1373. /*
  1374. * Don't ACK an address of 0.0.0.0 - reject it instead.
  1375. */
  1376. orc = CONFREJ;
  1377. wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
  1378. break;
  1379. }
  1380. ho->neg_addr = 1;
  1381. ho->hisaddr = ciaddr1;
  1382. break;
  1383. case CI_MS_DNS1:
  1384. case CI_MS_DNS2:
  1385. /* Microsoft primary or secondary DNS request */
  1386. d = citype == CI_MS_DNS2;
  1387. /* If we do not have a DNS address then we cannot send it */
  1388. if (ao->dnsaddr[d] == 0 ||
  1389. cilen != CILEN_ADDR) { /* Check CI length */
  1390. orc = CONFREJ; /* Reject CI */
  1391. break;
  1392. }
  1393. GETLONG(tl, p);
  1394. if (htonl(tl) != ao->dnsaddr[d]) {
  1395. DECPTR(sizeof(u_int32_t), p);
  1396. tl = ntohl(ao->dnsaddr[d]);
  1397. PUTLONG(tl, p);
  1398. orc = CONFNAK;
  1399. }
  1400. break;
  1401. case CI_MS_WINS1:
  1402. case CI_MS_WINS2:
  1403. /* Microsoft primary or secondary WINS request */
  1404. d = citype == CI_MS_WINS2;
  1405. /* If we do not have a DNS address then we cannot send it */
  1406. if (ao->winsaddr[d] == 0 ||
  1407. cilen != CILEN_ADDR) { /* Check CI length */
  1408. orc = CONFREJ; /* Reject CI */
  1409. break;
  1410. }
  1411. GETLONG(tl, p);
  1412. if (htonl(tl) != ao->winsaddr[d]) {
  1413. DECPTR(sizeof(u_int32_t), p);
  1414. tl = ntohl(ao->winsaddr[d]);
  1415. PUTLONG(tl, p);
  1416. orc = CONFNAK;
  1417. }
  1418. break;
  1419. case CI_COMPRESSTYPE:
  1420. if (!ao->neg_vj ||
  1421. (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
  1422. orc = CONFREJ;
  1423. break;
  1424. }
  1425. GETSHORT(cishort, p);
  1426. if (!(cishort == IPCP_VJ_COMP ||
  1427. (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
  1428. orc = CONFREJ;
  1429. break;
  1430. }
  1431. ho->neg_vj = 1;
  1432. ho->vj_protocol = cishort;
  1433. if (cilen == CILEN_VJ) {
  1434. GETCHAR(maxslotindex, p);
  1435. if (maxslotindex > ao->maxslotindex) {
  1436. orc = CONFNAK;
  1437. if (!reject_if_disagree){
  1438. DECPTR(1, p);
  1439. PUTCHAR(ao->maxslotindex, p);
  1440. }
  1441. }
  1442. GETCHAR(cflag, p);
  1443. if (cflag && !ao->cflag) {
  1444. orc = CONFNAK;
  1445. if (!reject_if_disagree){
  1446. DECPTR(1, p);
  1447. PUTCHAR(wo->cflag, p);
  1448. }
  1449. }
  1450. ho->maxslotindex = maxslotindex;
  1451. ho->cflag = cflag;
  1452. } else {
  1453. ho->old_vj = 1;
  1454. ho->maxslotindex = MAX_STATES - 1;
  1455. ho->cflag = 1;
  1456. }
  1457. break;
  1458. default:
  1459. orc = CONFREJ;
  1460. break;
  1461. }
  1462. endswitch:
  1463. if (orc == CONFACK && /* Good CI */
  1464. rc != CONFACK) /* but prior CI wasnt? */
  1465. continue; /* Don't send this one */
  1466. if (orc == CONFNAK) { /* Nak this CI? */
  1467. if (reject_if_disagree) /* Getting fed up with sending NAKs? */
  1468. orc = CONFREJ; /* Get tough if so */
  1469. else {
  1470. if (rc == CONFREJ) /* Rejecting prior CI? */
  1471. continue; /* Don't send this one */
  1472. if (rc == CONFACK) { /* Ack'd all prior CIs? */
  1473. rc = CONFNAK; /* Not anymore... */
  1474. ucp = inp; /* Backup */
  1475. }
  1476. }
  1477. }
  1478. if (orc == CONFREJ && /* Reject this CI */
  1479. rc != CONFREJ) { /* but no prior ones? */
  1480. rc = CONFREJ;
  1481. ucp = inp; /* Backup */
  1482. }
  1483. /* Need to move CI? */
  1484. if (ucp != cip)
  1485. BCOPY(cip, ucp, cilen); /* Move it */
  1486. /* Update output pointer */
  1487. INCPTR(cilen, ucp);
  1488. }
  1489. /*
  1490. * If we aren't rejecting this packet, and we want to negotiate
  1491. * their address, and they didn't send their address, then we
  1492. * send a NAK with a CI_ADDR option appended. We assume the
  1493. * input buffer is long enough that we can append the extra
  1494. * option safely.
  1495. */
  1496. if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs &&
  1497. wo->req_addr && !reject_if_disagree && !noremoteip) {
  1498. if (rc == CONFACK) {
  1499. rc = CONFNAK;
  1500. ucp = inp; /* reset pointer */
  1501. wo->req_addr = 0; /* don't ask again */
  1502. }
  1503. PUTCHAR(CI_ADDR, ucp);
  1504. PUTCHAR(CILEN_ADDR, ucp);
  1505. tl = ntohl(wo->hisaddr);
  1506. PUTLONG(tl, ucp);
  1507. }
  1508. *len = ucp - inp; /* Compute output length */
  1509. IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc)));
  1510. return (rc); /* Return final code */
  1511. }
  1512. /*
  1513. * ip_check_options - check that any IP-related options are OK,
  1514. * and assign appropriate defaults.
  1515. */
  1516. static void
  1517. ip_check_options()
  1518. {
  1519. struct hostent *hp;
  1520. u_int32_t local;
  1521. ipcp_options *wo = &ipcp_wantoptions[0];
  1522. /*
  1523. * Default our local IP address based on our hostname.
  1524. * If local IP address already given, don't bother.
  1525. */
  1526. if (wo->ouraddr == 0 && !disable_defaultip) {
  1527. /*
  1528. * Look up our hostname (possibly with domain name appended)
  1529. * and take the first IP address as our local IP address.
  1530. * If there isn't an IP address for our hostname, too bad.
  1531. */
  1532. wo->accept_local = 1; /* don't insist on this default value */
  1533. if ((hp = gethostbyname(hostname)) != NULL) {
  1534. local = *(u_int32_t *)hp->h_addr;
  1535. if (local != 0 && !bad_ip_adrs(local))
  1536. wo->ouraddr = local;
  1537. }
  1538. }
  1539. ask_for_local = wo->ouraddr != 0 || !disable_defaultip;
  1540. }
  1541. /*
  1542. * ip_demand_conf - configure the interface as though
  1543. * IPCP were up, for use with dial-on-demand.
  1544. */
  1545. static int
  1546. ip_demand_conf(u)
  1547. int u;
  1548. {
  1549. ipcp_options *wo = &ipcp_wantoptions[u];
  1550. if (wo->hisaddr == 0 && !noremoteip) {
  1551. /* make up an arbitrary address for the peer */
  1552. wo->hisaddr = htonl(0x0a707070 + ifunit);
  1553. wo->accept_remote = 1;
  1554. }
  1555. if (wo->ouraddr == 0) {
  1556. /* make up an arbitrary address for us */
  1557. wo->ouraddr = htonl(0x0a404040 + ifunit);
  1558. wo->accept_local = 1;
  1559. ask_for_local = 0; /* don't tell the peer this address */
  1560. }
  1561. if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
  1562. return 0;
  1563. ipcp_script(_PATH_IPPREUP, 1);
  1564. if (!sifup(u))
  1565. return 0;
  1566. if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
  1567. return 0;
  1568. if (wo->default_route)
  1569. if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
  1570. default_route_set[u] = 1;
  1571. if (wo->proxy_arp)
  1572. if (sifproxyarp(u, wo->hisaddr))
  1573. proxy_arp_set[u] = 1;
  1574. notice("local IP address %I", wo->ouraddr);
  1575. if (wo->hisaddr)
  1576. notice("remote IP address %I", wo->hisaddr);
  1577. return 1;
  1578. }
  1579. /*
  1580. * ipcp_up - IPCP has come UP.
  1581. *
  1582. * Configure the IP network interface appropriately and bring it up.
  1583. */
  1584. static void
  1585. ipcp_up(f)
  1586. fsm *f;
  1587. {
  1588. u_int32_t mask;
  1589. ipcp_options *ho = &ipcp_hisoptions[f->unit];
  1590. ipcp_options *go = &ipcp_gotoptions[f->unit];
  1591. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  1592. IPCPDEBUG(("ipcp: up"));
  1593. /*
  1594. * We must have a non-zero IP address for both ends of the link.
  1595. */
  1596. if (!ho->neg_addr && !ho->old_addrs)
  1597. ho->hisaddr = wo->hisaddr;
  1598. if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs)
  1599. && wo->ouraddr != 0) {
  1600. error("Peer refused to agree to our IP address");
  1601. ipcp_close(f->unit, "Refused our IP address");
  1602. return;
  1603. }
  1604. if (go->ouraddr == 0) {
  1605. error("Could not determine local IP address");
  1606. ipcp_close(f->unit, "Could not determine local IP address");
  1607. return;
  1608. }
  1609. if (ho->hisaddr == 0 && !noremoteip) {
  1610. ho->hisaddr = htonl(0x0a404040 + ifunit);
  1611. warn("Could not determine remote IP address: defaulting to %I",
  1612. ho->hisaddr);
  1613. }
  1614. script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
  1615. if (ho->hisaddr != 0)
  1616. script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
  1617. if (!go->req_dns1)
  1618. go->dnsaddr[0] = 0;
  1619. if (!go->req_dns2)
  1620. go->dnsaddr[1] = 0;
  1621. if (go->dnsaddr[0])
  1622. script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);
  1623. if (go->dnsaddr[1])
  1624. script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);
  1625. if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
  1626. script_setenv("USEPEERDNS", "1", 0);
  1627. create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
  1628. }
  1629. /*
  1630. * Check that the peer is allowed to use the IP address it wants.
  1631. */
  1632. if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) {
  1633. error("Peer is not authorized to use remote address %I", ho->hisaddr);
  1634. ipcp_close(f->unit, "Unauthorized remote IP address");
  1635. return;
  1636. }
  1637. /* set tcp compression */
  1638. sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
  1639. /*
  1640. * If we are doing dial-on-demand, the interface is already
  1641. * configured, so we put out any saved-up packets, then set the
  1642. * interface to pass IP packets.
  1643. */
  1644. if (demand) {
  1645. if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
  1646. ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
  1647. if (go->ouraddr != wo->ouraddr) {
  1648. warn("Local IP address changed to %I", go->ouraddr);
  1649. script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
  1650. wo->ouraddr = go->ouraddr;
  1651. } else
  1652. script_unsetenv("OLDIPLOCAL");
  1653. if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) {
  1654. warn("Remote IP address changed to %I", ho->hisaddr);
  1655. script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
  1656. wo->hisaddr = ho->hisaddr;
  1657. } else
  1658. script_unsetenv("OLDIPREMOTE");
  1659. /* Set the interface to the new addresses */
  1660. mask = GetMask(go->ouraddr);
  1661. if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
  1662. if (debug)
  1663. warn("Interface configuration failed");
  1664. ipcp_close(f->unit, "Interface configuration failed");
  1665. return;
  1666. }
  1667. /* assign a default route through the interface if required */
  1668. if (ipcp_wantoptions[f->unit].default_route)
  1669. if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
  1670. default_route_set[f->unit] = 1;
  1671. /* Make a proxy ARP entry if requested. */
  1672. if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
  1673. if (sifproxyarp(f->unit, ho->hisaddr))
  1674. proxy_arp_set[f->unit] = 1;
  1675. }
  1676. demand_rexmit(PPP_IP);
  1677. sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
  1678. } else {
  1679. /*
  1680. * Set IP addresses and (if specified) netmask.
  1681. */
  1682. mask = GetMask(go->ouraddr);
  1683. #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
  1684. if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
  1685. if (debug)
  1686. warn("Interface configuration failed");
  1687. ipcp_close(f->unit, "Interface configuration failed");
  1688. return;
  1689. }
  1690. #endif
  1691. /* run the pre-up script, if any, and wait for it to finish */
  1692. ipcp_script(_PATH_IPPREUP, 1);
  1693. /* bring the interface up for IP */
  1694. if (!sifup(f->unit)) {
  1695. if (debug)
  1696. warn("Interface failed to come up");
  1697. ipcp_close(f->unit, "Interface configuration failed");
  1698. return;
  1699. }
  1700. #if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
  1701. if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
  1702. if (debug)
  1703. warn("Interface configuration failed");
  1704. ipcp_close(f->unit, "Interface configuration failed");
  1705. return;
  1706. }
  1707. #endif
  1708. sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
  1709. /* assign a default route through the interface if required */
  1710. if (ipcp_wantoptions[f->unit].default_route)
  1711. if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
  1712. default_route_set[f->unit] = 1;
  1713. /* Make a proxy ARP entry if requested. */
  1714. if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
  1715. if (sifproxyarp(f->unit, ho->hisaddr))
  1716. proxy_arp_set[f->unit] = 1;
  1717. ipcp_wantoptions[0].ouraddr = go->ouraddr;
  1718. notice("local IP address %I", go->ouraddr);
  1719. if (ho->hisaddr != 0)
  1720. notice("remote IP address %I", ho->hisaddr);
  1721. if (go->dnsaddr[0])
  1722. notice("primary DNS address %I", go->dnsaddr[0]);
  1723. if (go->dnsaddr[1])
  1724. notice("secondary DNS address %I", go->dnsaddr[1]);
  1725. }
  1726. reset_link_stats(f->unit);
  1727. np_up(f->unit, PPP_IP);
  1728. ipcp_is_up = 1;
  1729. notify(ip_up_notifier, 0);
  1730. if (ip_up_hook)
  1731. ip_up_hook();
  1732. /*
  1733. * Execute the ip-up script, like this:
  1734. * /etc/ppp/ip-up interface tty speed local-IP remote-IP
  1735. */
  1736. if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
  1737. ipcp_script_state = s_up;
  1738. ipcp_script(_PATH_IPUP, 0);
  1739. }
  1740. }
  1741. /*
  1742. * ipcp_down - IPCP has gone DOWN.
  1743. *
  1744. * Take the IP network interface down, clear its addresses
  1745. * and delete routes through it.
  1746. */
  1747. static void
  1748. ipcp_down(f)
  1749. fsm *f;
  1750. {
  1751. IPCPDEBUG(("ipcp: down"));
  1752. /* XXX a bit IPv4-centric here, we only need to get the stats
  1753. * before the interface is marked down. */
  1754. /* XXX more correct: we must get the stats before running the notifiers,
  1755. * at least for the radius plugin */
  1756. update_link_stats(f->unit);
  1757. notify(ip_down_notifier, 0);
  1758. if (ip_down_hook)
  1759. ip_down_hook();
  1760. if (ipcp_is_up) {
  1761. ipcp_is_up = 0;
  1762. np_down(f->unit, PPP_IP);
  1763. }
  1764. sifvjcomp(f->unit, 0, 0, 0);
  1765. print_link_stats(); /* _after_ running the notifiers and ip_down_hook(),
  1766. * because print_link_stats() sets link_stats_valid
  1767. * to 0 (zero) */
  1768. /*
  1769. * If we are doing dial-on-demand, set the interface
  1770. * to queue up outgoing packets (for now).
  1771. */
  1772. if (demand) {
  1773. sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
  1774. } else {
  1775. sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
  1776. sifdown(f->unit);
  1777. ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
  1778. ipcp_hisoptions[f->unit].hisaddr);
  1779. }
  1780. /* Execute the ip-down script */
  1781. if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
  1782. ipcp_script_state = s_down;
  1783. ipcp_script(_PATH_IPDOWN, 0);
  1784. }
  1785. }
  1786. /*
  1787. * ipcp_clear_addrs() - clear the interface addresses, routes,
  1788. * proxy arp entries, etc.
  1789. */
  1790. static void
  1791. ipcp_clear_addrs(unit, ouraddr, hisaddr)
  1792. int unit;
  1793. u_int32_t ouraddr; /* local address */
  1794. u_int32_t hisaddr; /* remote address */
  1795. {
  1796. if (proxy_arp_set[unit]) {
  1797. cifproxyarp(unit, hisaddr);
  1798. proxy_arp_set[unit] = 0;
  1799. }
  1800. if (default_route_set[unit]) {
  1801. cifdefaultroute(unit, ouraddr, hisaddr);
  1802. default_route_set[unit] = 0;
  1803. }
  1804. cifaddr(unit, ouraddr, hisaddr);
  1805. }
  1806. /*
  1807. * ipcp_finished - possibly shut down the lower layers.
  1808. */
  1809. static void
  1810. ipcp_finished(f)
  1811. fsm *f;
  1812. {
  1813. if (ipcp_is_open) {
  1814. ipcp_is_open = 0;
  1815. np_finished(f->unit, PPP_IP);
  1816. }
  1817. }
  1818. /*
  1819. * ipcp_script_done - called when the ip-up or ip-down script
  1820. * has finished.
  1821. */
  1822. static void
  1823. ipcp_script_done(arg)
  1824. void *arg;
  1825. {
  1826. ipcp_script_pid = 0;
  1827. switch (ipcp_script_state) {
  1828. case s_up:
  1829. if (ipcp_fsm[0].state != OPENED) {
  1830. ipcp_script_state = s_down;
  1831. ipcp_script(_PATH_IPDOWN, 0);
  1832. }
  1833. break;
  1834. case s_down:
  1835. if (ipcp_fsm[0].state == OPENED) {
  1836. ipcp_script_state = s_up;
  1837. ipcp_script(_PATH_IPUP, 0);
  1838. }
  1839. break;
  1840. }
  1841. }
  1842. /*
  1843. * ipcp_script - Execute a script with arguments
  1844. * interface-name tty-name speed local-IP remote-IP.
  1845. */
  1846. static void
  1847. ipcp_script(script, wait)
  1848. char *script;
  1849. int wait;
  1850. {
  1851. char strspeed[32], strlocal[32], strremote[32];
  1852. char *argv[8];
  1853. slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);
  1854. slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr);
  1855. slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr);
  1856. argv[0] = script;
  1857. argv[1] = ifname;
  1858. argv[2] = devnam;
  1859. argv[3] = strspeed;
  1860. argv[4] = strlocal;
  1861. argv[5] = strremote;
  1862. argv[6] = ipparam;
  1863. argv[7] = NULL;
  1864. if (wait)
  1865. run_program(script, argv, 0, NULL, NULL, 1);
  1866. else
  1867. ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done,
  1868. NULL, 0);
  1869. }
  1870. /*
  1871. * create_resolv - create the replacement resolv.conf file
  1872. */
  1873. static void
  1874. create_resolv(peerdns1, peerdns2)
  1875. u_int32_t peerdns1, peerdns2;
  1876. {
  1877. FILE *f;
  1878. f = fopen(_PATH_RESOLV, "w");
  1879. if (f == NULL) {
  1880. error("Failed to create %s: %m", _PATH_RESOLV);
  1881. return;
  1882. }
  1883. if (peerdns1)
  1884. fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1));
  1885. if (peerdns2)
  1886. fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2));
  1887. if (ferror(f))
  1888. error("Write failed to %s: %m", _PATH_RESOLV);
  1889. fclose(f);
  1890. }
  1891. /*
  1892. * ipcp_printpkt - print the contents of an IPCP packet.
  1893. */
  1894. static char *ipcp_codenames[] = {
  1895. "ConfReq", "ConfAck", "ConfNak", "ConfRej",
  1896. "TermReq", "TermAck", "CodeRej"
  1897. };
  1898. static int
  1899. ipcp_printpkt(p, plen, printer, arg)
  1900. u_char *p;
  1901. int plen;
  1902. void (*printer) __P((void *, char *, ...));
  1903. void *arg;
  1904. {
  1905. int code, id, len, olen;
  1906. u_char *pstart, *optend;
  1907. u_short cishort;
  1908. u_int32_t cilong;
  1909. if (plen < HEADERLEN)
  1910. return 0;
  1911. pstart = p;
  1912. GETCHAR(code, p);
  1913. GETCHAR(id, p);
  1914. GETSHORT(len, p);
  1915. if (len < HEADERLEN || len > plen)
  1916. return 0;
  1917. if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *))
  1918. printer(arg, " %s", ipcp_codenames[code-1]);
  1919. else
  1920. printer(arg, " code=0x%x", code);
  1921. printer(arg, " id=0x%x", id);
  1922. len -= HEADERLEN;
  1923. switch (code) {
  1924. case CONFREQ:
  1925. case CONFACK:
  1926. case CONFNAK:
  1927. case CONFREJ:
  1928. /* print option list */
  1929. while (len >= 2) {
  1930. GETCHAR(code, p);
  1931. GETCHAR(olen, p);
  1932. p -= 2;
  1933. if (olen < 2 || olen > len) {
  1934. break;
  1935. }
  1936. printer(arg, " <");
  1937. len -= olen;
  1938. optend = p + olen;
  1939. switch (code) {
  1940. case CI_ADDRS:
  1941. if (olen == CILEN_ADDRS) {
  1942. p += 2;
  1943. GETLONG(cilong, p);
  1944. printer(arg, "addrs %I", htonl(cilong));
  1945. GETLONG(cilong, p);
  1946. printer(arg, " %I", htonl(cilong));
  1947. }
  1948. break;
  1949. case CI_COMPRESSTYPE:
  1950. if (olen >= CILEN_COMPRESS) {
  1951. p += 2;
  1952. GETSHORT(cishort, p);
  1953. printer(arg, "compress ");
  1954. switch (cishort) {
  1955. case IPCP_VJ_COMP:
  1956. printer(arg, "VJ");
  1957. break;
  1958. case IPCP_VJ_COMP_OLD:
  1959. printer(arg, "old-VJ");
  1960. break;
  1961. default:
  1962. printer(arg, "0x%x", cishort);
  1963. }
  1964. }
  1965. break;
  1966. case CI_ADDR:
  1967. if (olen == CILEN_ADDR) {
  1968. p += 2;
  1969. GETLONG(cilong, p);
  1970. printer(arg, "addr %I", htonl(cilong));
  1971. }
  1972. break;
  1973. case CI_MS_DNS1:
  1974. case CI_MS_DNS2:
  1975. p += 2;
  1976. GETLONG(cilong, p);
  1977. printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2),
  1978. htonl(cilong));
  1979. break;
  1980. case CI_MS_WINS1:
  1981. case CI_MS_WINS2:
  1982. p += 2;
  1983. GETLONG(cilong, p);
  1984. printer(arg, "ms-wins %I", htonl(cilong));
  1985. break;
  1986. }
  1987. while (p < optend) {
  1988. GETCHAR(code, p);
  1989. printer(arg, " %.2x", code);
  1990. }
  1991. printer(arg, ">");
  1992. }
  1993. break;
  1994. case TERMACK:
  1995. case TERMREQ:
  1996. if (len > 0 && *p >= ' ' && *p < 0x7f) {
  1997. printer(arg, " ");
  1998. print_string((char *)p, len, printer, arg);
  1999. p += len;
  2000. len = 0;
  2001. }
  2002. break;
  2003. }
  2004. /* print the rest of the bytes in the packet */
  2005. for (; len > 0; --len) {
  2006. GETCHAR(code, p);
  2007. printer(arg, " %.2x", code);
  2008. }
  2009. return p - pstart;
  2010. }
  2011. /*
  2012. * ip_active_pkt - see if this IP packet is worth bringing the link up for.
  2013. * We don't bring the link up for IP fragments or for TCP FIN packets
  2014. * with no data.
  2015. */
  2016. #define IP_HDRLEN 20 /* bytes */
  2017. #define IP_OFFMASK 0x1fff
  2018. #ifndef IPPROTO_TCP
  2019. #define IPPROTO_TCP 6
  2020. #endif
  2021. #define TCP_HDRLEN 20
  2022. #define TH_FIN 0x01
  2023. /*
  2024. * We use these macros because the IP header may be at an odd address,
  2025. * and some compilers might use word loads to get th_off or ip_hl.
  2026. */
  2027. #define net_short(x) (((x)[0] << 8) + (x)[1])
  2028. #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
  2029. #define get_ipoff(x) net_short((unsigned char *)(x) + 6)
  2030. #define get_ipproto(x) (((unsigned char *)(x))[9])
  2031. #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
  2032. #define get_tcpflags(x) (((unsigned char *)(x))[13])
  2033. static int
  2034. ip_active_pkt(pkt, len)
  2035. u_char *pkt;
  2036. int len;
  2037. {
  2038. u_char *tcp;
  2039. int hlen;
  2040. len -= PPP_HDRLEN;
  2041. pkt += PPP_HDRLEN;
  2042. if (len < IP_HDRLEN)
  2043. return 0;
  2044. if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
  2045. return 0;
  2046. if (get_ipproto(pkt) != IPPROTO_TCP)
  2047. return 1;
  2048. hlen = get_iphl(pkt) * 4;
  2049. if (len < hlen + TCP_HDRLEN)
  2050. return 0;
  2051. tcp = pkt + hlen;
  2052. if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
  2053. return 0;
  2054. return 1;
  2055. }