1
0
Files
irix-657m-src/eoe/cmd/dhcp_server/dhcpfuncs.c
2022-09-29 17:59:04 +03:00

482 lines
12 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/types.h>
#include <net/if.h>
#include <netinet/in.h>
#include "dhcp.h"
#include "dhcpdefs.h"
#include <strings.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <ndbm.h>
#include <syslog.h>
extern char *ether_ntoa(EtherAddr *);
extern struct dhcp_request_list *dhcp_rlist;
extern struct dhcp_timelist *dhcp_tmlist_first;
extern struct dhcp_timelist *dhcp_tmlist_last;
extern char *myname;
extern int dh0_timeouts_cnt;
extern int ping_number_pending;
extern int getdomainname(char *, int);
extern int sys0_addToHostsFile(u_long, char *, char *);
extern int sys0_addToEthersFile(EtherAddr *, char *);
extern u_long loc0_get_ipaddr_from_cid(EtherAddr *, char *, int, DBM *);
extern int sys0_removeFromHostsFile(u_long);
extern int sys0_removeFromEthersFile(EtherAddr *);
char *dh0_getNisDomain(void);
int dh0_create_system_mapping(u_long, EtherAddr *, char *, char *);
int dh0_remove_system_mapping(char *, EtherAddr *, int, DBM *);
char *dh0_getDnsDomain(void);
u_long *dh0_get_dnsServers(void);
struct dhcp_request_list*
dh0_add_to_dhcp_reqlist(char *, int, EtherAddr *, u_long, char *,
struct getParams *, u_long, u_int,
dhcpConfig *, ping_status_t, int, int,
char *, int, struct bootp*, struct bootp*,
struct dhcp_client_info*);
int dh0_upd_dhcp_rq_entry(struct dhcp_request_list *,
struct getParams *, u_int);
int dh0_remove_from_dhcp_reqlist(char *, int);
int dh0_addto_timelist(char *, int, EtherAddr *, time_t,
struct dhcp_request_list*);
int dh0_free_timelist_entry(struct dhcp_timelist *);
int dh0_remove_from_timelist(char *, int);
int dh0_set_timeval(struct timeval *, long);
long dh0_update_and_get_next_timeout(time_t);
struct dhcp_timelist *dh0_find_timelist_entry(char *, int);
struct dhcp_timelist *dh0_pop_timelist_timer(void);
struct dhcp_request_list *dh0_find_dhcp_rqlist_entry(char *, int);
static int free_dhcp_rq(struct dhcp_request_list *);
extern ping_send_DHCPOFFER(struct dhcp_request_list*);
char *
dh0_getNisDomain(void)
{
char dmname[64];
char *dm;
if(getdomainname(dmname, sizeof(dmname)) == 0) {
if(dmname[0] == '\0') {
return (char *)0;
}
else {
dm = strdup(dmname);
return(dm);
}
}
return (char *)0;
}
/* Add entry to the /etc/hosts and /etc/ethers files */
int
dh0_create_system_mapping(u_long ipaddr, EtherAddr *eth, char *hsname, char *nisdm)
{
int rval;
rval = sys0_addToHostsFile(ipaddr, hsname, nisdm);
if(rval){
return(1);
}
rval = sys0_addToEthersFile(eth, hsname);
if(rval){
return(2);
}
return(0);
}
/* Delete the entry from the /etc/hosts and /etc/ethers files */
int
dh0_remove_system_mapping(char *cid_ptr, EtherAddr *eth, int cid_length,
DBM *db)
{
int rval;
u_long addrfromCid;
addrfromCid = loc0_get_ipaddr_from_cid(eth, cid_ptr, cid_length, db);
if(addrfromCid == 0)
return 1;
rval = sys0_removeFromHostsFile(addrfromCid);
if(rval)
return rval;
rval = sys0_removeFromEthersFile(eth);
return rval;
}
char *
dh0_getDnsDomain(void)
{
char *dm;
res_init();
dm = _res.defdname;
if((dm == 0) || (*dm == '\0'))
return (char *)0;
dm = strdup(_res.defdname);
return dm;
}
u_long *
dh0_get_dnsServers(void)
{
u_long *dnssrvs;
int i;
res_init();
if(_res.nscount == 0)
return 0;
dnssrvs = (u_long *)malloc(sizeof(u_long) * (_res.nscount + 1));
for(i = 0; i < _res.nscount; i++)
dnssrvs[i] = _res.nsaddr_list[i].sin_addr.s_addr;
dnssrvs[i] = 0;
return dnssrvs;
}
struct dhcp_request_list*
dh0_add_to_dhcp_reqlist(char *cid_ptr, int cid_length, EtherAddr *ead,
u_long ipa, char *hsname, struct getParams *reqparams,
u_long srv, u_int lease, dhcpConfig *cfg,
ping_status_t ping_stat, int ident, int seqnum,
char *dh_msg, int has_sname,
struct bootp* pingrp, struct bootp* pingrq,
struct dhcp_client_info *dcip_data)
{
struct dhcp_request_list *rq;
/* check whether an entry exists to avoid duplicates */
if (rq = dh0_find_dhcp_rqlist_entry(cid_ptr, cid_length)) {
bcopy(cid_ptr, rq->cid_ptr, cid_length);
/*rq->cid_ptr = strdup(cid_ptr); */
rq->cid_length = cid_length;
rq->dh_ipaddr = ipa;
if (rq->dh_hsname)
free(rq->dh_hsname);
if(hsname)
rq->dh_hsname = strdup(hsname);
else
rq->dh_hsname = 0;
bcopy(reqparams, &rq->dh_reqParams, sizeof(struct getParams));
rq->dh_reqServer = srv;
rq->dh_reqLease = lease;
rq->dh_configPtr = cfg;
rq->ping_status = ping_stat;
if (ping_stat == PING_SENT) {
memcpy(&rq->ping_rp, pingrp, sizeof (struct bootp));
memcpy(&rq->ping_rq, pingrq, sizeof (struct bootp));
rq->ping_seqnum = seqnum;
rq->ping_ident = ident;
rq->ping_dh_msg = dh_msg;
rq->ping_has_sname = has_sname;
if (dcip_data)
memcpy(&rq->dci_data, dcip_data,
sizeof( struct dhcp_client_info));
else
bzero(&rq->dci_data, sizeof(struct dhcp_client_info));
}
return rq;
}
rq = (struct dhcp_request_list *)malloc(sizeof (struct dhcp_request_list));
if (rq == (struct dhcp_request_list*)0)
return 0;
rq->cid_ptr = (char *)malloc(cid_length);
if (rq->cid_ptr == (char*)0) {
free(rq);
return 0;
}
bcopy(cid_ptr, rq->cid_ptr, cid_length);
rq->cid_length = cid_length;
rq->dh_eaddr = (EtherAddr *)malloc(sizeof (EtherAddr));
bcopy(ead->ea_addr, rq->dh_eaddr->ea_addr, 6);
rq->dh_ipaddr = ipa;
if(hsname)
rq->dh_hsname = strdup(hsname);
else
rq->dh_hsname = 0;
bcopy(reqparams, &rq->dh_reqParams, sizeof(struct getParams));
rq->dh_reqServer = srv;
rq->dh_reqLease = lease;
rq->dh_configPtr = cfg;
rq->ping_status = ping_stat;
if (ping_stat == PING_SENT) {
memcpy(&rq->ping_rp, pingrp, sizeof (struct bootp));
memcpy(&rq->ping_rq, pingrq, sizeof (struct bootp));
rq->ping_seqnum = seqnum;
rq->ping_ident = ident;
rq->ping_dh_msg = dh_msg;
rq->ping_has_sname = has_sname;
if (dcip_data)
memcpy(&rq->dci_data, dcip_data, sizeof( struct dhcp_client_info));
else
bzero(&rq->dci_data, sizeof(struct dhcp_client_info));
}
rq->dh_prev = 0;
rq->dh_next = 0;
if(dhcp_rlist) {
dhcp_rlist->dh_prev = rq;
rq->dh_next = dhcp_rlist;
}
dhcp_rlist = rq;
return rq;
}
int
dh0_upd_dhcp_rq_entry(struct dhcp_request_list* rq,
struct getParams *reqparams, u_int lease)
{
bcopy(reqparams, &rq->dh_reqParams, sizeof(struct getParams));
rq->dh_reqLease = lease;
return 0;
}
static int
free_dhcp_rq(struct dhcp_request_list *rq)
{
if(rq->dh_hsname)
free(rq->dh_hsname);
free(rq->dh_eaddr);
free(rq->cid_ptr);
free(rq);
return 0;
}
int
dh0_remove_from_dhcp_reqlist(char *cid_ptr, int cid_length)
{
struct dhcp_request_list *rq, *pq;
rq = dhcp_rlist;
if(!rq)
return 1;
while(rq) {
if((cid_length == rq->cid_length) &&
(bcmp(rq->cid_ptr, cid_ptr, cid_length) == 0)) {
pq = rq->dh_prev;
if(pq) {
pq->dh_next = rq->dh_next;
if(rq->dh_next)
rq->dh_next->dh_prev = pq;
}
else {
dhcp_rlist = rq->dh_next;
if(dhcp_rlist)
dhcp_rlist->dh_prev = 0;
}
free_dhcp_rq(rq);
return 0;
}
rq = rq->dh_next;
}
return 0; /* XXX error condition ??? */
}
struct dhcp_request_list *
dh0_find_dhcp_rqlist_entry(char *cid_ptr, int cid_length)
{
struct dhcp_request_list *rq;
rq = dhcp_rlist;
if(!rq)
return 0;
while(rq) {
/*syslog(LOG_DEBUG,"Request list entry:cid = %s",rq->cid_ptr);*/
if (cid_length == rq->cid_length) {
if(bcmp(rq->cid_ptr, cid_ptr, cid_length) == 0)
return rq;
}
rq = rq->dh_next;
}
return 0;
}
struct dhcp_request_list *
dh0_find_dhcp_rqlist_entry_by_ipaddr(u_long ipaddr)
{
struct dhcp_request_list *rq;
rq = dhcp_rlist;
if(!rq)
return 0;
while(rq) {
if (ipaddr == rq->dh_ipaddr)
return rq;
rq = rq->dh_next;
}
return 0;
}
int
dh0_addto_timelist(char *cid_ptr, int cid_length, EtherAddr *ead, time_t tval,
struct dhcp_request_list *dhcp_rq)
{
struct dhcp_timelist *tmq, *pmq;
/* check whether there exists an entry to avoid duplicates */
if (tmq = dh0_find_timelist_entry(cid_ptr,cid_length)) {
tmq->tm_value = tval;
if (tmq->tm_dhcp_rq && (tmq->tm_dhcp_rq->ping_status == PING_SENT))
ping_number_pending--;
if (dhcp_rq && (dhcp_rq->ping_status == PING_SENT))
ping_number_pending++;
/* printf("UPD: tq=0x%x, dhcp_rq=0x%x(0x%x), ping_status=%d(%d), number=%d(%d)\n",
tmq, tmq->tm_dhcp_rq, dhcp_rq,
(tmq->tm_dhcp_rq)?tmq->tm_dhcp_rq->ping_status: -1,
(dhcp_rq)?dhcp_rq->ping_status: -1, ping_number_pending,
dh0_timeouts_cnt); */
tmq->tm_dhcp_rq = dhcp_rq;
return 0; /* update existing entry */
}
tmq = (struct dhcp_timelist *)malloc(sizeof (struct dhcp_timelist));
tmq->cid_ptr = (char *)malloc(cid_length);
if (cid_ptr != 0)
bcopy(cid_ptr,tmq->cid_ptr,cid_length);
tmq->cid_length = cid_length;
tmq->tm_eaddr = (EtherAddr *)malloc(sizeof (EtherAddr));
if(ead != 0)
bcopy(ead->ea_addr, tmq->tm_eaddr->ea_addr, 6);
tmq->tm_value = tval;
tmq->tm_dhcp_rq = dhcp_rq;
tmq->tm_prev = 0;
tmq->tm_next = 0;
if (dhcp_rq && (dhcp_rq->ping_status == PING_SENT))
ping_number_pending++;
if(dhcp_tmlist_last) {
pmq = dhcp_tmlist_last->tm_prev;
dhcp_tmlist_last->tm_prev = tmq;
tmq->tm_next = dhcp_tmlist_last;
if(pmq) {
pmq->tm_next = tmq;
tmq->tm_prev = pmq;
}
else
dhcp_tmlist_first = tmq;
}
else {
dhcp_tmlist_first = tmq;
dhcp_tmlist_last = tmq;
}
dh0_timeouts_cnt++;
/*printf("ADD: tm=0x%x, dhcp_rq=0x%x, ping_status=%d, number=%d(%d)\n",
tmq, dhcp_rq, (dhcp_rq)?dhcp_rq->ping_status: -1, ping_number_pending,
dh0_timeouts_cnt);*/
return 0;
}
int
dh0_free_timelist_entry(struct dhcp_timelist *tq)
{
free(tq->cid_ptr);
free(tq->tm_eaddr);
free(tq);
return 0;
}
int
dh0_remove_from_timelist(char *cid_ptr, int cid_length)
{
struct dhcp_timelist *tq, *pq;
tq = dhcp_tmlist_first;
if(tq == 0)
return 1;
while(tq) {
if((tq->cid_length == cid_length) &&
bcmp(tq->cid_ptr, cid_ptr, cid_length) == 0) {
pq = tq->tm_prev;
if(pq) {
pq->tm_next = tq->tm_next;
tq->tm_next->tm_prev = pq;
}
else {
dhcp_tmlist_first = tq->tm_next;
if(dhcp_tmlist_first)
dhcp_tmlist_first->tm_prev = 0;
}
if (tq->tm_dhcp_rq && (tq->tm_dhcp_rq->ping_status == PING_SENT))
ping_number_pending--;
dh0_timeouts_cnt--;
/*printf("RM:tm=0x%x, dhcp_rq=0x%x, ping_status=%d, number=%d(%d)\n",
tq, tq->tm_dhcp_rq, (tq->tm_dhcp_rq)?tq->tm_dhcp_rq->ping_status: -1, ping_number_pending, dh0_timeouts_cnt);*/
dh0_free_timelist_entry(tq);
return 0;
}
tq = tq->tm_next;
}
return 1;
}
struct dhcp_timelist *
dh0_find_timelist_entry(char *cid_ptr, int cid_length)
{
struct dhcp_timelist *tq;
tq = dhcp_tmlist_first;
if(tq == 0)
return 0;
while(tq) {
if (cid_length == tq->cid_length) {
if(bcmp(tq->cid_ptr, cid_ptr, cid_length) == 0)
return tq;
}
tq = tq->tm_next;
}
return 0;
}
struct dhcp_timelist *
dh0_pop_timelist_timer(void)
{
struct dhcp_timelist *tq;
tq = dhcp_tmlist_first;
if(!tq)
return 0;
dhcp_tmlist_first = dhcp_tmlist_first->tm_next;
dhcp_tmlist_first->tm_prev = 0;
dh0_timeouts_cnt--;
if (tq->tm_dhcp_rq && (tq->tm_dhcp_rq->ping_status == PING_SENT))
ping_number_pending--;
/*printf("POP:tm=0x%x, dhcp_rq=0x%x, ping_status=%d, number=%d(%d)\n",
tq, tq->tm_dhcp_rq, (tq->tm_dhcp_rq)?tq->tm_dhcp_rq->ping_status: -1, ping_number_pending, dh0_timeouts_cnt);*/
return tq;
}
int
dh0_set_timeval(struct timeval *tmo, long tval)
{
tmo->tv_sec = tval;
tmo->tv_usec = 0;
return 0;
}
long
dh0_update_and_get_next_timeout(time_t timenow)
{
long time_left;
if(dh0_timeouts_cnt == 1) {
time_left = dhcp_tmlist_last->tm_value - timenow;
return time_left;
}
time_left = dhcp_tmlist_first->tm_value - timenow;
if(time_left < 0)
return 1;
return time_left;
}