1627 lines
42 KiB
C
1627 lines
42 KiB
C
#include <stdio.h>
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#include <net/if.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <strings.h>
|
|
#include <sys/sysmacros.h>
|
|
#include <ctype.h>
|
|
#include <dirent.h>
|
|
#include <syslog.h>
|
|
#include <errno.h>
|
|
#include <ndbm.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include "dhcp.h"
|
|
#include "dhcpdefs.h"
|
|
#include "dhcp_types.h"
|
|
#include "dhcp_optvals.h"
|
|
|
|
char *RealHostFile = "/etc/hosts";
|
|
char *tmpHostFile = "/etc/hosts.tmp";
|
|
char *RealEtherFile = "/etc/ethers";
|
|
char *tmpEtherFile = "/etc/ethers.tmp";
|
|
|
|
char addl_options_to_send[128]; /* these are options specified in the
|
|
* options file
|
|
*/
|
|
int addl_options_len = 0;
|
|
|
|
extern iaddr_t myhostaddr;
|
|
extern struct netaddr *np_recv;
|
|
extern int ifcount;
|
|
extern int ProclaimServer;
|
|
extern int always_return_netmask;
|
|
rfc1533opts *rfc1533ptr = 0;
|
|
|
|
extern int sys0_removeFromHostsFile(u_long);
|
|
extern int sys0_removeFromEthersFile(EtherAddr *);
|
|
extern int ether_line(char *, struct ether_addr *, char *);
|
|
extern int efputs(char*, FILE*);
|
|
extern int erename(char*, char*);
|
|
extern void setparams(struct getParams*, int, u_char*);
|
|
|
|
char * alt_hosts_file = (char *)0;
|
|
char * alt_ethers_file = (char *)0;
|
|
int dont_update_hosts = 0;
|
|
int dont_update_ethers = 0;
|
|
|
|
#define LINE_SIZE 128
|
|
|
|
#define CONFIG_DIR "/etc/config/"
|
|
|
|
FILE *
|
|
log_fopen(char *file, char *options)
|
|
{
|
|
FILE *fp;
|
|
|
|
fp = fopen(file, options);
|
|
if (! fp) {
|
|
syslog(LOG_ERR, "fopen failed for file %s: %m", file);
|
|
}
|
|
return fp;
|
|
}
|
|
|
|
DBM *
|
|
log_dbmopen(char *file){
|
|
DBM *db;
|
|
db = dbm_open(file, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IROTH);
|
|
if (db==NULL)
|
|
syslog(LOG_ERR, "dbm_open failed for file %s: %m", file);
|
|
return db;
|
|
}
|
|
|
|
void
|
|
log_dbmclose(DBM *db){
|
|
dbm_close(db);
|
|
|
|
}
|
|
|
|
int
|
|
dh0_get_dhcp_msg_type(u_char *dhbuf)
|
|
{
|
|
u_char *p, *p_end;
|
|
int len;
|
|
int msg_type = -1;
|
|
|
|
p = dhbuf;
|
|
p_end = p + DHCP_OPTS_SIZE;
|
|
|
|
while( (p < p_end) && (*p != END_TAG) ) {
|
|
switch(*p++) {
|
|
case PAD_TAG:
|
|
continue;
|
|
case DHCP_MSG_TAG:
|
|
len = *p++;
|
|
if(len == 1)
|
|
msg_type = *p++;
|
|
return msg_type;
|
|
case SGI_VENDOR_TAG:
|
|
len = *p++;
|
|
continue;
|
|
default:
|
|
len = *p++;
|
|
p += len;
|
|
}
|
|
}
|
|
return msg_type;
|
|
}
|
|
|
|
/* dhcp_client_info added to support Dynmaic DNS and vendor options
|
|
* we should actually collect most of the parameters passed and place
|
|
* them into dhcp_client_info
|
|
*/
|
|
int
|
|
dh0_decode_dhcp_client_packet(u_char dhbuf[], struct getParams *reqParams,
|
|
u_long *ipaddr,
|
|
u_int *lease, u_long *server, char **req_hsname,
|
|
char **cid_ptr, int *cid_flag_ptr,
|
|
int *cid_length, int *sgi_resolv_name,
|
|
struct dhcp_client_info* dcip_data)
|
|
{
|
|
char nbuf[MAXHOSTNAMELEN+1];
|
|
u_char *p, *p_end;
|
|
int len;
|
|
int msg_type = -1;
|
|
int hostname_tag_flag = 0;
|
|
int encaps_options_len = 0; /* distinguish between client fqdn and
|
|
* sgi hostname which have the same option code
|
|
*/
|
|
|
|
bzero(reqParams, sizeof(struct getParams));
|
|
if (addl_options_len) {
|
|
setparams(reqParams, addl_options_len, (u_char*)addl_options_to_send);
|
|
}
|
|
*ipaddr = *server = 0;
|
|
*lease = 0;
|
|
p = dhbuf;
|
|
p_end = p + DHCP_OPTS_SIZE;
|
|
|
|
while( (p < p_end) && (*p != END_TAG) ) {
|
|
switch(*p++) {
|
|
case PAD_TAG:
|
|
continue;
|
|
case DHCP_MSG_TAG:
|
|
len = *p++;
|
|
if(len == 1)
|
|
msg_type = *p++;
|
|
else
|
|
p += len;
|
|
if( (msg_type < DHCPDISCOVER) || (msg_type > DHCPPOLL) )
|
|
msg_type = -1;
|
|
continue;
|
|
case DHCP_PARAM_REQ_TAG:
|
|
len = *p++;
|
|
setparams(reqParams, len, p);
|
|
p += len;
|
|
continue;
|
|
case IPADDR_TAG:
|
|
len = *p++;
|
|
if(len == 4) {
|
|
bcopy(p, ipaddr, 4);
|
|
p += len;
|
|
}
|
|
continue;
|
|
case IP_LEASE_TIME_TAG:
|
|
len = *p++;
|
|
if(len == 4) {
|
|
bcopy(p, lease, 4);
|
|
p += len;
|
|
}
|
|
continue;
|
|
case DHCP_SERVER_TAG:
|
|
len = *p++;
|
|
if(len == 4) {
|
|
bcopy(p, server, 4);
|
|
p += len;
|
|
}
|
|
continue;
|
|
case SGI_VENDOR_TAG:
|
|
len = *p++;
|
|
encaps_options_len = len;
|
|
continue;
|
|
case RESOLVE_HOSTNAME_TAG:
|
|
/* case CLIENT_FQDN_TAG:*/
|
|
/* Windows NT clients also set this - but our clients use either
|
|
HOSTNAME_TAG or RESOLVE_HOSTNAME_TAG. If HOSTNAME_TAG is set or if
|
|
the first byte is null in the value field we ignore this TAG
|
|
In the long term we should stop using this hack */
|
|
len = *p++;
|
|
bcopy(p, nbuf, len);
|
|
nbuf[len] = '\0';
|
|
if (encaps_options_len > 0) { /* SGI hostname */
|
|
if ((nbuf[0] != '\0') && (0 == hostname_tag_flag)) {
|
|
*req_hsname = strdup(nbuf);
|
|
*sgi_resolv_name = 1;
|
|
}
|
|
encaps_options_len -= len; /* may have client fqdn also */
|
|
}
|
|
else {
|
|
/* CLIENT_FQDN_TAG - if its not encapsulated then it must be this */
|
|
bcopy(p, dcip_data->client_fqdn, len); /* flag, rcode1, rcode2, domain name */
|
|
reqParams->GET_CLIENT_FQDN = 1;
|
|
}
|
|
p += len;
|
|
continue;
|
|
case DHCP_CLASS_TAG: /* 60 */
|
|
/* clients send the vendor class using this tag */
|
|
len = *p++;
|
|
bcopy(p, dcip_data->vendor_tag, len);
|
|
p += len;
|
|
continue;
|
|
case HOSTNAME_TAG:
|
|
len = *p++;
|
|
bcopy(p, nbuf, len);
|
|
nbuf[len] = '\0';
|
|
if (*sgi_resolv_name == 1) {
|
|
*sgi_resolv_name = 0;
|
|
free(*req_hsname);
|
|
*req_hsname = (char*)0;
|
|
}
|
|
if (*req_hsname)
|
|
free(*req_hsname);
|
|
*req_hsname = strdup(nbuf);
|
|
hostname_tag_flag = 1;
|
|
p += len;
|
|
continue;
|
|
case DHCP_CLIENT_ID_TAG:
|
|
len = *p; /*the Len field includes both the h/w type & CID*/
|
|
p += 1;
|
|
if (len >= 2){
|
|
*cid_length = len;
|
|
*cid_ptr = (char *)malloc(len * sizeof(char));
|
|
bzero(*cid_ptr, len);
|
|
bcopy(p, *cid_ptr, len); /*copying type + cid*/
|
|
/* *(cid_ptr + len) = NULL; */
|
|
p += len;
|
|
*cid_flag_ptr = 1;
|
|
}
|
|
continue;
|
|
default:
|
|
len = *p++;
|
|
p += len;
|
|
}
|
|
}
|
|
return msg_type;
|
|
}
|
|
|
|
static int
|
|
encode_ptr_tag(char **pb, int tag, char *value, int len)
|
|
{
|
|
char *p;
|
|
|
|
p = *pb;
|
|
if(value && *value) {
|
|
*p++ = tag;
|
|
*p++ = len;
|
|
bcopy(value, p, len);
|
|
p += len;
|
|
*pb = p;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
encode_value_tag(char **pb, int tag, unsigned value, int len)
|
|
{
|
|
char *p;
|
|
unsigned short val;
|
|
|
|
p = *pb;
|
|
if(value) {
|
|
*p++ = tag;
|
|
*p++ = len;
|
|
if(len == 1)
|
|
*p = value;
|
|
else if (len == 2) {
|
|
val = (unsigned short) value;
|
|
bcopy(&val, p, len);
|
|
}
|
|
else
|
|
bcopy(&value, p, len);
|
|
p += len;
|
|
*pb = p;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
encode_ptrvalue_array_tag(char **pb, int tag, u_long *value)
|
|
{
|
|
char *p, *q;
|
|
int i;
|
|
int tlen;
|
|
|
|
if(!value)
|
|
return 1;
|
|
p = *pb;
|
|
|
|
tlen = 0;
|
|
*p++ = tag;
|
|
q = p++;
|
|
|
|
i = 0;
|
|
while(value[i]) {
|
|
bcopy(&value[i], p, 4);
|
|
p += 4;
|
|
tlen += 4;
|
|
i++;
|
|
}
|
|
*q = tlen;
|
|
*pb = p;
|
|
if(i == 0)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* encode vendor options onto the packet sent to the client
|
|
* all applicable vendor options for the vendor class are
|
|
* sent regardsless of whether they were asked for or not
|
|
*/
|
|
int
|
|
dh0_encode_vendor_options(struct getParams *reqP, char *offered_hsname,
|
|
dhcpConfig *cfg, char **cpp,
|
|
struct dhcp_client_info *dcip_data)
|
|
{
|
|
int tlen;
|
|
char *p, *q;
|
|
struct dhcp_optval *dop_opt;
|
|
struct vendor_options *vop_opt;
|
|
int len, i;
|
|
char *optlen;
|
|
|
|
tlen = 0;
|
|
p = *cpp;
|
|
/* this is retained for compatibility with old clients
|
|
* the clients must be changed to send a sgi tag instead */
|
|
if( (reqP->RESOLVE_HOSTNAME) || (reqP->GET_SDIST_SERVER) ) {
|
|
if(offered_hsname || cfg->p_propel_addr) {
|
|
*p++ = SGI_VENDOR_TAG;
|
|
q = p++;
|
|
if((reqP->GET_SDIST_SERVER) && cfg->p_propel_addr) {
|
|
encode_value_tag(&p, SDIST_SERVER_TAG, cfg->p_propel_addr, 4);
|
|
tlen += (4+2);
|
|
}
|
|
if((reqP->RESOLVE_HOSTNAME) && offered_hsname) {
|
|
len = strlen(offered_hsname);
|
|
encode_ptr_tag(&p, RESOLVE_HOSTNAME_TAG, offered_hsname, len);
|
|
tlen += (len+2);
|
|
}
|
|
}
|
|
}
|
|
if (dcip_data->vendor_tag[0] != NULL) { /* add the applicable
|
|
vendor class options */
|
|
/* check if this vendor tag is in cfg */
|
|
vop_opt = cfg->vop_options;
|
|
while (vop_opt) {
|
|
if (strcmp(vop_opt->cp_vendor_tag,
|
|
dcip_data->vendor_tag) == 0) {
|
|
dop_opt = vop_opt->dop_optval;
|
|
while (dop_opt && (dop_opt->i_opt_num != 0)) {
|
|
for (i = 0; i < MAX_OPT_TYPES; i++) {
|
|
if (dop_opt->dof_fields[i].i_len) {
|
|
if (tlen == 0) {
|
|
*p++ = SGI_VENDOR_TAG;
|
|
q = p++;
|
|
}
|
|
if (i == 0) {
|
|
*p++ = (uint8_t)dop_opt->i_opt_num;
|
|
optlen = p++;
|
|
*optlen = (uint8_t)0;
|
|
}
|
|
dop_opt->dof_fields[i].doep_encoder
|
|
(dop_opt->i_opt_num,
|
|
dop_opt->dof_fields[i].vp_value, &p,
|
|
dop_opt->dof_fields[i].i_len);
|
|
*optlen += (uint8_t)(dop_opt->dof_fields[i].i_len);
|
|
if (i == 0)
|
|
tlen += (dop_opt->dof_fields[i].i_len + 2);
|
|
else
|
|
tlen += dop_opt->dof_fields[i].i_len;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
dop_opt = dop_opt->dop_next;
|
|
}
|
|
}
|
|
vop_opt = vop_opt->vop_next;
|
|
}
|
|
}
|
|
if (tlen)
|
|
*q = tlen;
|
|
*cpp = p;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* used dhcp_client_info instead of multiple fields
|
|
*/
|
|
int
|
|
dh0_encode_dhcp_server_packet(u_char dhbuf[], int msgtype,
|
|
struct getParams *reqP, u_long req_lease,
|
|
char *msg, char *hsname, char *offered_hsname,
|
|
dhcpConfig *cfg,
|
|
struct dhcp_client_info *dcip_data)
|
|
{
|
|
char *p, *q;
|
|
int i;
|
|
int tlen, len;
|
|
unsigned short tmpshort;
|
|
u_long mltaddr;
|
|
|
|
if( (msgtype < DHCPDISCOVER) || (msgtype > DHCPPRPL) )
|
|
return 1;
|
|
if( (msgtype != DHCPNAK) && (msgtype != DHCPPRPL) && (cfg == 0) )
|
|
return 2;
|
|
|
|
p = (char *)dhbuf;
|
|
encode_value_tag(&p, DHCP_MSG_TAG, msgtype, 1);
|
|
|
|
/* IP Address lease time is a MUST item */
|
|
if( (msgtype == DHCPOFFER) || (msgtype == DHCPACK) ) {
|
|
/* lease value is computed elsewhere. If lease is zero then
|
|
don't send it (response to DHCPINFORM) */
|
|
if (req_lease)
|
|
encode_value_tag(&p, IP_LEASE_TIME_TAG, req_lease, 4);
|
|
}
|
|
|
|
/* The server identifier is a MUST field */
|
|
mltaddr = MULTIHMDHCP ? np_recv->myaddr.s_addr : myhostaddr.s_addr;
|
|
encode_value_tag(&p, DHCP_SERVER_TAG, mltaddr, 4);
|
|
if(msgtype == DHCPNAK) {
|
|
if(msg) {
|
|
len = strlen(msg);
|
|
encode_ptr_tag(&p, DHCP_SERVER_MSG, msg, len);
|
|
}
|
|
*p = END_TAG;
|
|
return 0;
|
|
}
|
|
|
|
if( (reqP->GET_SUBNETMASK) || (always_return_netmask) ) {
|
|
encode_value_tag(&p, SUBNETMASK_TAG, cfg->p_netmask, 4);
|
|
}
|
|
if(reqP->GET_HOSTNAME) {
|
|
if(hsname && *hsname) {
|
|
len = strlen(hsname);
|
|
encode_ptr_tag(&p, HOSTNAME_TAG, hsname, len);
|
|
}
|
|
}
|
|
if(reqP->GET_NISDOMAIN) {
|
|
if(cfg->p_nisdomain && *(cfg->p_nisdomain)) {
|
|
len = strlen(cfg->p_nisdomain);
|
|
encode_ptr_tag(&p, NISDOMAIN_NAME_TAG, cfg->p_nisdomain, len);
|
|
}
|
|
}
|
|
if(reqP->GET_DNSDOMAIN) {
|
|
if(cfg->p_dnsdomain && *(cfg->p_dnsdomain)) {
|
|
len = strlen(cfg->p_dnsdomain);
|
|
encode_ptr_tag(&p, DNSDOMAIN_NAME_TAG, cfg->p_dnsdomain, len);
|
|
}
|
|
}
|
|
|
|
dh0_encode_vendor_options(reqP, offered_hsname, cfg, &p, dcip_data);
|
|
|
|
if(reqP->GET_ROUTER) {
|
|
encode_ptrvalue_array_tag(&p, ROUTER_TAG, cfg->p_router_addr);
|
|
}
|
|
if(reqP->GET_TIMESERVERS) {
|
|
encode_ptrvalue_array_tag(&p, TIMESERVERS_TAG, cfg->p_tmsserver_addr);
|
|
}
|
|
if(reqP->GET_DNSSERVERS) {
|
|
encode_ptrvalue_array_tag(&p, DNSSERVERS_TAG, cfg->p_dnsserver_addr);
|
|
}
|
|
if(reqP->GET_NIS_SERVERS) {
|
|
encode_ptrvalue_array_tag(&p, NIS_SERVERS_TAG, cfg->p_nisserver_addr);
|
|
}
|
|
if(reqP->GET_IF_MTU) {
|
|
encode_value_tag(&p, IF_MTU_TAG, cfg->p_mtu, 2);
|
|
}
|
|
if(reqP->GET_ALL_SUBNETS_LOCAL) {
|
|
if(cfg->p_allnetsloc)
|
|
encode_value_tag(&p, ALL_SUBNETS_LOCAL_TAG, 1, 1);
|
|
else
|
|
encode_value_tag(&p, ALL_SUBNETS_LOCAL_TAG, 0, 1);
|
|
}
|
|
if(reqP->GET_BROADCAST_ADDRESS) {
|
|
encode_value_tag(&p, BROADCAST_ADDRESS_TAG, cfg->p_broadcast, 4);
|
|
}
|
|
if(reqP->GET_CLIENT_MASK_DISC) {
|
|
if(cfg->p_domaskdisc)
|
|
encode_value_tag(&p, CLIENT_MASK_DISC_TAG, 1, 1);
|
|
else
|
|
encode_value_tag(&p, CLIENT_MASK_DISC_TAG, 0, 1);
|
|
}
|
|
if(reqP->GET_MASK_SUPPLIER) {
|
|
if(cfg->p_respmaskreq)
|
|
encode_value_tag(&p, MASK_SUPPLIER_TAG, 1, 1);
|
|
else
|
|
encode_value_tag(&p, MASK_SUPPLIER_TAG, 0, 1);
|
|
}
|
|
if( (reqP->GET_STATIC_ROUTE) && cfg->p_routes) {
|
|
tlen = 0;
|
|
*p++ = STATIC_ROUTE_TAG;
|
|
q = p++;
|
|
i = 0;
|
|
while(cfg->p_routes[i].r_dest && cfg->p_routes[i].r_router) {
|
|
bcopy(&cfg->p_routes[i].r_dest, p, 4);
|
|
p += 4;
|
|
bcopy(&cfg->p_routes[i].r_router, p, 4);
|
|
p += 4;
|
|
tlen += 8;
|
|
i++;
|
|
}
|
|
*q = tlen;
|
|
}
|
|
if(reqP->GET_RENEW_LEASE_TIME) {
|
|
if(req_lease && (req_lease < cfg->p_lease))
|
|
encode_value_tag(&p, RENEW_LEASE_TIME_TAG, req_lease/2, 4);
|
|
else
|
|
encode_value_tag(&p, RENEW_LEASE_TIME_TAG, cfg->p_lease/2, 4);
|
|
}
|
|
if(reqP->GET_REBIND_LEASE_TIME) {
|
|
if(req_lease && (req_lease < cfg->p_lease))
|
|
encode_value_tag(&p, REBIND_LEASE_TIME_TAG, (7/8)*req_lease, 4);
|
|
else
|
|
encode_value_tag(&p, REBIND_LEASE_TIME_TAG, (7/8)*cfg->p_lease, 4);
|
|
}
|
|
|
|
/* new options added here */
|
|
if (reqP->GET_LOGSERVERS)
|
|
encode_ptrvalue_array_tag(&p, LOGSERVERS_TAG, cfg->p_logserver_addr);
|
|
if (reqP->GET_COOKIESERVERS)
|
|
encode_ptrvalue_array_tag(&p, COOKIESERVERS_TAG,
|
|
cfg->p_cookieserver_addr);
|
|
if (reqP->GET_LPRSERVERS)
|
|
encode_ptrvalue_array_tag(&p, LPRSERVERS_TAG, cfg->p_LPRserver_addr);
|
|
if (reqP->GET_RESOURCESERVERS)
|
|
encode_ptrvalue_array_tag(&p, RESOURCESERVERS_TAG,
|
|
cfg->p_resourceserver_addr);
|
|
if((reqP->GET_BOOTFILE_SIZE) && (cfg->p_bootfile_size))
|
|
encode_value_tag(&p, BOOTFILE_SIZE_TAG, cfg->p_bootfile_size, 2);
|
|
if(reqP->GET_SWAPSERVER_ADDRESS)
|
|
encode_value_tag(&p, SWAPSERVER_ADDRESS_TAG,
|
|
cfg->p_swapserver_addr, 4);
|
|
if(reqP->GET_IP_FORWARDING)
|
|
encode_value_tag(&p, IP_FORWARDING_TAG, cfg->p_IPforwarding, 1);
|
|
if(reqP->GET_NON_LOCAL_SRC_ROUTE)
|
|
encode_value_tag(&p, NON_LOCAL_SRC_ROUTE_TAG,
|
|
cfg->p_source_routing, 1);
|
|
if( (reqP->GET_POLICY_FILTER) && cfg->p_policy_filter) {
|
|
tlen = 0;
|
|
*p++ = POLICY_FILTER_TAG;
|
|
q = p++;
|
|
i = 0;
|
|
while(cfg->p_policy_filter[i].r_dest && cfg->p_routes[i].r_router) {
|
|
bcopy(&cfg->p_policy_filter[i].r_dest, p, 4); /* address */
|
|
p += 4;
|
|
bcopy(&cfg->p_policy_filter[i].r_router, p, 4); /* mask */
|
|
p += 4;
|
|
tlen += 8;
|
|
i++;
|
|
}
|
|
*q = tlen;
|
|
}
|
|
if(reqP->GET_MAX_DGRAM_REASSEMBL)
|
|
encode_value_tag(&p, MAX_DGRAM_REASSEMBL_TAG,
|
|
cfg->p_max_reassy_size, 2);
|
|
if(reqP->GET_DEF_IP_TIME_LIVE)
|
|
encode_value_tag(&p, DEF_IP_TIME_LIVE_TAG, cfg->p_IP_ttl, 1);
|
|
if(reqP->GET_PATH_MTU_AGE_TMOUT)
|
|
encode_value_tag(&p, PATH_MTU_AGE_TMOUT_TAG,
|
|
cfg->p_pathmtu_timeout, 4);
|
|
if( (reqP->GET_PATH_MTU_PLT_TABLE) && (cfg->p_pathmtu_table)) {
|
|
tlen = 0;
|
|
*p++ = PATH_MTU_PLT_TABLE_TAG;
|
|
q = p++;
|
|
i = 0;
|
|
while (tmpshort = cfg->p_pathmtu_table[i]) {
|
|
bcopy(&tmpshort, p, 2);
|
|
p += 1;
|
|
tlen += 2;
|
|
i++;
|
|
}
|
|
*q = tlen;
|
|
}
|
|
if(reqP->GET_ROUTER_DISC)
|
|
encode_value_tag(&p, ROUTER_DISC_TAG, cfg->p_router_disc, 1);
|
|
if(reqP->GET_ROUTER_SOLICIT_ADDR)
|
|
encode_value_tag(&p, ROUTER_SOLICIT_ADDR_TAG,
|
|
cfg->p_router_solicit_addr, 4);
|
|
if(reqP->GET_TRAILER_ENCAPS)
|
|
encode_value_tag(&p, TRAILER_ENCAPS_TAG, cfg->p_trailer_encaps, 1);
|
|
if( (reqP->GET_ARP_CACHE_TIMEOUT) && (cfg->p_arpcache_timeout))
|
|
encode_value_tag(&p, ARP_CACHE_TIMEOUT_TAG, cfg->p_arpcache_timeout, 4);
|
|
if(reqP->GET_ETHERNET_ENCAPS)
|
|
encode_value_tag(&p, ETHERNET_ENCAPS_TAG, cfg->p_ether_encaps, 1);
|
|
if( (reqP->GET_TCP_DEFAULT_TTL) && (cfg->p_TCP_ttl))
|
|
encode_value_tag(&p, TCP_DEFAULT_TTL_TAG, cfg->p_TCP_ttl, 1);
|
|
if( (reqP->GET_TCP_KEEPALIVE_INTVL) && (cfg->p_TCP_keepalive_intrvl))
|
|
encode_value_tag(&p, TCP_KEEPALIVE_INTVL_TAG,
|
|
cfg->p_TCP_keepalive_intrvl, 4);
|
|
if(reqP->GET_TCP_KEEPALIVE_GARBG)
|
|
encode_value_tag(&p, TCP_KEEPALIVE_GARBG_TAG,
|
|
cfg->p_TCP_keepalive_garbage, 1);
|
|
if (reqP->GET_NETBIOS_NMSERV_ADDR)
|
|
encode_ptrvalue_array_tag(&p, NETBIOS_NMSERV_ADDR_TAG,
|
|
cfg->p_NetBIOS_nameserver_addr);
|
|
if (reqP->GET_NETBIOS_DISTR_ADDR)
|
|
encode_ptrvalue_array_tag(&p, NETBIOS_DISTR_ADDR_TAG,
|
|
cfg->p_NetBIOS_distrserver_addr);
|
|
if( (reqP->GET_NETBIOS_NODETYPE) && (cfg->p_NetBIOS_nodetype))
|
|
encode_value_tag(&p, NETBIOS_NODETYPE_TAG,
|
|
cfg->p_NetBIOS_nodetype, 1);
|
|
if(reqP->GET_NETBIOS_SCOPE) { /* is this a string ???? */
|
|
if(cfg->p_NetBIOS_scope && *(cfg->p_NetBIOS_scope)) {
|
|
len = strlen(cfg->p_NetBIOS_scope);
|
|
encode_ptr_tag(&p, NETBIOS_SCOPE_TAG, cfg->p_NetBIOS_scope, len);
|
|
}
|
|
}
|
|
if (reqP->GET_NETBIOS_DISTR_ADDR)
|
|
encode_ptrvalue_array_tag(&p, NETBIOS_DISTR_ADDR_TAG,
|
|
cfg->p_NetBIOS_distrserver_addr);
|
|
if (reqP->GET_X_FONTSERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, X_FONTSERVER_ADDR_TAG,
|
|
cfg->p_X_fontserver_addr);
|
|
if (reqP->GET_X_DISPLAYMGR_ADDR)
|
|
encode_ptrvalue_array_tag(&p, X_DISPLAYMGR_ADDR_TAG,
|
|
cfg->p_X_displaymgr_addr);
|
|
if(reqP->GET_NISPLUS_DOMAIN) {
|
|
if(cfg->p_nisplusdomain && *(cfg->p_nisplusdomain)) {
|
|
len = strlen(cfg->p_nisplusdomain);
|
|
encode_ptr_tag(&p, NISPLUS_DOMAIN_TAG, cfg->p_nisplusdomain, len);
|
|
}
|
|
}
|
|
if (reqP->GET_NISPLUS_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, NISPLUS_SERVER_ADDR_TAG,
|
|
cfg->p_nisplusserver_addr);
|
|
if (reqP->GET_MBLEIP_HMAGENT_ADDR)
|
|
encode_ptrvalue_array_tag(&p, MBLEIP_HMAGENT_ADDR_TAG,
|
|
cfg->p_mobileIP_homeagent_addr);
|
|
if (reqP->GET_SMTP_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, SMTP_SERVER_ADDR_TAG,
|
|
cfg->p_SMTPserver_addr);
|
|
if (reqP->GET_POP3_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, POP3_SERVER_ADDR_TAG,
|
|
cfg->p_POP3server_addr);
|
|
if (reqP->GET_NNTP_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, NNTP_SERVER_ADDR_TAG,
|
|
cfg->p_NNTPserver_addr);
|
|
if (reqP->GET_WWW_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, WWW_SERVER_ADDR_TAG,
|
|
cfg->p_WWWserver_addr);
|
|
if (reqP->GET_FINGER_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, FINGER_SERVER_ADDR_TAG,
|
|
cfg->p_fingerserver_addr);
|
|
if (reqP->GET_IRC_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, IRC_SERVER_ADDR_TAG,
|
|
cfg->p_IRCserver_addr);
|
|
if (reqP->GET_STTALK_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, STTALK_SERVER_ADDR_TAG,
|
|
cfg->p_StreetTalkserver_addr);
|
|
if (reqP->GET_STDA_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, STDA_SERVER_ADDR_TAG,
|
|
cfg->p_STDAserver_addr);
|
|
|
|
if (reqP->GET_TIME_OFFSET)
|
|
encode_value_tag(&p, TIME_OFFSET_TAG, cfg->p_time_offset, 4);
|
|
if (reqP->GET_NAMESERVER116_ADDR)
|
|
encode_ptrvalue_array_tag(&p, NAME_SERVER116_TAG,
|
|
cfg->p_nameserver116_addr);
|
|
if (reqP->GET_IMPRESS_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, IMPRESSSERVERS_TAG,
|
|
cfg->p_impressserver_addr);
|
|
if (reqP->GET_MERITDUMP_FILE) {
|
|
if (cfg->p_merit_dump_pathname && *(cfg->p_merit_dump_pathname)) {
|
|
len = strlen(cfg->p_merit_dump_pathname);
|
|
encode_ptr_tag(&p, MERITDUMP_FILE_TAG, cfg->p_merit_dump_pathname,
|
|
len);
|
|
}
|
|
}
|
|
if (reqP->GET_ROOT_PATH) {
|
|
if (cfg->p_root_disk_pathname && *(cfg->p_root_disk_pathname)) {
|
|
len = strlen(cfg->p_root_disk_pathname);
|
|
encode_ptr_tag(&p, ROOT_PATH_TAG, cfg->p_root_disk_pathname,
|
|
len);
|
|
}
|
|
}
|
|
if (reqP->GET_EXTENSIONS) {
|
|
if (cfg->p_extensions_pathname && *(cfg->p_extensions_pathname)) {
|
|
len = strlen(cfg->p_extensions_pathname);
|
|
encode_ptr_tag(&p, EXTENSIONS_PATH_TAG, cfg->p_extensions_pathname,
|
|
len);
|
|
}
|
|
}
|
|
if (reqP->GET_NTP_SERVER_ADDR)
|
|
encode_ptrvalue_array_tag(&p, NTP_SERVERS_TAG, cfg->p_NTPserver_addr);
|
|
if (reqP->GET_TFTP_SERVER_NAME) {
|
|
if (cfg->p_tftp_server_name && *(cfg->p_tftp_server_name)) {
|
|
len = strlen(cfg->p_tftp_server_name);
|
|
encode_ptr_tag(&p, TFTP_SERVER_NAME_TAG, cfg->p_tftp_server_name,
|
|
len);
|
|
}
|
|
}
|
|
if (reqP->GET_BOOTFILE_NAME) {
|
|
if (cfg->p_bootfile_name && *(cfg->p_bootfile_name)) {
|
|
len = strlen(cfg->p_bootfile_name);
|
|
encode_ptr_tag(&p, BOOTFILE_NAME_TAG, cfg->p_bootfile_name,
|
|
len);
|
|
}
|
|
}
|
|
|
|
if(msg) {
|
|
len = strlen(msg);
|
|
encode_ptr_tag(&p, DHCP_SERVER_MSG, msg, len);
|
|
}
|
|
|
|
*p = END_TAG;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int
|
|
sys0_addToHostsFile(u_long ipa, char *hname, char *nisdm)
|
|
{
|
|
FILE *fp;
|
|
struct in_addr ipn;
|
|
char *ipchar;
|
|
int rval;
|
|
|
|
if (dont_update_hosts)
|
|
return 0;
|
|
if(rval = sys0_removeFromHostsFile(ipa))
|
|
return(rval);
|
|
|
|
if(alt_hosts_file)
|
|
fp = log_fopen(alt_hosts_file, "a");
|
|
else
|
|
fp = log_fopen(RealHostFile, "a");
|
|
if(!fp)
|
|
return(1);
|
|
ipn.s_addr = ipa;
|
|
ipchar = inet_ntoa(ipn);
|
|
if (nisdm && *nisdm) {
|
|
if (fprintf(fp, "%s\t%s.%s\t%s\n", ipchar, hname, nisdm, hname) < 0) {
|
|
fclose(fp);
|
|
return(1);
|
|
}
|
|
}
|
|
else {
|
|
if (fprintf(fp, "%s\t%s\n", ipchar, hname) < 0) {
|
|
fclose(fp);
|
|
return(1);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return(0);
|
|
}
|
|
|
|
int
|
|
sys0_addToEthersFile(EtherAddr *eth, char *hname)
|
|
{
|
|
FILE *fp;
|
|
char *ebuf;
|
|
int rval;
|
|
|
|
if (dont_update_ethers)
|
|
return 0;
|
|
if (rval = sys0_removeFromEthersFile(eth))
|
|
return rval;
|
|
if(alt_ethers_file)
|
|
fp = log_fopen(alt_ethers_file, "a");
|
|
else
|
|
fp = log_fopen(RealEtherFile, "a");
|
|
if(!fp)
|
|
return(1);
|
|
ebuf = ether_ntoa(eth);
|
|
if (fprintf(fp, "%s\t%s\n", ebuf, hname) < 0) {
|
|
fclose(fp);
|
|
return(1);
|
|
}
|
|
fclose(fp);
|
|
return(0);
|
|
}
|
|
|
|
int
|
|
sys0_removeFromHostsFile(u_long ipaddr)
|
|
{
|
|
FILE *fp, *fp1;
|
|
char buf[256], zbuf[256];
|
|
u_long curip;
|
|
char *p;
|
|
|
|
if (dont_update_hosts)
|
|
return 0;
|
|
if(alt_hosts_file)
|
|
fp = log_fopen(alt_hosts_file, "r");
|
|
else
|
|
fp = log_fopen(RealHostFile, "r");
|
|
if(!fp)
|
|
return(1);
|
|
fp1 = log_fopen(tmpHostFile, "w");
|
|
if(!fp1) {
|
|
fclose(fp);
|
|
return(2);
|
|
}
|
|
|
|
while(fgets(buf, 256, fp) != NULL) {
|
|
if( (buf[0] == '\n') || (buf[0] == '#') ) {
|
|
if(efputs(buf, fp1)) {
|
|
fclose(fp);
|
|
fclose(fp1);
|
|
return(2);
|
|
}
|
|
continue;
|
|
}
|
|
if(isdigit(buf[0])) {
|
|
strcpy(zbuf, buf);
|
|
p = buf;
|
|
while( (*p != ' ') && (*p != '\t') )
|
|
p++;
|
|
*p = '\0';
|
|
curip = inet_addr(buf);
|
|
if(curip == ipaddr)
|
|
continue;
|
|
}
|
|
if (efputs(zbuf, fp1)) {
|
|
fclose(fp);
|
|
fclose(fp1);
|
|
return(2);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
fclose(fp1);
|
|
if(alt_hosts_file) {
|
|
if (erename(tmpHostFile, alt_hosts_file))
|
|
return 1;
|
|
}
|
|
else {
|
|
if (erename(tmpHostFile, RealHostFile))
|
|
return 1;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
int
|
|
sys0_removeFromEthersFile(EtherAddr *eth)
|
|
{
|
|
FILE *fp, *fp1;
|
|
char buf[256], hsname[64];
|
|
EtherAddr ehs;
|
|
int len;
|
|
int cr_found;
|
|
|
|
if (dont_update_ethers)
|
|
return 0;
|
|
if(alt_ethers_file)
|
|
fp = log_fopen(alt_ethers_file, "r");
|
|
else
|
|
fp = log_fopen(RealEtherFile, "r");
|
|
if(!fp)
|
|
return(1);
|
|
fp1 = log_fopen(tmpEtherFile, "w");
|
|
if(!fp1) {
|
|
fclose(fp);
|
|
return(2);
|
|
}
|
|
|
|
while(fgets(buf, 256, fp) != NULL) {
|
|
if( (buf[0] == '\n') || (buf[0] == '#') ) {
|
|
if (efputs(buf, fp1)) {
|
|
fclose(fp);
|
|
fclose(fp1);
|
|
return(2);
|
|
}
|
|
continue;
|
|
}
|
|
if(isxdigit(buf[0])) {
|
|
len = strlen(buf);
|
|
cr_found = 0;
|
|
if(buf[len-1] == '\n') {
|
|
buf[len-1] = '\0';
|
|
cr_found = 1;
|
|
}
|
|
if(ether_line(buf, &ehs, hsname) == 0) {
|
|
if(bcmp(ehs.ea_addr, eth->ea_addr, 6) == 0) {
|
|
cr_found = 0;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
if(cr_found) {
|
|
buf[len-1] = '\n';
|
|
cr_found = 0;
|
|
}
|
|
if (efputs(buf, fp1)) {
|
|
fclose(fp);
|
|
fclose(fp1);
|
|
return(2);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
fclose(fp1);
|
|
if(alt_ethers_file) {
|
|
if (erename(tmpEtherFile, alt_ethers_file))
|
|
return 1;
|
|
}
|
|
else {
|
|
if (erename(tmpEtherFile, RealEtherFile))
|
|
return 1;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
char *
|
|
sys0_name_errmsg(char *nm, int code)
|
|
{
|
|
char xbuf[256];
|
|
char *msg;
|
|
|
|
switch(code) {
|
|
case NAME_INVALID:
|
|
sprintf(xbuf, "%d:The selected hostname %s is not valid.",
|
|
NAME_INVALID, nm);
|
|
break;
|
|
case NAME_INUSE:
|
|
sprintf(xbuf, "%d:The selected hostname %s is already in use.",
|
|
NAME_INUSE, nm);
|
|
break;
|
|
default:
|
|
return (char *)0;
|
|
}
|
|
msg = strdup(xbuf);
|
|
return msg;
|
|
}
|
|
|
|
char *
|
|
sys0_addr_errmsg(u_long addr, int code)
|
|
{
|
|
char xbuf[256];
|
|
char *msg;
|
|
iaddr_t ipn;
|
|
|
|
ipn.s_addr = addr;
|
|
switch(code) {
|
|
case ADDR_INVALID:
|
|
sprintf(xbuf, "%d:The selected address %s is not served by this server.",
|
|
ADDR_INVALID, inet_ntoa(ipn));
|
|
break;
|
|
case ADDR_INUSE:
|
|
sprintf(xbuf, "%d:The selected address %s is already in use.",
|
|
ADDR_INUSE, inet_ntoa(ipn));
|
|
break;
|
|
default:
|
|
return (char *)0;
|
|
}
|
|
msg = strdup(xbuf);
|
|
return msg;
|
|
}
|
|
|
|
|
|
int
|
|
sys0_hostnameIsValid(char* hname)
|
|
{
|
|
char tn[255];
|
|
char c1, cn, c;
|
|
int len, i;
|
|
|
|
if(hname && (*hname == NULL))
|
|
return 0;
|
|
if((len = strlen(hname)) > MAXHOSTNAMELEN)
|
|
return 0;
|
|
strcpy(tn, hname);
|
|
c1 = tn[0];
|
|
cn = tn[len-1];
|
|
if(!isalpha(c1))
|
|
return 0;
|
|
if(!isalnum(cn))
|
|
return 0;
|
|
for(i=0; i < len; i++) {
|
|
c = tn[i];
|
|
if(isalnum(c) || (c == '.') || (c == '-') )
|
|
continue;
|
|
else
|
|
return 0;
|
|
}
|
|
for(i=1; i < len-2; i++) {
|
|
if( ((tn[i] == '.') || (tn[i] == '-')) &&
|
|
((tn[i+1] == '.') || (tn[i+1] == '-')) )
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
set_flag_state(char *fname, int fstate)
|
|
{
|
|
FILE *fp;
|
|
|
|
if ((fp = fopen(fname, "w")) == NULL)
|
|
return(1);
|
|
if (fstate == CHK_ON)
|
|
fwrite("on\n", 3, 1, fp);
|
|
else
|
|
fwrite("off\n", 4, 1, fp);
|
|
fclose(fp);
|
|
return(0);
|
|
}
|
|
|
|
static int
|
|
get_flag_state(char *namep)
|
|
{
|
|
char line[LINE_SIZE];
|
|
FILE *fp;
|
|
int state = CHK_OFF; /* assume off */
|
|
|
|
if ((fp = log_fopen(namep, "r")) == NULL) {
|
|
state = CHK_ERROR;
|
|
} else {
|
|
if ((fgets(line, LINE_SIZE, fp) != NULL) &&
|
|
(strncasecmp(line, "on", 2) == 0)) {
|
|
state = CHK_ON;
|
|
}
|
|
fclose(fp);
|
|
}
|
|
return(state);
|
|
}
|
|
|
|
int
|
|
chkconf(char *flag_file, char *flag_state)
|
|
{
|
|
char flag_name[LINE_SIZE];
|
|
int state;
|
|
|
|
if (flag_state == NULL) {
|
|
strcpy(flag_name, CONFIG_DIR);
|
|
strcat(flag_name, flag_file);
|
|
if(get_flag_state(flag_name) == CHK_ON) {
|
|
state = CHK_ON;
|
|
}
|
|
else {
|
|
state = CHK_OFF; /* it's off or can't read the file */
|
|
}
|
|
} else {
|
|
strcpy(flag_name, CONFIG_DIR);
|
|
strcat(flag_name, flag_file);
|
|
if (strncasecmp("on", flag_state, 2) == 0)
|
|
state = CHK_ON;
|
|
else if (strncasecmp("off", flag_state, 3) == 0)
|
|
state = CHK_OFF;
|
|
else {
|
|
fprintf(stderr,"Error: state can only be \"on\" or \"off\"\n");
|
|
state = CHK_OTHER;
|
|
}
|
|
if(set_flag_state(flag_name, state)) {
|
|
fprintf(stderr, "Error: cannot set flag \"%s\": %s\n",
|
|
flag_file, flag_state);
|
|
state = CHK_OTHER;
|
|
}
|
|
}
|
|
return(state);
|
|
}
|
|
|
|
/*
|
|
* Convert Ethernet address to printable representation.
|
|
*/
|
|
char *
|
|
ether_sprintf(u_char *ap)
|
|
{
|
|
char xbuf[64];
|
|
#define C(i) (*(ap+i) & 0xff)
|
|
sprintf(xbuf, "%x:%x:%x:%x:%x:%x\n", C(0), C(1), C(2), C(3), C(4), C(5));
|
|
#undef C
|
|
return xbuf;
|
|
}
|
|
|
|
int
|
|
cf0_encode_rfc1533_opts(u_char dhbuf[])
|
|
{
|
|
char *p, *q;
|
|
int i;
|
|
int tlen, len;
|
|
unsigned short tmpshort;
|
|
|
|
p = (char *)dhbuf;
|
|
|
|
if(rfc1533ptr->p_netmask)
|
|
encode_value_tag(&p, SUBNETMASK_TAG, rfc1533ptr->p_netmask, 4);
|
|
if(rfc1533ptr->p_time_offset)
|
|
encode_value_tag(&p, TIME_OFFSET_TAG, rfc1533ptr->p_time_offset, 4);
|
|
if(rfc1533ptr->p_router_addr)
|
|
encode_ptrvalue_array_tag(&p, ROUTER_TAG, rfc1533ptr->p_router_addr);
|
|
if(rfc1533ptr->p_tmsserver_addr)
|
|
encode_ptrvalue_array_tag(&p, TIMESERVERS_TAG,
|
|
rfc1533ptr->p_tmsserver_addr);
|
|
if(rfc1533ptr->p_nameserver116_addr)
|
|
encode_ptrvalue_array_tag(&p, NAME_SERVER116_TAG,
|
|
rfc1533ptr->p_nameserver116_addr);
|
|
if(rfc1533ptr->p_dnsserver_addr)
|
|
encode_ptrvalue_array_tag(&p, DNSSERVERS_TAG,
|
|
rfc1533ptr->p_dnsserver_addr);
|
|
if(rfc1533ptr->p_logserver_addr)
|
|
encode_ptrvalue_array_tag(&p, LOGSERVERS_TAG,
|
|
rfc1533ptr->p_logserver_addr);
|
|
if(rfc1533ptr->p_cookieserver_addr)
|
|
encode_ptrvalue_array_tag(&p, COOKIESERVERS_TAG,
|
|
rfc1533ptr->p_cookieserver_addr);
|
|
if(rfc1533ptr->p_LPRserver_addr)
|
|
encode_ptrvalue_array_tag(&p, LPRSERVERS_TAG,
|
|
rfc1533ptr->p_LPRserver_addr);
|
|
if(rfc1533ptr->p_impressserver_addr)
|
|
encode_ptrvalue_array_tag(&p, IMPRESSSERVERS_TAG,
|
|
rfc1533ptr->p_impressserver_addr);
|
|
if(rfc1533ptr->p_resourceserver_addr)
|
|
encode_ptrvalue_array_tag(&p, RESOURCESERVERS_TAG,
|
|
rfc1533ptr->p_resourceserver_addr);
|
|
if(rfc1533ptr->p_bootfile_size)
|
|
encode_value_tag(&p, BOOTFILE_SIZE_TAG, rfc1533ptr->p_bootfile_size, 2);
|
|
if(rfc1533ptr->p_merit_dump_pathname) {
|
|
if( rfc1533ptr->p_merit_dump_pathname &&
|
|
*(rfc1533ptr->p_merit_dump_pathname)) {
|
|
len = strlen(rfc1533ptr->p_merit_dump_pathname);
|
|
encode_ptr_tag(&p, MERITDUMP_FILE_TAG,
|
|
rfc1533ptr->p_merit_dump_pathname, len);
|
|
}
|
|
}
|
|
if(rfc1533ptr->p_dnsdomain) {
|
|
if(rfc1533ptr->p_dnsdomain && *(rfc1533ptr->p_dnsdomain)) {
|
|
len = strlen(rfc1533ptr->p_dnsdomain);
|
|
encode_ptr_tag(&p, DNSDOMAIN_NAME_TAG, rfc1533ptr->p_dnsdomain, len);
|
|
}
|
|
}
|
|
if(rfc1533ptr->p_swapserver_addr)
|
|
encode_value_tag(&p, SWAPSERVER_ADDRESS_TAG,
|
|
rfc1533ptr->p_swapserver_addr, 4);
|
|
if(rfc1533ptr->p_root_disk_pathname) {
|
|
if( rfc1533ptr->p_root_disk_pathname &&
|
|
*(rfc1533ptr->p_root_disk_pathname)) {
|
|
len = strlen(rfc1533ptr->p_root_disk_pathname);
|
|
encode_ptr_tag(&p, ROOT_PATH_TAG,
|
|
rfc1533ptr->p_root_disk_pathname, len);
|
|
}
|
|
}
|
|
if(rfc1533ptr->p_extensions_pathname) {
|
|
if( rfc1533ptr->p_root_disk_pathname &&
|
|
*(rfc1533ptr->p_root_disk_pathname)) {
|
|
len = strlen(rfc1533ptr->p_root_disk_pathname);
|
|
encode_ptr_tag(&p, ROOT_PATH_TAG,
|
|
rfc1533ptr->p_root_disk_pathname, len);
|
|
}
|
|
}
|
|
if(rfc1533ptr->p_IPforwarding)
|
|
encode_value_tag(&p, IP_FORWARDING_TAG, rfc1533ptr->p_IPforwarding, 1);
|
|
if(rfc1533ptr->p_source_routing)
|
|
encode_value_tag(&p, NON_LOCAL_SRC_ROUTE_TAG,
|
|
rfc1533ptr->p_source_routing, 1);
|
|
if(rfc1533ptr->p_policy_filter) {
|
|
tlen = 0;
|
|
*p++ = POLICY_FILTER_TAG;
|
|
q = p++;
|
|
i = 0;
|
|
while(rfc1533ptr->p_policy_filter[i].r_dest &&
|
|
rfc1533ptr->p_routes[i].r_router) {
|
|
bcopy(&rfc1533ptr->p_policy_filter[i].r_dest, p, 4); /* address */
|
|
p += 4;
|
|
bcopy(&rfc1533ptr->p_policy_filter[i].r_router, p, 4); /* mask */
|
|
p += 4;
|
|
tlen += 8;
|
|
i++;
|
|
}
|
|
*q = tlen;
|
|
}
|
|
if(rfc1533ptr->p_max_reassy_size)
|
|
encode_value_tag(&p, MAX_DGRAM_REASSEMBL_TAG,
|
|
rfc1533ptr->p_max_reassy_size, 2);
|
|
if(rfc1533ptr->p_IP_ttl)
|
|
encode_value_tag(&p, DEF_IP_TIME_LIVE_TAG, rfc1533ptr->p_IP_ttl, 1);
|
|
if(rfc1533ptr->p_pathmtu_timeout)
|
|
encode_value_tag(&p, PATH_MTU_AGE_TMOUT_TAG,
|
|
rfc1533ptr->p_pathmtu_timeout, 4);
|
|
if(rfc1533ptr->p_pathmtu_table) {
|
|
tlen = 0;
|
|
*p++ = PATH_MTU_PLT_TABLE_TAG;
|
|
q = p++;
|
|
i = 0;
|
|
while (tmpshort = rfc1533ptr->p_pathmtu_table[i]) {
|
|
bcopy(&tmpshort, p, 2);
|
|
p += 1;
|
|
tlen += 2;
|
|
i++;
|
|
}
|
|
*q = tlen;
|
|
}
|
|
if(rfc1533ptr->p_mtu)
|
|
encode_value_tag(&p, IF_MTU_TAG, rfc1533ptr->p_mtu, 2);
|
|
if(rfc1533ptr->p_allnetsloc)
|
|
encode_value_tag(&p, ALL_SUBNETS_LOCAL_TAG, 1, 1);
|
|
if(rfc1533ptr->p_broadcast)
|
|
encode_value_tag(&p, BROADCAST_ADDRESS_TAG, rfc1533ptr->p_broadcast, 4);
|
|
if(rfc1533ptr->p_domaskdisc)
|
|
encode_value_tag(&p, CLIENT_MASK_DISC_TAG, 1, 1);
|
|
if(rfc1533ptr->p_respmaskreq)
|
|
encode_value_tag(&p, MASK_SUPPLIER_TAG, 1, 1);
|
|
if(rfc1533ptr->p_router_disc)
|
|
encode_value_tag(&p, ROUTER_DISC_TAG, rfc1533ptr->p_router_disc, 1);
|
|
if(rfc1533ptr->p_router_solicit_addr)
|
|
encode_value_tag(&p, ROUTER_SOLICIT_ADDR_TAG,
|
|
rfc1533ptr->p_router_solicit_addr, 4);
|
|
if(rfc1533ptr->p_routes) {
|
|
tlen = 0;
|
|
*p++ = STATIC_ROUTE_TAG;
|
|
q = p++;
|
|
i = 0;
|
|
while(rfc1533ptr->p_routes[i].r_dest &&
|
|
rfc1533ptr->p_routes[i].r_router) {
|
|
bcopy(&rfc1533ptr->p_routes[i].r_dest, p, 4);
|
|
p += 4;
|
|
bcopy(&rfc1533ptr->p_routes[i].r_router, p, 4);
|
|
p += 4;
|
|
tlen += 8;
|
|
i++;
|
|
}
|
|
*q = tlen;
|
|
}
|
|
if(rfc1533ptr->p_trailer_encaps)
|
|
encode_value_tag(&p, TRAILER_ENCAPS_TAG,
|
|
rfc1533ptr->p_trailer_encaps, 1);
|
|
if(rfc1533ptr->p_arpcache_timeout)
|
|
encode_value_tag(&p, ARP_CACHE_TIMEOUT_TAG,
|
|
rfc1533ptr->p_arpcache_timeout, 4);
|
|
if(rfc1533ptr->p_ether_encaps)
|
|
encode_value_tag(&p, ETHERNET_ENCAPS_TAG, rfc1533ptr->p_ether_encaps, 1);
|
|
if(rfc1533ptr->p_TCP_ttl)
|
|
encode_value_tag(&p, TCP_DEFAULT_TTL_TAG, rfc1533ptr->p_TCP_ttl, 1);
|
|
if(rfc1533ptr->p_TCP_keepalive_intrvl)
|
|
encode_value_tag(&p, TCP_KEEPALIVE_INTVL_TAG,
|
|
rfc1533ptr->p_TCP_keepalive_intrvl, 4);
|
|
if(rfc1533ptr->p_TCP_keepalive_garbage)
|
|
encode_value_tag(&p, TCP_KEEPALIVE_GARBG_TAG,
|
|
rfc1533ptr->p_TCP_keepalive_garbage, 1);
|
|
if(rfc1533ptr->p_nisdomain) {
|
|
if(rfc1533ptr->p_nisdomain && *(rfc1533ptr->p_nisdomain)) {
|
|
len = strlen(rfc1533ptr->p_nisdomain);
|
|
encode_ptr_tag(&p, NISDOMAIN_NAME_TAG, rfc1533ptr->p_nisdomain, len);
|
|
}
|
|
}
|
|
if(rfc1533ptr->p_nisserver_addr)
|
|
encode_ptrvalue_array_tag(&p, NIS_SERVERS_TAG,
|
|
rfc1533ptr->p_nisserver_addr);
|
|
if(rfc1533ptr->p_NTPserver_addr)
|
|
encode_ptrvalue_array_tag(&p, NTP_SERVERS_TAG,
|
|
rfc1533ptr->p_NTPserver_addr);
|
|
if(rfc1533ptr->p_NetBIOS_nameserver_addr)
|
|
encode_ptrvalue_array_tag(&p, NETBIOS_NMSERV_ADDR_TAG,
|
|
rfc1533ptr->p_NetBIOS_nameserver_addr);
|
|
if(rfc1533ptr->p_NetBIOS_distrserver_addr)
|
|
encode_ptrvalue_array_tag(&p, NETBIOS_DISTR_ADDR_TAG,
|
|
rfc1533ptr->p_NetBIOS_distrserver_addr);
|
|
if(rfc1533ptr->p_NetBIOS_nodetype)
|
|
encode_value_tag(&p, NETBIOS_NODETYPE_TAG,
|
|
rfc1533ptr->p_NetBIOS_nodetype, 1);
|
|
if(rfc1533ptr->p_NetBIOS_scope) {
|
|
if(rfc1533ptr->p_NetBIOS_scope && *(rfc1533ptr->p_NetBIOS_scope)) {
|
|
len = strlen(rfc1533ptr->p_NetBIOS_scope);
|
|
encode_ptr_tag(&p, NETBIOS_SCOPE_TAG,
|
|
rfc1533ptr->p_NetBIOS_scope, len);
|
|
}
|
|
}
|
|
if(rfc1533ptr->p_X_fontserver_addr)
|
|
encode_ptrvalue_array_tag(&p, X_FONTSERVER_ADDR_TAG,
|
|
rfc1533ptr->p_X_fontserver_addr);
|
|
if(rfc1533ptr->p_X_displaymgr_addr)
|
|
encode_ptrvalue_array_tag(&p, X_DISPLAYMGR_ADDR_TAG,
|
|
rfc1533ptr->p_X_displaymgr_addr);
|
|
if(rfc1533ptr->p_nisplusdomain) {
|
|
if(rfc1533ptr->p_nisplusdomain && *(rfc1533ptr->p_nisplusdomain)) {
|
|
len = strlen(rfc1533ptr->p_nisplusdomain);
|
|
encode_ptr_tag(&p, NISPLUS_DOMAIN_TAG,
|
|
rfc1533ptr->p_nisplusdomain, len);
|
|
}
|
|
}
|
|
if(rfc1533ptr->p_nisplusserver_addr)
|
|
encode_ptrvalue_array_tag(&p, NISPLUS_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_nisplusserver_addr);
|
|
if(rfc1533ptr->p_mobileIP_homeagent_addr)
|
|
encode_ptrvalue_array_tag(&p, MBLEIP_HMAGENT_ADDR_TAG,
|
|
rfc1533ptr->p_mobileIP_homeagent_addr);
|
|
if(rfc1533ptr->p_SMTPserver_addr)
|
|
encode_ptrvalue_array_tag(&p, SMTP_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_SMTPserver_addr);
|
|
if(rfc1533ptr->p_POP3server_addr)
|
|
encode_ptrvalue_array_tag(&p, POP3_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_POP3server_addr);
|
|
if(rfc1533ptr->p_NNTPserver_addr)
|
|
encode_ptrvalue_array_tag(&p, NNTP_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_NNTPserver_addr);
|
|
if(rfc1533ptr->p_WWWserver_addr)
|
|
encode_ptrvalue_array_tag(&p, WWW_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_WWWserver_addr);
|
|
if(rfc1533ptr->p_fingerserver_addr)
|
|
encode_ptrvalue_array_tag(&p, FINGER_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_fingerserver_addr);
|
|
if(rfc1533ptr->p_IRCserver_addr)
|
|
encode_ptrvalue_array_tag(&p, IRC_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_IRCserver_addr);
|
|
if(rfc1533ptr->p_StreetTalkserver_addr)
|
|
encode_ptrvalue_array_tag(&p, STTALK_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_StreetTalkserver_addr);
|
|
if(rfc1533ptr->p_STDAserver_addr)
|
|
encode_ptrvalue_array_tag(&p, STDA_SERVER_ADDR_TAG,
|
|
rfc1533ptr->p_STDAserver_addr);
|
|
*p = END_TAG;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* error checking fputs
|
|
* return 0 if no error otherwise 1
|
|
* fputs does not check/set errno hence using fwrite
|
|
*/
|
|
|
|
int efputs(char *buf, FILE *fp)
|
|
{
|
|
if (fwrite(buf, strlen(buf), 1, fp) != 1) {
|
|
syslog(LOG_ERR, "File write error %s", strerror(errno));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/*
|
|
* error checking rename
|
|
* return 0 if no error otherwise 1
|
|
* fputs does not check/set errno hence using fwrite
|
|
*/
|
|
|
|
int erename(char *old, char *new)
|
|
{
|
|
if (rename(old, new) < 0) {
|
|
syslog(LOG_ERR, "Rename error %s", strerror(errno));
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void setparams( struct getParams *reqParams, int len, u_char *p)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0; i < len; i++) {
|
|
switch(*p++) {
|
|
case IP_LEASE_TIME_TAG:
|
|
reqParams->GET_IPLEASE_TIME = 1;
|
|
break;
|
|
case SUBNETMASK_TAG:
|
|
reqParams->GET_SUBNETMASK = 1;
|
|
break;
|
|
case HOSTNAME_TAG:
|
|
reqParams->GET_HOSTNAME = 1;
|
|
break;
|
|
case NISDOMAIN_NAME_TAG:
|
|
reqParams->GET_NISDOMAIN = 1;
|
|
break;
|
|
case DNSDOMAIN_NAME_TAG:
|
|
reqParams->GET_DNSDOMAIN = 1;
|
|
break;
|
|
case DHCP_SERVER_TAG:
|
|
reqParams->GET_DHCP_SERVER = 1;
|
|
break;
|
|
case RESOLVE_HOSTNAME_TAG:
|
|
reqParams->RESOLVE_HOSTNAME = 1;
|
|
break;
|
|
case SDIST_SERVER_TAG:
|
|
reqParams->GET_SDIST_SERVER = 1;
|
|
break;
|
|
case IPADDR_TAG:
|
|
reqParams->GET_IPADDRESS = 1;
|
|
break;
|
|
case ROUTER_TAG:
|
|
reqParams->GET_ROUTER = 1;
|
|
break;
|
|
case TIMESERVERS_TAG:
|
|
reqParams->GET_TIMESERVERS = 1;
|
|
break;
|
|
case DNSSERVERS_TAG:
|
|
reqParams->GET_DNSSERVERS = 1;
|
|
break;
|
|
case NIS_SERVERS_TAG:
|
|
reqParams->GET_NIS_SERVERS = 1;
|
|
break;
|
|
case IF_MTU_TAG:
|
|
reqParams->GET_IF_MTU = 1;
|
|
break;
|
|
case ALL_SUBNETS_LOCAL_TAG:
|
|
reqParams->GET_ALL_SUBNETS_LOCAL = 1;
|
|
break;
|
|
case BROADCAST_ADDRESS_TAG:
|
|
reqParams->GET_BROADCAST_ADDRESS = 1;
|
|
break;
|
|
case CLIENT_MASK_DISC_TAG:
|
|
reqParams->GET_CLIENT_MASK_DISC = 1;
|
|
break;
|
|
case MASK_SUPPLIER_TAG:
|
|
reqParams->GET_MASK_SUPPLIER = 1;
|
|
break;
|
|
case STATIC_ROUTE_TAG:
|
|
reqParams->GET_STATIC_ROUTE = 1;
|
|
break;
|
|
case OPTION_OVERLOAD_TAG:
|
|
reqParams->HAS_OPTION_OVERLOAD = 1;
|
|
break;
|
|
case MAX_DHCP_MSG_SIZE_TAG:
|
|
reqParams->HAS_MAX_DHCP_MSG_SIZE = 1;
|
|
break;
|
|
case RENEW_LEASE_TIME_TAG:
|
|
reqParams->GET_RENEW_LEASE_TIME = 1;
|
|
break;
|
|
case REBIND_LEASE_TIME_TAG:
|
|
reqParams->GET_REBIND_LEASE_TIME = 1;
|
|
break;
|
|
case LOGSERVERS_TAG:
|
|
reqParams->GET_LOGSERVERS = 1;
|
|
break;
|
|
case COOKIESERVERS_TAG:
|
|
reqParams->GET_COOKIESERVERS = 1;
|
|
break;
|
|
case LPRSERVERS_TAG:
|
|
reqParams->GET_LPRSERVERS = 1;
|
|
break;
|
|
case RESOURCESERVERS_TAG:
|
|
reqParams->GET_RESOURCESERVERS = 1;
|
|
break;
|
|
case BOOTFILE_SIZE_TAG:
|
|
reqParams->GET_BOOTFILE_SIZE = 1;
|
|
break;
|
|
case SWAPSERVER_ADDRESS_TAG:
|
|
reqParams->GET_SWAPSERVER_ADDRESS = 1;
|
|
break;
|
|
case IP_FORWARDING_TAG:
|
|
reqParams->GET_IP_FORWARDING = 1;
|
|
break;
|
|
case NON_LOCAL_SRC_ROUTE_TAG:
|
|
reqParams->GET_NON_LOCAL_SRC_ROUTE = 1;
|
|
break;
|
|
case POLICY_FILTER_TAG:
|
|
reqParams->GET_POLICY_FILTER = 1;
|
|
break;
|
|
case MAX_DGRAM_REASSEMBL_TAG:
|
|
reqParams->GET_MAX_DGRAM_REASSEMBL = 1;
|
|
break;
|
|
case DEF_IP_TIME_LIVE_TAG:
|
|
reqParams->GET_DEF_IP_TIME_LIVE = 1;
|
|
break;
|
|
case PATH_MTU_AGE_TMOUT_TAG:
|
|
reqParams->GET_PATH_MTU_AGE_TMOUT = 1;
|
|
break;
|
|
case PATH_MTU_PLT_TABLE_TAG:
|
|
reqParams->GET_PATH_MTU_PLT_TABLE = 1;
|
|
break;
|
|
case ROUTER_DISC_TAG:
|
|
reqParams->GET_ROUTER_DISC = 1;
|
|
break;
|
|
case ROUTER_SOLICIT_ADDR_TAG:
|
|
reqParams->GET_ROUTER_SOLICIT_ADDR = 1;
|
|
break;
|
|
case TRAILER_ENCAPS_TAG:
|
|
reqParams->GET_TRAILER_ENCAPS = 1;
|
|
break;
|
|
case ARP_CACHE_TIMEOUT_TAG:
|
|
reqParams->GET_ARP_CACHE_TIMEOUT = 1;
|
|
break;
|
|
case ETHERNET_ENCAPS_TAG:
|
|
reqParams->GET_ETHERNET_ENCAPS = 1;
|
|
break;
|
|
case TCP_DEFAULT_TTL_TAG:
|
|
reqParams->GET_TCP_DEFAULT_TTL = 1;
|
|
break;
|
|
case TCP_KEEPALIVE_INTVL_TAG:
|
|
reqParams->GET_TCP_KEEPALIVE_INTVL = 1;
|
|
break;
|
|
case TCP_KEEPALIVE_GARBG_TAG:
|
|
reqParams->GET_TCP_KEEPALIVE_GARBG = 1;
|
|
break;
|
|
case NETBIOS_NMSERV_ADDR_TAG:
|
|
reqParams->GET_NETBIOS_NMSERV_ADDR = 1;
|
|
break;
|
|
case NETBIOS_DISTR_ADDR_TAG:
|
|
reqParams->GET_NETBIOS_DISTR_ADDR = 1;
|
|
break;
|
|
case NETBIOS_NODETYPE_TAG:
|
|
reqParams->GET_NETBIOS_NODETYPE = 1;
|
|
break;
|
|
case NETBIOS_SCOPE_TAG:
|
|
reqParams->GET_NETBIOS_SCOPE = 1;
|
|
break;
|
|
case X_FONTSERVER_ADDR_TAG:
|
|
reqParams->GET_X_FONTSERVER_ADDR = 1;
|
|
break;
|
|
case X_DISPLAYMGR_ADDR_TAG:
|
|
reqParams->GET_X_DISPLAYMGR_ADDR = 1;
|
|
break;
|
|
case NISPLUS_DOMAIN_TAG:
|
|
reqParams->GET_NISPLUS_DOMAIN = 1;
|
|
break;
|
|
case NISPLUS_SERVER_ADDR_TAG:
|
|
reqParams->GET_NISPLUS_SERVER_ADDR = 1;
|
|
break;
|
|
case MBLEIP_HMAGENT_ADDR_TAG:
|
|
reqParams->GET_MBLEIP_HMAGENT_ADDR = 1;
|
|
break;
|
|
case SMTP_SERVER_ADDR_TAG:
|
|
reqParams->GET_SMTP_SERVER_ADDR = 1;
|
|
break;
|
|
case POP3_SERVER_ADDR_TAG:
|
|
reqParams->GET_POP3_SERVER_ADDR = 1;
|
|
break;
|
|
case NNTP_SERVER_ADDR_TAG:
|
|
reqParams->GET_NNTP_SERVER_ADDR = 1;
|
|
break;
|
|
case WWW_SERVER_ADDR_TAG:
|
|
reqParams->GET_WWW_SERVER_ADDR = 1;
|
|
break;
|
|
case FINGER_SERVER_ADDR_TAG:
|
|
reqParams->GET_FINGER_SERVER_ADDR = 1;
|
|
break;
|
|
case IRC_SERVER_ADDR_TAG:
|
|
reqParams->GET_IRC_SERVER_ADDR = 1;
|
|
break;
|
|
case STTALK_SERVER_ADDR_TAG:
|
|
reqParams->GET_STTALK_SERVER_ADDR = 1;
|
|
break;
|
|
case STDA_SERVER_ADDR_TAG:
|
|
reqParams->GET_STDA_SERVER_ADDR = 1;
|
|
break;
|
|
case TIME_OFFSET_TAG:
|
|
reqParams->GET_TIME_OFFSET = 1;
|
|
break;
|
|
case NAME_SERVER116_TAG:
|
|
reqParams->GET_NAMESERVER116_ADDR = 1;
|
|
break;
|
|
case IMPRESSSERVERS_TAG:
|
|
reqParams->GET_IMPRESS_SERVER_ADDR = 1;
|
|
break;
|
|
case MERITDUMP_FILE_TAG:
|
|
reqParams->GET_MERITDUMP_FILE = 1;
|
|
break;
|
|
case ROOT_PATH_TAG:
|
|
reqParams->GET_ROOT_PATH = 1;
|
|
break;
|
|
case EXTENSIONS_PATH_TAG:
|
|
reqParams->GET_EXTENSIONS = 1;
|
|
break;
|
|
case NTP_SERVERS_TAG:
|
|
reqParams->GET_NTP_SERVER_ADDR = 1;
|
|
break;
|
|
case TFTP_SERVER_NAME_TAG:
|
|
reqParams->GET_TFTP_SERVER_NAME = 1;
|
|
break;
|
|
case BOOTFILE_NAME_TAG:
|
|
reqParams->GET_BOOTFILE_NAME = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
set_addl_options_to_send(char *pstr)
|
|
{
|
|
int tmp;
|
|
|
|
pstr = strtok(pstr, ":,");
|
|
addl_options_len = 0;
|
|
while (pstr) {
|
|
sscanf(pstr, " %d", &tmp);
|
|
addl_options_to_send[addl_options_len] = (char)tmp;
|
|
addl_options_len++;
|
|
pstr = strtok(0, ":,");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Append the client fqdn onto the DHCPACK reply
|
|
* Its is not possible to do this in the encode function because the
|
|
* DNS may have to be update and the return codes are needed
|
|
*/
|
|
int
|
|
dh0_append_client_fqdn(u_char dhbuf[], char *client_fqdn)
|
|
{
|
|
/* find the end of the options by walking down */
|
|
u_char *p = dhbuf;
|
|
u_char *p_end = p + DHCP_OPTS_SIZE;
|
|
int len;
|
|
|
|
/* skip until end */
|
|
while ( (p < p_end) && (*p != END_TAG) ) {
|
|
switch (*p++) {
|
|
case PAD_TAG:
|
|
continue;
|
|
default:
|
|
len = *p++;
|
|
p += len;
|
|
continue;
|
|
}
|
|
}
|
|
if (*p != END_TAG) {
|
|
syslog(LOG_ERR, "Did not find end tag when adding the client_fqdn");
|
|
return 1;
|
|
}
|
|
/* encode client fqdn */
|
|
if ( (*client_fqdn != NULL) ) {
|
|
len = 4 + strlen(client_fqdn+3);
|
|
encode_ptr_tag((char **)&p, CLIENT_FQDN_TAG, client_fqdn, len);
|
|
}
|
|
|
|
*p = END_TAG;
|
|
|
|
return 0;
|
|
}
|