1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00
ipxwrapper/src/addr.c
2012-11-10 17:05:41 +00:00

224 lines
5.1 KiB
C

/* ipxwrapper - Address manipulation functions
* Copyright (C) 2012 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <windows.h>
#include <winsock2.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "addr.h"
#include "common.h"
static bool _addr_from_string(unsigned char *dest, const char *src, int size)
{
int i;
for(i = 0; i < size; i++)
{
char term = (i + 1 == size ? '\0' : ':');
if(isxdigit(src[0]) && (src[1] == term || (isxdigit(src[1]) && src[2] == term)))
{
dest[i] = strtoul(src, NULL, 16);
src += strcspn(src, ":");
src += strspn(src, ":");
}
else{
return false;
}
}
return true;
}
addr32_t addr32_in(const void *src)
{
addr32_t buf = 0;
memcpy(&buf, src, 4);
return buf;
}
/* Write out a 32-bit address in network byte order. */
void *addr32_out(void *dest, addr32_t src)
{
return memcpy(dest, &src, 4);
}
/* Convert a 32-bit address to a string in the format XX:XX:XX:XX */
char *addr32_string(char *buf, addr32_t addr)
{
unsigned char c[6];
addr32_out(c, addr);
sprintf(
buf,
"%02X:%02X:%02X:%02X",
(unsigned int)(c[0]),
(unsigned int)(c[1]),
(unsigned int)(c[2]),
(unsigned int)(c[3])
);
return buf;
}
/* Parse a string-formatted 32-bit address and store it in an addr32_t value.
* Returns true on success, false on parse error.
*/
bool addr32_from_string(addr32_t *dest, const char *src)
{
return _addr_from_string((unsigned char*)&dest, src, 4);
}
/* Read a 32-bit network address from the registry.
* Returns default_value upon failure.
*/
addr32_t reg_get_addr32(HKEY key, const char *name, addr32_t default_value)
{
unsigned char buf[4], default_buf[4];
addr48_out(default_buf, default_value);
reg_get_bin(key, name, buf, 4, default_buf);
return addr32_in(buf);
}
/* Store a 32-bit network address in the registry.
* Returns true on success, false on failure.
*/
bool reg_set_addr32(HKEY key, const char *name, addr32_t value)
{
unsigned char buf[4];
addr32_out(buf, value);
return reg_set_bin(key, name, buf, sizeof(buf));
}
addr48_t addr48_in(const void *src)
{
addr48_t buf = 0;
memcpy(((char*)&buf) + 2, src, 6);
return buf;
}
/* Write out a 48-bit address in network byte order. */
void *addr48_out(void *dest, addr48_t src)
{
return memcpy(dest, ((char*)&src) + 2, 6);
}
/* Convert a 48-bit address to a string in the format XX:XX:XX:XX:XX:XX */
char *addr48_string(char *buf, addr48_t addr)
{
unsigned char c[6];
addr48_out(c, addr);
sprintf(
buf,
"%02X:%02X:%02X:%02X:%02X:%02X",
(unsigned int)(c[0]),
(unsigned int)(c[1]),
(unsigned int)(c[2]),
(unsigned int)(c[3]),
(unsigned int)(c[4]),
(unsigned int)(c[5])
);
return buf;
}
/* Parse a string-formatted 48-bit address and store it in an addr48_t value.
* Returns true on success, false on parse error.
*/
bool addr48_from_string(addr48_t *dest, const char *src)
{
return _addr_from_string(((unsigned char*)&dest) + 2, src, 6);
}
/* Read a 48-bit network address from the registry.
* Returns default_value upon failure.
*/
addr48_t reg_get_addr48(HKEY key, const char *name, addr48_t default_value)
{
unsigned char buf[6], default_buf[6];
addr48_out(default_buf, default_value);
reg_get_bin(key, name, buf, 6, default_buf);
return addr48_in(buf);
}
/* Store a 48-bit network address in the registry.
* Returns true on success, false on failure.
*/
bool reg_set_addr48(HKEY key, const char *name, addr48_t value)
{
unsigned char buf[6];
addr48_out(buf, value);
return reg_set_bin(key, name, buf, sizeof(buf));
}
/* Format an IPX address as a string.
*
* The socket number should be in network byte order and the supplied buffer
* must be at least IPX_SADDR_SIZE bytes long.
*/
void ipx_to_string(char *buf, addr32_t net, addr48_t node, uint16_t sock)
{
addr32_string(buf, net);
buf[11] = '/';
addr48_string(buf + 12, node);
buf[29] = '/';
sprintf(buf + 30, "%hu", ntohs(sock));
}
/* Generate a (probably) unique locally-administered MAC address. */
addr48_t gen_random_mac()
{
static bool seeded = false;
if(!seeded)
{
srand(GetTickCount());
seeded = true;
}
unsigned char addr[6];
unsigned int i;
for(i = 0; i < 6; i++)
{
addr[i] = (rand() % 0xFF);
}
addr[0] |= 0x02;
return addr48_in(addr);
}