Annotation of libelwix/src/net.c, revision 1.2.2.3
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 $
1.2.2.3 ! misho 6: * $Id: net.c,v 1.2.2.2 2013/06/03 11:48:26 misho Exp $
1.1 misho 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: */
1.2 misho 57: char *
1.1 misho 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: */
1.2 misho 80: struct e_ether_addr *
1.1 misho 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: */
1.2 misho 109: u_short
1.1 misho 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: */
1.2 misho 277: int
1.1 misho 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: }
1.2.2.1 misho 284:
285: /*
286: * e_innet() - Test address match in network
287: *
288: * @net = network
289: * @addr = address
290: * return: -1 error, 0 match or 1 not match
291: */
292: int
1.2.2.2 misho 293: e_innet(netaddr_t * __restrict net, inaddr_t * __restrict addr)
1.2.2.1 misho 294: {
295: register int i;
296: int ret = 0;
297:
298: if (!net || !addr)
299: return -1;
300:
301: switch (net->addr.sa.sa_family) {
302: case AF_INET:
1.2.2.3 ! misho 303: for (i = 0; i < sizeof(struct in_addr); i++) {
! 304: ret = ((caddr_t) &net->addr.sin.sin_addr.s_addr)[i] &
! 305: net->mask.in.s4_addr[i];
! 306: ret -= addr->in.s4_addr[i] & net->mask.in.s4_addr[i];
! 307: if (ret)
! 308: break;
! 309: }
1.2.2.1 misho 310: break;
311: case AF_INET6:
312: for (i = 0; i < sizeof(struct in6_addr); i++) {
1.2.2.3 ! misho 313: ret = net->addr.sin6.sin6_addr.s6_addr[i] &
! 314: net->mask.in6.s6_addr[i];
1.2.2.2 misho 315: ret -= addr->in6.s6_addr[i] & net->mask.in6.s6_addr[i];
1.2.2.1 misho 316: if (ret)
317: break;
318: }
319: break;
320: default:
321: return -1;
322: }
323:
324: return !!ret;
325: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>