#include "defs.h"
#include <ctype.h>
in_addr_t
std_mask(in_addr_t addr)
{
addr = ntohl(addr);
if (addr == 0)
return (0);
if (IN_CLASSA(addr))
return (IN_CLASSA_NET);
if (IN_CLASSB(addr))
return (IN_CLASSB_NET);
if (IN_CLASSC(addr))
return (IN_CLASSC_NET);
return (IN_CLASSE_NET);
}
boolean_t
getnet(const char *name,
in_addr_t *netp,
in_addr_t *maskp)
{
int i;
struct netent *np;
in_addr_t mask;
struct in_addr in;
char hname[MAXHOSTNAMELEN+1];
char *mname, *p;
if (NULL != (mname = strrchr(name, '/'))) {
i = (int)(mname - name);
if (i > (int)sizeof (hname)-1)
return (_B_FALSE);
(void) memmove(hname, name, i);
hname[i] = '\0';
mname++;
name = hname;
}
if ((in.s_addr = inet_network(name)) == (in_addr_t)-1) {
if (mname == NULL && strcasecmp(name, "default") == 0)
in.s_addr = ntohl(RIP_DEFAULT);
else if ((np = getnetbyname(name)) != NULL)
in.s_addr = np->n_net;
else
return (_B_FALSE);
}
if (0 == (in.s_addr & 0xff000000))
in.s_addr <<= 8;
if (0 == (in.s_addr & 0xff000000))
in.s_addr <<= 8;
if (0 == (in.s_addr & 0xff000000))
in.s_addr <<= 8;
if (mname == NULL) {
mask = std_mask(htonl(in.s_addr));
if ((~mask & in.s_addr) != 0)
mask = HOST_MASK;
} else {
mask = (uint32_t)strtoul(mname, &p, 0);
if (*p != '\0' || mask > 32 || mname == p)
return (_B_FALSE);
if (mask != 0)
mask = HOST_MASK << (32-mask);
}
if (mask != 0 && in.s_addr == RIP_DEFAULT)
return (_B_FALSE);
if ((~mask & in.s_addr) != 0)
return (_B_FALSE);
if ((mask & in.s_addr) == 0 && in.s_addr != RIP_DEFAULT)
return (_B_FALSE);
if ((in.s_addr >> 24) == 0 && in.s_addr != RIP_DEFAULT)
return (_B_FALSE);
if ((in.s_addr >> 24) == 0xff)
return (_B_FALSE);
*netp = in.s_addr;
*maskp = mask;
return (_B_TRUE);
}
char *
qstring(const uchar_t *srcp, int len)
{
static char buf[8*20+1];
char *prcp, *tmp_ptr;
uchar_t c;
const uchar_t *s2;
s2 = srcp + len;
while (s2 > srcp && *--s2 == '\0')
len--;
for (prcp = buf; len != 0 && prcp < &buf[sizeof (buf)-1]; len--) {
c = *srcp++;
if (isprint(c) && c != '\\') {
*prcp++ = c;
continue;
}
*prcp++ = '\\';
tmp_ptr = strchr("\\\\\nn\rr\tt\bb\aa\ff", c);
if (tmp_ptr != NULL)
*prcp++ = tmp_ptr[1];
else
prcp += snprintf(prcp,
(sizeof (buf) - (strlen(buf)+1)), "%o", c);
}
*prcp = '\0';
return (buf);
}
int
parse_quote(char **linep,
const char *delims,
char *delimp,
char *buf,
int lim)
{
char c = '\0', *pc;
const char *p;
pc = *linep;
if (*pc == '\0')
return (-1);
while (lim != 0) {
c = *pc++;
if (c == '\0')
break;
if (c == '\\' && *pc != '\0') {
c = *pc++;
switch (c) {
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'b':
c = '\b';
}
if (c >= '0' && c <= '7') {
c -= '0';
if (*pc >= '0' && *pc <= '7') {
c = (c<<3)+(*pc++ - '0');
if (*pc >= '0' && *pc <= '7')
c = (c<<3)+(*pc++ - '0');
}
}
} else {
for (p = delims; *p != '\0'; ++p) {
if (*p == c || isspace(c) && *p == ' ')
goto exit;
}
}
*buf++ = c;
--lim;
}
exit:
if (lim == 0)
return (-1);
*buf = '\0';
if (delimp != NULL)
*delimp = c;
*linep = pc-1;
return (0);
}
void *
find_ancillary(struct msghdr *msg, int cmsg_type)
{
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(msg, cmsg)) {
if (cmsg->cmsg_level == IPPROTO_IP &&
cmsg->cmsg_type == cmsg_type) {
return (CMSG_DATA(cmsg));
}
}
return (NULL);
}