Annotation of libelwix/src/net.c, revision 1.1
1.1 ! misho 1: /*************************************************************************
! 2: * (C) 2013 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
! 3: * by Michael Pounov <misho@elwix.org>
! 4: *
! 5: * $Author: misho $
! 6: * $Id: global.h,v 1.13 2012/08/29 13:51:29 misho Exp $
! 7: *
! 8: **************************************************************************
! 9: The ELWIX and AITNET software is distributed under the following
! 10: terms:
! 11:
! 12: All of the documentation and software included in the ELWIX and AITNET
! 13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
! 14:
! 15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
! 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
! 17:
! 18: Redistribution and use in source and binary forms, with or without
! 19: modification, are permitted provided that the following conditions
! 20: are met:
! 21: 1. Redistributions of source code must retain the above copyright
! 22: notice, this list of conditions and the following disclaimer.
! 23: 2. Redistributions in binary form must reproduce the above copyright
! 24: notice, this list of conditions and the following disclaimer in the
! 25: documentation and/or other materials provided with the distribution.
! 26: 3. All advertising materials mentioning features or use of this software
! 27: must display the following acknowledgement:
! 28: This product includes software developed by Michael Pounov <misho@elwix.org>
! 29: ELWIX - Embedded LightWeight unIX and its contributors.
! 30: 4. Neither the name of AITNET nor the names of its contributors
! 31: may be used to endorse or promote products derived from this software
! 32: without specific prior written permission.
! 33:
! 34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
! 35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 44: SUCH DAMAGE.
! 45: */
! 46: #include "global.h"
! 47:
! 48:
! 49: /*
! 50: * e_ether_ntoa() - Convert ethernet address to string
! 51: *
! 52: * @n = ethernet address structure, like struct ether_addr
! 53: * @a = string
! 54: * @len = string length
! 55: * return: NULL error or !=NULL string a
! 56: */
! 57: inline char *
! 58: e_ether_ntoa(const struct e_ether_addr *n, char * __restrict a, int len)
! 59: {
! 60: if (!n || !a)
! 61: return NULL;
! 62:
! 63: memset(a, 0, len);
! 64: if (snprintf(a, len, "%02x:%02x:%02x:%02x:%02x:%02x",
! 65: n->ether_addr_octet[0], n->ether_addr_octet[1],
! 66: n->ether_addr_octet[2], n->ether_addr_octet[3],
! 67: n->ether_addr_octet[4], n->ether_addr_octet[5]) < 17)
! 68: return NULL;
! 69:
! 70: return a;
! 71: }
! 72:
! 73: /*
! 74: * e_ether_aton() - Convert string to ethernet address
! 75: *
! 76: * @a = string
! 77: * @e = ethernet address structure, like struct ether_addr
! 78: * return: NULL error or !=NULL ethernet address structure
! 79: */
! 80: inline struct e_ether_addr *
! 81: e_ether_aton(const char *a, struct e_ether_addr *e)
! 82: {
! 83: int i;
! 84: u_int o0, o1, o2, o3, o4, o5;
! 85:
! 86: if (!a || !e)
! 87: return NULL;
! 88:
! 89: i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
! 90: if (i != 6)
! 91: return NULL;
! 92:
! 93: e->ether_addr_octet[0] = o0;
! 94: e->ether_addr_octet[1] = o1;
! 95: e->ether_addr_octet[2] = o2;
! 96: e->ether_addr_octet[3] = o3;
! 97: e->ether_addr_octet[4] = o4;
! 98: e->ether_addr_octet[5] = o5;
! 99:
! 100: return e;
! 101: }
! 102:
! 103: /*
! 104: * e_n2port() - Extract port from network structure
! 105: *
! 106: * @addr = Address
! 107: * return: 0 not supported family type or port number
! 108: */
! 109: inline u_short
! 110: e_n2port(sockaddr_t * __restrict addr)
! 111: {
! 112: u_short port = 0;
! 113:
! 114: if (!addr)
! 115: return port;
! 116:
! 117: switch (addr->sa.sa_family) {
! 118: case AF_INET:
! 119: return ntohs(addr->sin.sin_port);
! 120: case AF_INET6:
! 121: return ntohs(addr->sin6.sin6_port);
! 122: default:
! 123: break;
! 124: }
! 125:
! 126: return port;
! 127: }
! 128:
! 129: /*
! 130: * e_n2addr() - Extract address from network structure
! 131: *
! 132: * @addr = Address
! 133: * @val = Value for store string address
! 134: * return: NULL error or !=NULL string address from val
! 135: */
! 136: const char *
! 137: e_n2addr(sockaddr_t * __restrict addr, ait_val_t * __restrict val)
! 138: {
! 139: char str[INET6_ADDRSTRLEN] = { 0 };
! 140: const char *ret = NULL;
! 141:
! 142: if (!addr || !val)
! 143: return ret;
! 144:
! 145: AIT_INIT_VAL(val);
! 146: switch (addr->sa.sa_family) {
! 147: case AF_INET:
! 148: if (!inet_ntop(AF_INET, &addr->sin.sin_addr, str, INET_ADDRSTRLEN)) {
! 149: LOGERR;
! 150: return ret;
! 151: } else
! 152: ret = str;
! 153: break;
! 154: case AF_INET6:
! 155: if (!inet_ntop(AF_INET6, &addr->sin6.sin6_addr, str, INET6_ADDRSTRLEN)) {
! 156: LOGERR;
! 157: return ret;
! 158: } else
! 159: ret = str;
! 160: break;
! 161: case AF_LOCAL:
! 162: ret = addr->sun.sun_path;
! 163: break;
! 164: default:
! 165: elwix_SetErr(EPROTONOSUPPORT, "Unsuported address family %d",
! 166: addr->sa.sa_family);
! 167: return ret;
! 168: }
! 169:
! 170: AIT_SET_STR(val, ret);
! 171: return (const char*) AIT_GET_STR(val);
! 172: }
! 173:
! 174: /*
! 175: * e_gethostbyname() - Get host and port and make network structure
! 176: *
! 177: * @psHost = Hostname
! 178: * @port = Port
! 179: * @addr = Network address structure
! 180: * return: NULL error or !=NULL network structure
! 181: */
! 182: sockaddr_t *
! 183: e_gethostbyname(const char *psHost, u_short port, sockaddr_t * __restrict addr)
! 184: {
! 185: struct hostent *host = NULL;
! 186:
! 187: if (!psHost || !addr)
! 188: return NULL;
! 189:
! 190: if (*psHost != '/') {
! 191: /* resolver */
! 192: if (!addr->sa.sa_family)
! 193: host = gethostbyname(psHost);
! 194: else
! 195: host = gethostbyname2(psHost, addr->sa.sa_family);
! 196: if (!host) {
! 197: elwix_SetErr(EINVAL, "Resolver #%d - %s", h_errno, hstrerror(h_errno));
! 198: return NULL;
! 199: } else {
! 200: memset(addr, 0, sizeof(sockaddr_t));
! 201: addr->sa.sa_family = host->h_addrtype;
! 202: }
! 203: } else {
! 204: memset(addr, 0, sizeof(sockaddr_t));
! 205: addr->sa.sa_family = AF_LOCAL;
! 206: }
! 207:
! 208:
! 209: switch (addr->sa.sa_family) {
! 210: case AF_INET:
! 211: addr->sin.sin_len = sizeof(struct sockaddr_in);
! 212: addr->sin.sin_family = AF_INET;
! 213: addr->sin.sin_port = htons(port);
! 214: memcpy(&addr->sin.sin_addr, host->h_addr, sizeof addr->sin.sin_addr);
! 215: return addr;
! 216: case AF_INET6:
! 217: addr->sin6.sin6_len = sizeof(struct sockaddr_in6);
! 218: addr->sin6.sin6_family = AF_INET6;
! 219: addr->sin6.sin6_port = htons(port);
! 220: memcpy(&addr->sin6.sin6_addr, host->h_addr, sizeof addr->sin6.sin6_addr);
! 221: return addr;
! 222: case AF_LOCAL:
! 223: addr->sun.sun_len = sizeof(struct sockaddr_un);
! 224: addr->sun.sun_family = AF_LOCAL;
! 225: memset(addr->sun.sun_path, 0, sizeof addr->sun.sun_path);
! 226: snprintf(addr->sun.sun_path, sizeof addr->sun.sun_path, "%s-%hu", psHost, port);
! 227: return addr;
! 228: default:
! 229: elwix_SetErr(EPROTONOSUPPORT, "Unsuported address family %d", addr->sa.sa_family);
! 230: break;
! 231: }
! 232:
! 233: return NULL;
! 234: }
! 235:
! 236: /*
! 237: * e_addrcmp() - Compare network addresses
! 238: *
! 239: * @a = 1st address
! 240: * @b = 2nd address
! 241: * @p = compare and ports, if family is AF_INET or AF_INET6
! 242: * return: 0 is equal or !=0 is different
! 243: */
! 244: int
! 245: e_addrcmp(sockaddr_t * __restrict a, sockaddr_t * __restrict b, int p)
! 246: {
! 247: if (a && b && a->sa.sa_family == b->sa.sa_family)
! 248: switch (a->sa.sa_family) {
! 249: case AF_LOCAL:
! 250: return strcmp(a->sun.sun_path, b->sun.sun_path);
! 251: case AF_INET:
! 252: if (p && (a->sin.sin_port - b->sin.sin_port))
! 253: return (int) !!(a->sin.sin_port - b->sin.sin_port);
! 254: else
! 255: return memcmp(&a->sin.sin_addr, &b->sin.sin_addr,
! 256: sizeof a->sin.sin_addr);
! 257: case AF_INET6:
! 258: if (p && (a->sin6.sin6_port - b->sin6.sin6_port))
! 259: return (int) !!(a->sin6.sin6_port - b->sin6.sin6_port);
! 260: else
! 261: return memcmp(&a->sin6.sin6_addr, &b->sin6.sin6_addr,
! 262: sizeof a->sin6.sin6_addr);
! 263: case AF_LINK:
! 264: return memcmp(&a->sdl.sdl_data, &b->sdl.sdl_data,
! 265: sizeof a->sdl.sdl_data);
! 266: }
! 267:
! 268: return (int) !!(a - b);
! 269: }
! 270:
! 271: /*
! 272: * e_usleep() - usleep() replacement for ELWIX
! 273: *
! 274: * @usec = microseconds for sleep
! 275: * return: -1 interrupted by signal or 0 ok
! 276: */
! 277: inline int
! 278: e_usleep(u_int usec)
! 279: {
! 280: struct timeval tv = { (time_t) (usec / 1000000), (long) (usec % 1000000) };
! 281:
! 282: return select(0, NULL, NULL, NULL, &tv);
! 283: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>