/* process a type 0 (LOCAL) or type 1 (REMOTE) IP string */ static void processIPStr(int type, char *ipstr) { int pos; char *tmpstr; /* char tmpstr2[20]; xxx.xxx.xxx.xxx-xxx (largest we can get) */ char tmpstr2[128]; /* allow hostnames */ char *tmpstr3; char tmpstr5[16]; char *tmpstr6; char *tmpstr7; int num; char ipa[8]; /* xxx-xxx (largest we can get) */ char ipb[8]; char ipc[8]; char ipd[8]; char ip_pre[13]; /* xxx.xxx.xxx. (largest we can get) */ char ip_post[13]; char ipl[4]; char ipu[4]; int bail = FALSE; /* so we know when to stop formatting the ip line */ int lower, upper, n; num = 0; while (!bail) { if ((tmpstr = strchr(ipstr, ',')) == NULL) { /* last (or only) entry reached */ strlcpy(tmpstr2, ipstr, sizeof(tmpstr2)); bail = TRUE; } else { pos = tmpstr - ipstr; ipstr[pos] = '\0'; strlcpy(tmpstr2, ipstr, sizeof(tmpstr2)); ipstr = tmpstr + 1; } #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Parsing segment: %s", tmpstr2); #endif if (!isIpRange(tmpstr2)) { /* We got a normal IP * Check if the IP address is valid, use it if so */ if ((tmpstr7 = lookup(tmpstr2)) == NULL) { syslog(LOG_ERR, "MGR: Bad IP address (%s) in config file!", tmpstr2); exit(1); } if (num == pptp_connections) { syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections); return; } #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Setting IP %d = %s", num, tmpstr7); #endif if (type == LOCAL) slot_set_local(num, tmpstr7); else slot_set_remote(num, tmpstr7); num++; } else { /* Got a range; * eg. 192.168.0.234-238 * or (thanx Kev! :-).. i thought i was finished :-) * 192.168-178.1.231 */ /* lose the "."'s */ while ((tmpstr3 = strchr(tmpstr2, '.')) != NULL) { pos = tmpstr3 - tmpstr2; tmpstr2[pos] = ' '; } if ((tmpstr3 = strchr(tmpstr2, '-')) == NULL || strchr(tmpstr3 + 1, '-') != NULL) { syslog(LOG_ERR, "MGR: Confused in IP parse routines (multiple hyphens)"); continue; } /* should be left with "192 168 0 234-238" * or 192 168-178 1 231 */ sscanf(tmpstr2, "%7s %7s %7s %7s", ipa, ipb, ipc, ipd); if ((tmpstr6 = strchr(ipd, '-')) != NULL) { pos = tmpstr6 - ipd; ipd[pos] = ' '; sscanf(ipd, "%3s %3s", ipl, ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); #endif lower = atoi(ipl); upper = atoi(ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Range = %d to %d on 4th segment", lower, upper); #endif sprintf(ip_pre, "%.3s.%.3s.%.3s.", ipa, ipb, ipc); ip_post[0] = '\0'; #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); #endif } else if ((tmpstr6 = strchr(ipc, '-')) != NULL) { pos = tmpstr6 - ipc; ipc[pos] = ' '; sscanf(ipc, "%3s %3s", ipl, ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); #endif lower = atoi(ipl); upper = atoi(ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Range = %d to %d on 3rd segment", lower, upper); #endif sprintf(ip_pre, "%.3s.%.3s.", ipa, ipb); sprintf(ip_post, ".%.3s", ipd); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); #endif } else if ((tmpstr6 = strchr(ipb, '-')) != NULL) { pos = tmpstr6 - ipb; ipb[pos] = ' '; sscanf(ipb, "%3s %3s", ipl, ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); #endif lower = atoi(ipl); upper = atoi(ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Range = %d to %d on 2nd segment", lower, upper); #endif sprintf(ip_pre, "%.3s.", ipa); sprintf(ip_post, ".%.3s.%.3s", ipc, ipd); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); #endif } else if ((tmpstr6 = strchr(ipa, '-')) != NULL) { pos = tmpstr6 - ipa; ipa[pos] = ' '; sscanf(ipa, "%3s %3s", ipl, ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: (lower upper) = (%s %s)", ipl, ipu); #endif lower = atoi(ipl); upper = atoi(ipu); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Range = %d to %d on 1st segment", lower, upper); #endif ip_pre[0] = '\0'; sprintf(ip_post, ".%.3s.%.3s.%.3s", ipb, ipc, ipd); #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Pre = %s Post = %s", ip_pre, ip_post); #endif } else { syslog(LOG_ERR, "MGR: Confused in IP parse routines (lost hyphen)"); continue; } for (n = lower; n <= upper; n++) { sprintf(tmpstr5, "%s%d%s", ip_pre, n, ip_post); /* Check if the ip address is valid */ if ((tmpstr7 = validip(tmpstr5)) == NULL) { syslog(LOG_ERR, "MGR: Bad IP address (%s) in config file!", tmpstr5); exit(1); } if (num == pptp_connections) { syslog(LOG_WARNING, "MGR: connections limit (%d) reached, extra IP addresses ignored", pptp_connections); return; } #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Setting IP %d = %s", num, tmpstr7); #endif if (type == LOCAL) slot_set_local(num, tmpstr7); else slot_set_remote(num, tmpstr7); num++; } } } if (num == 1 && type == LOCAL && pptp_connections > 1) { #if DEBUG_IP_PARSER syslog(LOG_DEBUG, "MGR: Setting all %d local IPs to %s", pptp_connections, slot_get_local(0)); #endif for (n = 1; n < pptp_connections; n++) slot_set_local(n, slot_get_local(0)); } else if (pptp_connections > num) { syslog(LOG_INFO, "MGR: Maximum of %d connections reduced to %d, not enough IP addresses given", pptp_connections, num); pptp_connections = num; } }
/* * lookup info about a client in the database. Find an address on the * same net as riip. */ int lookup(Bootp *bp, Info *iip, Info *riip) { Ndbtuple *t, *nt; Ndbs s; char *hwattr; char *hwval, hwbuf[33]; uchar ciaddr[IPaddrlen]; if(opendb() == nil){ warning(1, "can't open db"); return -1; } memset(iip, 0, sizeof(*iip)); /* client knows its address? */ v4tov6(ciaddr, bp->ciaddr); if(validip(ciaddr)){ if(lookupip(ciaddr, iip, 0) < 0) { if (debug) warning(0, "don't know %I", ciaddr); return -1; /* don't know anything about it */ } if(!samenet(riip->ipaddr, iip)){ warning(0, "%I not on %I", ciaddr, riip->ipnet); return -1; } /* * see if this is a masquerade, i.e., if the ether * address doesn't match what we expected it to be. */ if(memcmp(iip->etheraddr, zeroes, 6) != 0) if(memcmp(bp->chaddr, iip->etheraddr, 6) != 0) warning(0, "ciaddr %I rcvd from %E instead of %E", ciaddr, bp->chaddr, iip->etheraddr); return 0; } if(bp->hlen > Maxhwlen) return -1; switch(bp->htype){ case 1: hwattr = "ether"; hwval = hwbuf; snprint(hwbuf, sizeof(hwbuf), "%E", bp->chaddr); break; default: syslog(0, blog, "not ethernet %E, htype %d, hlen %d", bp->chaddr, bp->htype, bp->hlen); return -1; } /* * use hardware address to find an ip address on * same net as riip */ t = ndbsearch(db, &s, hwattr, hwval); while(t){ for(nt = t; nt; nt = nt->entry){ if(strcmp(nt->attr, "ip") != 0) continue; parseip(ciaddr, nt->val); if(lookupip(ciaddr, iip, 0) < 0) continue; if(samenet(riip->ipaddr, iip)){ ndbfree(t); return 0; } } ndbfree(t); t = ndbsnext(&s, hwattr, hwval); } return -1; }