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>