Radcli library 1.5.2
A simple radius library
Loading...
Searching...
No Matches
util.c
1/*
2 * Copyright (C) 1995,1996,1997 Lars Fenneberg
3 *
4 * Copyright 1992 Livingston Enterprises, Inc.
5 *
6 * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
7 * and Merit Network, Inc. All Rights Reserved
8 *
9 * See the file COPYRIGHT for the respective terms and conditions.
10 * If the file is missing contact me at lf@elemental.net
11 * and I'll send you a copy.
12 *
13 */
14
15#define _GNU_SOURCE
16
17#include <sys/time.h>
18
19#include <config.h>
20#include <includes.h>
21#include <radcli/radcli.h>
22#include "util.h"
23
24#define RC_BUFSIZ 1024
25
26#ifdef __linux__
27#include <sched.h>
28#define NSNET_SZ (128)
29#endif
30
31
32static char const * months[] =
33 {
34 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
35 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
36 };
37
38/*- Turns printable string into correct tm struct entries
39 *
40 * @param valstr the printable date in 'day month year' format.
41 * @param tm the output struct.
42 -*/
43void rc_str2tm (char const *valstr, struct tm *tm)
44{
45 int i;
46
47 /* Get the month */
48 for (i = 0; i < 12; i++)
49 {
50 if (strncmp (months[i], valstr, 3) == 0)
51 {
52 tm->tm_mon = i;
53 i = 13;
54 }
55 }
56
57 /* Get the Day */
58 tm->tm_mday = atoi (&valstr[4]);
59
60 /* Now the year */
61 tm->tm_year = atoi (&valstr[7]) - 1900;
62}
63
64/*- Returns the current monotonic time as a double
65 *
66 * @return Get monotonic time seconds since some fixed start) expressed as
67 * double-precision floating point number.
68 -*/
69double rc_getmtime(void)
70{
71#ifdef HAVE_CLOCK_GETTIME
72 struct timespec timespec;
73
74 if (clock_gettime(CLOCK_MONOTONIC, &timespec) != 0)
75 return -1;
76
77 return timespec.tv_sec + ((double)timespec.tv_nsec) / 1000000000.0;
78#else
79 struct timeval timev;
80
81 if (gettimeofday(&timev, NULL) == -1)
82 return -1;
83
84 return timev.tv_sec + ((double)timev.tv_usec) / 1000000.0;
85#endif
86}
87
102char *
103rc_mksid (void)
104{
105 static char buf[15];
106 static unsigned short int cnt = 0;
107 snprintf (buf, sizeof(buf), "%08lX%04X%02hX",
108 (unsigned long int) time (NULL),
109 (unsigned int) getpid (),
110 cnt & 0xFF);
111 cnt++;
112 return buf;
113}
114/*
115 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
116 *
117 * Permission to use, copy, modify, and distribute this software for any
118 * purpose with or without fee is hereby granted, provided that the above
119 * copyright notice and this permission notice appear in all copies.
120 *
121 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
122 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
123 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
124 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
125 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
126 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
127 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
128 *
129 * Copyright 2006 The FreeRADIUS server project
130 */
131
132#ifdef RC_NEED_STRLCPY
133
134/*-
135 * Copy src to string dst of size siz. At most siz-1 characters
136 * will be copied. Always NUL terminates (unless siz == 0).
137 * Returns strlen(src); if retval >= siz, truncation occurred.
138 -*/
139size_t
140rc_strlcpy(char *dst, char const *src, size_t siz)
141{
142 char *d = dst;
143 char const *s = src;
144 size_t n = siz;
145
146 /* Copy as many bytes as will fit */
147 if (n != 0 && --n != 0) {
148 do {
149 if ((*d++ = *s++) == 0)
150 break;
151 } while (--n != 0);
152 }
153
154 /* Not enough room in dst, add NUL and traverse rest of src */
155 if (n == 0) {
156 if (siz != 0)
157 *d = '\0'; /* NUL-terminate dst */
158 while (*s++)
159 ;
160 }
161
162 return(s - src - 1); /* count does not include NUL */
163}
164
165#endif /* RC_NEED_STRLCPY */
166
174int rc_set_netns(const char *net_namespace, int *prev_ns_handle)
175{
176 int rc = 0;
177#ifdef __linux__
178 rc = -1;
179 static const char* crt_nsnet = "/proc/self/ns/net";
180 int sock_ns_fd = -1;
181 char sock_nsnet[NSNET_SZ];
182
183 if (NULL == net_namespace) {
184 rc_log(LOG_ERR, "Namespace not provided");
185 return rc;
186 }
187 if (NULL == prev_ns_handle) {
188 rc_log(LOG_ERR, "NULL NS handle for: %s", net_namespace);
189 return rc;
190 }
191 *prev_ns_handle = -1;
192 snprintf(sock_nsnet, NSNET_SZ, "/var/run/netns/%s", net_namespace);
193 do {
194 *prev_ns_handle = open(crt_nsnet, O_RDONLY);
195 if (*prev_ns_handle < 0) {
196 rc_log(LOG_ERR, "Cannot open %s errno=%s(%d)", crt_nsnet, strerror (errno), errno);
197 break;
198 }
199 sock_ns_fd = open(sock_nsnet, O_RDONLY);
200 if (sock_ns_fd < 0) {
201 rc_log(LOG_ERR, "Cannot open %s errno=%s(%d)", sock_nsnet, strerror (errno), errno);
202 break;
203 }
204 if (setns(sock_ns_fd, CLONE_NEWNET) < 0) {
205 rc_log(LOG_ERR, "'setns' set failed for %s errno=%s(%d)", sock_nsnet,
206 strerror(errno), errno);
207 break;
208 }
209 rc = 0;
210 }while (0);
211 if (sock_ns_fd >= 0) {
212 (void)close(sock_ns_fd);
213 }
214 if (rc != 0) {
215 if (*prev_ns_handle >=0 ) {
216 (void)close(*prev_ns_handle);
217 *prev_ns_handle = -1;
218 }
219 }
220#else
221 rc_log(LOG_ERR, "Not a Linux system. No operation performed");
222#endif
223 return rc;
224}
225
233int rc_reset_netns(int *prev_ns_handle)
234{
235 int rc = 0;
236#ifdef __linux__
237 if (NULL == prev_ns_handle) {
238 rc_log(LOG_ERR, "NULL NS handle");
239 return -1;
240 }
241 if (setns(*prev_ns_handle, CLONE_NEWNET) < 0) {
242 rc_log(LOG_ERR, "'setns' - reset failed errno=%s(%d)", strerror (errno), errno);
243 }
244 if (close(*prev_ns_handle) != 0) {
245 rc_log(LOG_ERR, "Close error fd=%d errno=%s(%d)", *prev_ns_handle, strerror (errno), errno);
246 rc = -1;
247 }
248 *prev_ns_handle = -1;
249#else
250 rc_log(LOG_ERR, "Not a Linux system. No operation performed");
251#endif
252 return rc;
253}