1/*
2 * Common utility functions across router code
3 *
4 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: common_utils.c 473329 2014-04-29 00:37:52Z $
19 */
20
21#include <typedefs.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <dirent.h>
25
26#include <string.h>
27#include <stdarg.h>
28#include <errno.h>
29#include <assert.h>
30#include <fcntl.h>
31#include <limits.h>
32#include <unistd.h>
33#include <signal.h>
34#include <string.h>
35#include <ctype.h>
36#include <sys/types.h>
37#include <sys/time.h>
38#include <sys/stat.h>
39#include <sys/wait.h>
40#include <sys/ioctl.h>
41
42#include <bcmnvram.h>
43#include <shutils.h>
44#include "common_utils.h"
45
46char*
47strncpy_n(char *destination, const char *source, size_t num)
48{
49	char *ret = strncpy(destination, source, num - 1);
50	destination[num - 1] = '\0';
51	return ret;
52}
53
54unsigned long long
55getTimestamp(void)
56{
57	unsigned long long ts;
58	struct timeval now;
59	gettimeofday(&now, NULL);
60	ts = (unsigned long long)now.tv_sec * 1000 + now.tv_usec / 1000;
61	return ts;
62}
63
64void
65append_numto_hexStr(char octetstr[], int octetstr_len, int num)
66{
67	char temp[3] = {0};
68	memset(temp, 0, sizeof(temp));
69	snprintf(temp, sizeof(temp), OCTET, num);
70	strncat(octetstr, temp, min(strlen(temp), octetstr_len - strlen(octetstr)));
71}
72
73int
74is_duplicate_octet(uint8* haystack, size_t size, uint8 needle)
75{
76	assert(haystack);
77	int iter = 0;
78
79	if (needle == 255 || needle == 0) {
80		return FALSE;
81	} else {
82		for (iter = 0; iter < size; iter++) {
83			if (haystack[iter] == needle)
84				return TRUE;
85		}
86	}
87
88	return FALSE;
89}
90
91int
92is_octet_range_overlapping(uint8* haystack, size_t size, uint8 low_needle, uint8 high_needle)
93{
94	assert(haystack);
95	int iter = 0, low_iter = 0, high_iter = 0;
96
97	if (low_needle == 255 && high_needle == 255) {
98		return FALSE;
99	} else {
100		for (iter = 0; iter < size; iter++) {
101			low_iter = haystack[(iter*2)];
102			high_iter = haystack[(iter*2)+1];
103
104			if ((low_iter <= high_needle) && (low_needle <= high_iter))
105				return TRUE;
106		}
107	}
108
109	return FALSE;
110}
111
112void
113bytes_to_hex(uchar* str, int strbuflen, uchar* utf8, int utf8buflen)
114{
115	char temp[3] = {0};
116	uchar *src = str, *dst = utf8;
117	int len = strlen((char*)src), i, optlen;
118	optlen = len < (utf8buflen-1) ? len : (utf8buflen-1);
119
120	for (i = 0; i < optlen; i++) {
121		memset(temp, 0, sizeof(temp));
122		snprintf(temp, sizeof(temp), OCTET, (uchar)src[i]);
123		*dst++ = temp[0];
124		*dst++ = temp[1];
125	}
126}
127
128void
129hex_to_bytes(uchar* str, int strbuflen, uchar* utf8, int utf8buflen)
130{
131	char temp[3] = {0};
132	uchar *src = utf8, *dst = str;
133	int len = strlen((char*)src)/2, i, optlen;
134	optlen = len < strbuflen ? len : strbuflen;
135
136	for (i = 0; i < optlen; i++) {
137		memset(temp, 0, sizeof(temp));
138		temp[0] = src[0];
139		temp[1] = src[1];
140		temp[2] = NULL_CH;
141		*dst++ = (uchar) strtoul(temp, NULL, 16);
142		src += 2;
143	}
144}
145
146int
147get_hex_data(uchar *data_str, uchar *hex_data, int len)
148{
149	uchar *src, *dest;
150	uchar val;
151	int idx;
152	char hexstr[3] = {0};
153
154	src = data_str;
155	dest = hex_data;
156
157	for (idx = 0; idx < len; idx++) {
158		hexstr[0] = src[0];
159		hexstr[1] = src[1];
160		hexstr[2] = NULL_CH;
161
162		val = (uchar) strtoul(hexstr, NULL, 16);
163
164		*dest++ = val;
165		src += 2;
166	}
167
168	return 0;
169}
170
171int
172reallocate_string(char** string, const char* newstring)
173{
174	int newlength = 0;
175
176	if (newstring)
177		newlength = strlen(newstring);
178
179	if (*string)
180		free(*string);
181
182	if (newlength <= 0)
183		return 0;
184
185	*string = (char*)malloc(newlength+1);
186	if (*string == 0) {
187		return 0;
188	}
189
190	strcpy(*string, newstring);
191
192	return 1;
193}
194
195void *
196memmem(const void *l, size_t l_len, const void *s, size_t s_len)
197{
198	register char *cur, *last;
199	const char *cl = (const char *)l;
200	const char *cs = (const char *)s;
201
202	/* we need something to compare */
203	if (l_len == 0 || s_len == 0)
204		return NULL;
205
206	/* "s" must be smaller or equal to "l" */
207	if (l_len < s_len)
208		return NULL;
209
210	/* special case where s_len == 1 */
211	if (s_len == 1)
212		return memchr(l, (int)*cs, l_len);
213
214	/* the last position where its possible to find "s" in "l" */
215	last = (char *)cl + l_len - s_len;
216
217	for (cur = (char *)cl; cur <= last; cur++)
218		if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
219			return cur;
220
221	return NULL;
222}
223