1
0
Files
2022-09-29 17:59:04 +03:00

268 lines
5.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/soioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netdb.h>
#include <nlist.h>
#include <rpcsvc/ypclnt.h>
#include <syslog.h>
#include "dhcpdefs.h"
#define MAX_BROADCAST_SIZE 1400
#define YP_TRUE 1
char NFSOPT[] = "/etc/havenfs";
extern char *alt_sysname;
int
nha0_haveNfsOption(void)
{
FILE *fip;
if( access(NFSOPT, 1) )
return(0);
fip = popen(NFSOPT, "r");
if(!fip)
return 0;
if(pclose(fip))
return(0);
return(1);
}
int
nha0_ypbindIsUp(char *dmn)
{
int so;
int yellow;
if ((so = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return 0;
close(so);
yellow = !yp_bind(dmn);
return(yellow);
}
char *
nha0_get_primary_interface_name(long hstid)
{
int ss;
struct ifconf ifc;
struct ifreq fir;
char xbuf[MAX_BROADCAST_SIZE];
int i;
struct sockaddr_in *sin1;
char *intrfc;
ss = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ss < 0) {
return (char *)0;
}
bzero(&ifc, sizeof(ifc));
bzero(&fir, sizeof(fir));
bzero(xbuf, sizeof(xbuf));
ifc.ifc_len = MAX_BROADCAST_SIZE;
ifc.ifc_buf = xbuf;
if(ioctl(ss, SIOCGIFCONF, (char *)&ifc) < 0) {
close(ss);
return (char *)0;
}
close(ss);
i = 0;
fir = ifc.ifc_req[i];
while(strcmp(fir.ifr_name, "") ) { /* I18N */
sin1 = (struct sockaddr_in *)&fir.ifr_addr;
if(sin1->sin_addr.s_addr == hstid)
break;
fir = ifc.ifc_req[++i];
}
intrfc = strdup(fir.ifr_name); /* I18N */
return(intrfc);
}
u_long
nha0_getBroadcastAddr(char *interface)
{
struct sockaddr_in s_baddr;
int af = AF_INET;
struct ifreq gifr;
int ss;
bzero(&gifr, sizeof(gifr));
strncpy(gifr.ifr_name, interface, IFNAMSIZ); /* I18N */
ss = socket(af, SOCK_DGRAM, 0);
if (ss < 0) {
return 0;
}
if (ioctl(ss, SIOCGIFBRDADDR, (caddr_t)&gifr) < 0) {
close(ss);
return 0;
}
s_baddr = *(struct sockaddr_in *)&gifr.ifr_addr;
close(ss);
return(s_baddr.sin_addr.s_addr);
}
u_long
nha0_getSubnetmask(char *interface)
{
struct sockaddr_in s_mask;
int af = AF_INET;
struct ifreq gifr;
int ss;
bzero(&gifr, sizeof(gifr));
strncpy(gifr.ifr_name, interface, IFNAMSIZ); /* I18N */
ss = socket(af, SOCK_DGRAM, 0);
if (ss < 0) {
return 0;
}
if (ioctl(ss, SIOCGIFNETMASK, (caddr_t)&gifr) < 0) {
close(ss);
return 0;
}
s_mask = *(struct sockaddr_in *)&gifr.ifr_addr;
close(ss);
return(s_mask.sin_addr.s_addr);
}
/********
static u_long yp_server_list[256];
static int yp_server_cnt;
static int
yp_all_callback(int status, char *key, int kl, char *val, int vl, char *notused)
{
struct hostent *hp;
if(status == YP_TRUE) {
if(hp = gethostbyname(key))
yp_server_list[yp_server_cnt++] = *((u_long *)hp->h_addr);
return 0;
}
else
return 1;
}
u_long *
nha0_get_nis_servers(char *nisdm)
{
int err;
struct ypall_callback cbinfo;
yp_server_cnt = 0;
cbinfo.foreach = yp_all_callback;
cbinfo.data = (char *) NULL;
err = yp_all(nisdm, "ypservers", &cbinfo);
yp_server_list[yp_server_cnt] = 0;
return (u_long *)yp_server_list;
}
********/
#define KERNBASE 0x80000000
/* #define KERNBASE 0x8000000000000000 */
struct nlist nl[] = {
{ "ifnet" },
"",
};
static off_t
klseek(int kmem, off_t base)
{
base &= ~KERNBASE;
return (lseek(kmem, base, 0));
}
int
nha0_get_kmem_data(char *ifname, int *mtu)
{
char *sysname;
int kmem;
off_t ifnetaddr;
char xbuf[IFNAMSIZ];
struct ifnet ifnet;
char ybuf[IFNAMSIZ+2];
int found = 0;
if(alt_sysname)
sysname = alt_sysname;
else
sysname = "/unix";
/*
* Seek into the kernel for a value.
*/
kmem = open("/dev/kmem", 0);
if (kmem < 0) {
syslog(LOG_ERR,"Cannot open /dev/kmem (%m)");
return 1;
}
nlist(sysname, nl);
if (nl[0].n_type == 0) {
syslog(LOG_ERR,"Cannot read system namelist (%m)");
close(kmem);
return 1;
}
ifnetaddr = nl[0].n_value;
if(klseek(kmem, ifnetaddr) < 0) {
syslog(LOG_ERR,"Error seeking in kmem (%m)");
close(kmem);
return 1;
}
if(read(kmem, &ifnetaddr, sizeof(ifnetaddr)) < 0) {
syslog(LOG_ERR,"Error reading kmem: ifnetaddr (%m)");
close(kmem);
return 1;
}
for ( ;ifnetaddr != 0; ifnetaddr = (off_t) ifnet.if_next) {
/* Read ifnet structure from kernel */
klseek(kmem, ifnetaddr);
if(read(kmem, &ifnet, sizeof ifnet) < 0) {
syslog(LOG_ERR,"Error reading kmem: ifnet (%m)");
close(kmem);
return 1;
}
klseek(kmem, (off_t)ifnet.if_name);
if (read(kmem, xbuf, IFNAMSIZ-2) < 0) {
syslog(LOG_ERR,"Error reading kmem: if_name (%m)");
close(kmem);
return 1;
}
xbuf[IFNAMSIZ-2] = '\0';
sprintf(ybuf, "%s%d", xbuf, ifnet.if_unit);
if(strcmp(ifname, ybuf) == 0) {
found++;
#ifdef sgi
*mtu = ifnet.if_data.ifi_mtu;
#else
*mtu = ifnet.if_mtu;
#endif
break;
}
}
close(kmem);
if(found)
return 0;
return 1;
}