📄 database.c
字号:
return (0); }/********************************************************************************* read_cid - extract identifier value from input string** This routine extracts the client ID value from a numeric pair of the form* <type>:<value>. It is used when parsing entries from the client identifier * field of the address pool and binding databases. The value field is* represented as a string of characters representing a hexadecimal number,* preceded by 0x.** RETURNS: 0 if successful, or -1 on parse error.** ERRNO: N/A** NOMANUAL*/static int read_cid ( char **cp, /* current location in input string */ struct client_id *cid /* pointer to storage for extracted value */ ) { char tmp [MAXSTRINGLEN]; int i, j; get_string (cp, tmp); bzero (cid->id, MAXOPT); /* * Determine length of field by ignoring the leading "0x" characters, * then dividing for the two characters used for each byte. */ cid->idlen = (strlen (tmp) - 2) / 2; if (cid->idlen == 0) return (-1); if (cid->idlen > MAXOPT) { cid->idlen = MAXOPT; logMsg ("Warning: client ID exceeds maximum length. Truncating.\n", 0, 0, 0, 0, 0, 0); } bzero (cid->id, cid->idlen); /* Interpret characters in string as sequence of hexadecimal bytes. */ for (i = 0; i < cid->idlen; i++) { if (sscanf (&tmp [i * 2 + 2], "%2x", &j) != 1) {#ifdef DHCPS_DEBUG logMsg ("Warning: can't extract client ID.\n", 0, 0, 0, 0, 0, 0);#endif return (-1); } cid->id[i] = (char)j; } return (0); }/********************************************************************************* read_haddr - extract client hardware address from input string** This routine extracts the hardware address value from a numeric pair of the * form <type>:<value>. It is used when parsing entries from the hardware* address field of the binding database. If preceded by 0x, the string is* interpreted as a sequence of hexadecimal numbers. Otherwise, it is copied* directly, without interpretation.** RETURNS: 0 if successful, or -1 on parse error.** ERRNO: N/A** NOMANUAL*/static int read_haddr ( char **cp, /* current location in input string */ struct chaddr *haddr /* pointer to storage for extracted value */ ) { char tmp [MAXSTRINGLEN]; int i, j; get_string (cp, tmp); /* Interpret string as hexadecimal number if preceded by 0x. */ if (tmp[0] != '\0' && tmp[0] == '0' && (tmp[1] == 'x' || tmp[1] == 'X')) { /* * Length consists of number of bytes (two characters each) and does * not include the leading 0x. */ haddr->hlen = (strlen (tmp) - 2) / 2; if (haddr->hlen > MAX_HLEN) { haddr->hlen = MAX_HLEN; logMsg ("Hardware address exceeds maximum length. Truncating.\n", 0, 0, 0, 0, 0, 0); } bzero (haddr->haddr, haddr->hlen); for (i = 0; i < haddr->hlen; i++) { if (sscanf (&tmp [i * 2 + 2], "%2x", &j) != 1) {#ifdef DHCPS_DEBUG logMsg ("Warning: error extracting hardware address.\n", 0, 0, 0, 0, 0, 0);#endif return (-1); } haddr->haddr[i] = (char) j; } } else { haddr->hlen = strlen (tmp); if (haddr->hlen > MAX_HLEN) { haddr->hlen = MAX_HLEN; logMsg ("Hardware address exceeds maximum length. Truncating.\n", 0, 0, 0, 0, 0, 0); } bzero (haddr->haddr, haddr->hlen); bcopy (tmp, haddr->haddr, haddr->hlen); } return (0); }/********************************************************************************* read_subnet - extract subnet number from input string** This routine extracts the subnet number (in dotted decimal format) from the * input string into the provided buffer. It is used when parsing entries from * the subnet field of the binding database. If a client has changed subnets, * the lease recorded in the binding database will not be renewed.** RETURNS: 0 if successful, or -1 on parse error.** ERRNO: N/A** NOMANUAL*/static int read_subnet ( char **cp, /* current location in input string */ struct in_addr *subnet /* pointer to storage for extracted value */ ) { char tmpstr [MAXSTRINGLEN]; char *pTmp; STATUS result; get_string (cp, tmpstr); pTmp = tmpstr; result = get_ip (&pTmp, subnet); if (result != OK) {#ifdef DHCPS_DEBUG logMsg ("Warning: can't extract subnet number.\n", 0, 0, 0, 0, 0, 0);#endif return (-1); } return (0); }/********************************************************************************* read_bind_db - extract offered and active leases from permanent storage** This routine calls a hook routine, supplied by the user, to retrieve the * entries for each active or pending lease. It builds the list of these * entries and updates the internal data storage to prevent re-assignment of * IP addresses already in use. It is called once on server startup.** RETURNS: OK if data update completed, or ERROR otherwise.** ERRNO: N/A** NOMANUAL*/STATUS read_bind_db (void) { char buffer [MAXSTRINGLEN]; char tmp [MAXSTRINGLEN]; char *bufptr = NULL; unsigned buflen = 0; struct dhcp_binding *binding = NULL; STATUS result; if (dhcpsLeaseHookRtn == NULL) return (OK); result = (* dhcpsLeaseHookRtn) (DHCPS_STORAGE_START, NULL, 0); if (result != OK) { logMsg ("Warning: cannot open the binding database.\n", 0, 0, 0, 0, 0, 0); return (ERROR); } /* * Read binding information from entries with the following format: * * idtype:id:subnet:htype:haddr:"expire_date":resource_name */ FOREVER { buflen = sizeof (buffer); /* Extract single entry from storage as NULL-terminated string. */ read_entry (buffer, &buflen); if (buflen == 0) break; bufptr = buffer; if (buffer[0] == '\0') return (OK); /* Create linked list element. */ binding = (struct dhcp_binding *) calloc (1, sizeof (struct dhcp_binding)); if (binding == NULL) {#ifdef DHCPS_DEBUG logMsg("Error: Couldn't allocate memory in read_bind_db\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } /* read client identifier type */ if (read_idtype (&bufptr, &binding->cid.idtype) != 0) { free (binding); return (ERROR); } /* read client identifier value */ adjust (&bufptr); if (read_cid (&bufptr, &binding->cid) != 0) { free (binding); return (ERROR); } /* read subnet number of client */ adjust (&bufptr); if (read_subnet (&bufptr, &binding->cid.subnet) != 0) { free (binding); return (ERROR); } /* read hardware address type (e.g. "1" for 10 MB ethernet). */ adjust (&bufptr); if (read_idtype (&bufptr, &binding->haddr.htype) != 0) { free (binding); return (ERROR); } /* read client hardware address */ adjust (&bufptr); if (read_haddr (&bufptr, &binding->haddr) != 0) { free (binding); return (ERROR); } /* read expiration time for lease */ adjust (&bufptr); get_string (&bufptr, tmp); if (strcmp (tmp, "infinity") == 0 || strcmp(tmp, "bootp") == 0) binding->expire_epoch = 0xffffffff; else binding->expire_epoch = strtotime (tmp); /* read name of lease descriptor */ adjust (&bufptr); get_string (&bufptr, tmp); if (strlen (tmp) > MAX_NAME) { bcopy (tmp, binding->res_name, MAX_NAME); binding->res_name [MAX_NAME] = '\0'; } else { bcopy (tmp, binding->res_name, strlen (tmp)); binding->res_name [strlen (tmp)] = '\0'; } /* Find lease descriptor with given name. */ binding->res = (struct dhcp_resource *) hash_find ( &nmhashtable, binding->res_name, strlen (binding->res_name), resnmcmp, binding->res_name); if (binding->res == NULL) {#ifdef DHCPS_DEBUG logMsg ("Warning: can't find the resource \"%s\"", (int)binding->res_name, 0, 0, 0, 0, 0);#endif /* free binding info */ free (binding); continue; } /* Link lease record to lease descriptor and store in hash table. */ binding->res->binding = binding; binding->flag |= COMPLETE_ENTRY; if (hash_ins (&cidhashtable, binding->cid.id, binding->cid.idlen, bindcidcmp, &binding->cid, binding) < 0) {#ifdef DHCPS_DEBUG logMsg ("Error: Couldn't add client identifier to hash table.\n", 0, 0, 0, 0, 0, 0);#endif free (binding); return (ERROR); } /* Add lease record to linked list. */ if (add_bind (binding) != 0) { free (binding); return (ERROR); } }#ifdef DHCPS_DEBUG logMsg ("dhcps: read %d entries from binding and addr-pool database.\n", nbind, 0, 0, 0, 0, 0);#endif return (OK); }/********************************************************************************* read_relay_db - parse relay agent database** This routine creates the list of available relay agents. The DHCP server* will accept messages forwarded from other subnets if they are delivered* by a relay agent contained in the list.** RETURNS: OK if list created, or ERROR otherwise.** ERRNO: N/A** NOMANUAL*/void read_relay_db ( int dbsize /* number of relay agents in database */ ) { char relayIP [INET_ADDR_LEN]; char subnet_mask [INET_ADDR_LEN]; int nrelay = 0; int loop; int result; struct relay_acl *acl = NULL; /* * Read database entries, which contain relay agent's IP address and * subnet number. If it finds a NULL entry for pAddress it will stop * processing the table. */ for (loop = 0; (loop < dbsize) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -