/*
* Soft: Keepalived is a failover program for the LVS project
* <www.linuxvirtualserver.org>. It monitor & manipulate
* a loadbalanced server pool using multi-layer checks.
*
* Part: General program utils.
*
* Version: $Id: utils.c,v 1.1.1.1 2005/03/01 00:23:14 clement Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Copyright (C) 2001-2005 Alexandre Cassen, <acassen@linux-vs.org>
*/
#include "utils.h"
/* global vars */
int debug = 0;
/* Display a buffer into a HEXA formated output */
void
dump_buffer(char *buff, int count)
{
int i, j, c;
int printnext = 1;
if (count % 16)
c = count + (16 - count % 16);
else
c = count;
for (i = 0; i < c; i++) {
if (printnext) {
printnext--;
printf("%.4x ", i & 0xffff);
}
if (i < count)
printf("%3.2x", buff[i] & 0xff);
else
printf(" ");
if (!((i + 1) % 8)) {
if ((i + 1) % 16)
printf(" -");
else {
printf(" ");
for (j = i - 15; j <= i; j++)
if (j < count) {
if ((buff[j] & 0xff) >= 0x20
&& (buff[j] & 0xff) <= 0x7e)
printf("%c",
buff[j] & 0xff);
else
printf(".");
} else
printf(" ");
printf("\n");
printnext = 1;
}
}
}
}
/* Compute a checksum */
u_short
in_csum(u_short * addr, int len, u_short csum)
{
register int nleft = len;
const u_short *w = addr;
register u_short answer;
register int sum = csum;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum),
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1)
sum += htons(*(u_char *) w << 8);
/*
* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
/* IP network to ascii representation */
char *
inet_ntop2(uint32_t ip)
{
static char buf[16];
unsigned char *bytep;
bytep = (unsigned char *) &(ip);
sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
return buf;
}
/*
* IP network to ascii representation. To use
* for multiple IP address convertion into the same call.
*/
char *
inet_ntoa2(uint32_t ip, char *buf)
{
unsigned char *bytep;
bytep = (unsigned char *) &(ip);
sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
return buf;
}
/* IP string to network mask representation. CIDR notation. */
uint8_t
inet_stom(char *addr)
{
uint8_t mask = 32;
char *cp = addr;
if (!strstr(addr, "/"))
return mask;
while (*cp != '/' && *cp != '\0')
cp++;
if (*cp == '/')
return atoi(++cp);
return mask;
}
/* IP string to network range representation. */
uint8_t
inet_stor(char *addr)
{
uint8_t range = 0;
char *cp = addr;
if (!strstr(addr, "-"))
return range;
while (*cp != '-' && *cp != '\0')
cp++;
if (*cp == '-')
return atoi(++cp);
return range;
}
/*
* IP string to network representation
* Highly inspired from Paul Vixie code.
*/
int
inet_ston(const char *addr, uint32_t * dst)
{
static char digits[] = "0123456789";
int saw_digit, octets, ch;
u_char tmp[INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
*(tp = tmp) = 0;
while ((ch = *addr++) != '\0' && ch != '/' && ch != '-') {
const char *pch;
if ((pch = strchr(digits, ch)) != NULL) {
u_int new = *tp * 10 + (pch - digits);
if (new > 255)
return 0;
*tp = new;
if (!saw_digit) {
if (++octets > 4)
return 0;
saw_digit = 1;
}
} else if (ch == '.' && saw_digit) {
if (octets == 4)
return 0;
*++tp = 0;
saw_digit = 0;
} else
return 0;
}
if (octets < 4)
return 0;
memcpy(dst, tmp, INADDRSZ);
return 1;
}
/*
* Return broadcast address from network and netmask.
*/
uint32_t
inet_broadcast(uint32_t network, uint32_t netmask)
{
return 0xffffffff - netmask + network;
}
/*
* Convert CIDR netmask notation to long notation.
*/
uint32_t
inet_cidrtomask(uint8_t cidr)
{
uint32_t mask = 0;
int b;
for (b = 0; b < cidr; b++)
mask |= (1 << (31 - b));
return ntohl(mask);
}
/* Getting localhost official canonical name */
char *
get_local_name(void)
{
struct hostent *host;
struct utsname name;
if (uname(&name) < 0)
return NULL;
if (!(host = gethostbyname(name.nodename)))
return NULL;
return host->h_name;
}
syntax highlighted by Code2HTML, v. 0.9.1