mirror of
https://github.com/kenzok8/small-package.git
synced 2026-01-14 11:25:06 +08:00
402 lines
8.6 KiB
C
402 lines
8.6 KiB
C
#include <linux/init.h>
|
|
#include <linux/module.h>
|
|
#include <linux/types.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/string.h>
|
|
#include <linux/version.h>
|
|
#include "af_utils.h"
|
|
#define MAX_DUMP_STR_LEN 256
|
|
|
|
u_int32_t af_get_timestamp_sec(void)
|
|
{
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
|
|
struct timespec64 ts;
|
|
ktime_get_real_ts64(&ts);
|
|
return (u_int32_t)ts.tv_sec;
|
|
#else
|
|
struct timespec ts;
|
|
ts = current_kernel_time();
|
|
return ts.tv_sec;
|
|
#endif
|
|
|
|
}
|
|
|
|
int k_atoi(const char *str) {
|
|
int result = 0;
|
|
|
|
// Skip whitespace
|
|
while (*str == ' ' || *str == '\t') {
|
|
str++;
|
|
}
|
|
|
|
// Convert characters to integer
|
|
while (*str >= '0' && *str <= '9') {
|
|
result = result * 10 + (*str - '0');
|
|
str++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
char *k_trim(char *s)
|
|
{
|
|
char *start, *last, *bk;
|
|
int len;
|
|
|
|
start = s;
|
|
while (isspace(*start))
|
|
start++;
|
|
|
|
bk = last = s + strlen(s) - 1;
|
|
while (last > start && isspace(*last))
|
|
last--;
|
|
|
|
if ((s != start) || (bk != last))
|
|
{
|
|
len = last - start + 1;
|
|
strncpy(s, start, len);
|
|
s[len] = '\0';
|
|
}
|
|
return s;
|
|
}
|
|
|
|
int check_local_network_ip(unsigned int ip)
|
|
{
|
|
if ((ip & 0xffff0000) == 0xc0a80000)
|
|
return 1;
|
|
else if ((ip & 0xfff00000) == 0xac100000)
|
|
return 1;
|
|
else if ((ip & 0xff000000) == 0x0a000000)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void dump_str(char *name, unsigned char *p, int len)
|
|
{
|
|
char buf[MAX_DUMP_STR_LEN] = {0};
|
|
if (len > MAX_DUMP_STR_LEN) {
|
|
len = MAX_DUMP_STR_LEN - 1;
|
|
}
|
|
printk("%s: ",name);
|
|
strncpy(buf, p, len);
|
|
printk("[%s]\n", buf);
|
|
}
|
|
int isprint_char(unsigned char c)
|
|
{
|
|
if (c >= 0x20 && c <= 0x7e)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void print_hex_ascii(const unsigned char *data, size_t size) {
|
|
size_t i, j;
|
|
|
|
for (i = 0; i < size; i += 16) {
|
|
printk(KERN_CONT"%08lx ", (unsigned long)i);
|
|
for (j = 0; j < 16; ++j) {
|
|
if (i + j < size) {
|
|
printk(KERN_CONT"%02x ", data[i + j]);
|
|
} else {
|
|
printk(KERN_CONT" ");
|
|
}
|
|
}
|
|
|
|
printk(KERN_CONT" ");
|
|
|
|
for (j = 0; j < 16; ++j) {
|
|
if (i + j < size) {
|
|
unsigned char c = data[i + j];
|
|
printk(KERN_CONT"%c", isprint_char(c) ? c : '.');
|
|
}
|
|
}
|
|
|
|
printk(KERN_CONT"\n");
|
|
}
|
|
printk(KERN_CONT"---------------------------------------\n");
|
|
}
|
|
|
|
|
|
void dump_hex(char *name, unsigned char *p, int len)
|
|
{
|
|
int i;
|
|
if (len > MAX_DUMP_STR_LEN) {
|
|
len = MAX_DUMP_STR_LEN - 1;
|
|
}
|
|
printk("%s: ",name);
|
|
for (i = 0; i < len; i++) {
|
|
if (i % 16 == 0)
|
|
printk(KERN_CONT "\n");
|
|
printk(KERN_CONT "%02X ",*(p + i));
|
|
}
|
|
printk(KERN_CONT "\n");
|
|
}
|
|
|
|
#ifndef va_arg
|
|
typedef signed int acpi_native_int;
|
|
#ifndef _VALIST
|
|
#define _VALIST
|
|
typedef char *va_list;
|
|
#endif
|
|
|
|
#define _AUPBND (sizeof (acpi_native_int) - 1)
|
|
#define _ADNBND (sizeof (acpi_native_int) - 1)
|
|
|
|
|
|
#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))
|
|
#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
|
|
#define va_end(ap) (void) 0
|
|
#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
|
|
|
|
#endif
|
|
|
|
#ifndef TOLOWER
|
|
#define TOLOWER(x) ((x) | 0x20)
|
|
#endif
|
|
|
|
|
|
static long long k_simple_strtoll(const char *cp, char **endp, unsigned int base)
|
|
{
|
|
if (*cp == '-')
|
|
return -simple_strtoull(cp + 1, endp, base);
|
|
|
|
return simple_strtoull(cp, endp, base);
|
|
}
|
|
|
|
static int skip_atoi(const char **s)
|
|
{
|
|
int i=0;
|
|
while (isdigit(**s))
|
|
i = i*10 + *((*s)++) - '0';
|
|
return i;
|
|
}
|
|
|
|
char *skip_spaces(const char *str)
|
|
{
|
|
while (isspace(*str) && ((unsigned char )*str != 0xa0))
|
|
++str;
|
|
return (char *)str;
|
|
}
|
|
static int k_vsscanf(const char *buf, const char *fmt, va_list args)
|
|
{
|
|
const char *str = buf;
|
|
char *next;
|
|
char digit;
|
|
int num = 0;
|
|
u8 qualifier;
|
|
u8 base;
|
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)
|
|
int field_width;
|
|
#else
|
|
s16 field_width;
|
|
#endif
|
|
bool is_sign;
|
|
while (*fmt && *str) {
|
|
if (isspace(*fmt)) {
|
|
fmt = skip_spaces(++fmt);
|
|
str = skip_spaces(str);
|
|
}
|
|
|
|
if (*fmt != '%' && *fmt) {
|
|
if (*fmt++ != *str++)
|
|
break;
|
|
continue;
|
|
}
|
|
if (!*fmt)
|
|
break;
|
|
++fmt;
|
|
|
|
if (*fmt == '*') {
|
|
while (!isspace(*fmt) && *fmt != '%' && *fmt)
|
|
fmt++;
|
|
while (!isspace(*str) && *str)
|
|
str++;
|
|
continue;
|
|
}
|
|
field_width = -1;
|
|
if (isdigit(*fmt))
|
|
field_width = skip_atoi(&fmt);
|
|
qualifier = -1;
|
|
if (*fmt == 'h' || TOLOWER(*fmt) == 'l' ||
|
|
TOLOWER(*fmt) == 'z') {
|
|
qualifier = *fmt++;
|
|
if (unlikely(qualifier == *fmt)) {
|
|
if (qualifier == 'h') {
|
|
qualifier = 'H';
|
|
fmt++;
|
|
} else if (qualifier == 'l') {
|
|
qualifier = 'L';
|
|
fmt++;
|
|
}
|
|
}
|
|
}
|
|
if (!*fmt || !*str)
|
|
break;
|
|
base = 10;
|
|
is_sign = 0;
|
|
switch (*fmt++) {
|
|
case 'c':
|
|
{
|
|
char *s = (char *)va_arg(args, char*);
|
|
if (field_width == -1)
|
|
field_width = 1;
|
|
do {
|
|
*s++ = *str++;
|
|
} while (--field_width > 0 && *str);
|
|
num++;
|
|
}
|
|
continue;
|
|
case 's':
|
|
{
|
|
char *s = (char *)va_arg(args, char *);
|
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)
|
|
if(field_width == -1)
|
|
field_width = INT_MAX;
|
|
#else
|
|
if (field_width == -1)
|
|
field_width = SHRT_MAX;
|
|
#endif
|
|
str = skip_spaces(str);
|
|
|
|
while (*str && (!isspace(*str) || ((unsigned char )*str == 0xA0) )&& field_width--)
|
|
*s++ = *str++;
|
|
*s = '\0';
|
|
num++;
|
|
}
|
|
continue;
|
|
case 'n':
|
|
{
|
|
int *i = (int *)va_arg(args, int*);
|
|
*i = str - buf;
|
|
}
|
|
continue;
|
|
case 'o':
|
|
base = 8;
|
|
break;
|
|
case 'x':
|
|
case 'X':
|
|
base = 16;
|
|
break;
|
|
case 'i':
|
|
base = 0;
|
|
case 'd':
|
|
is_sign = 1;
|
|
case 'u':
|
|
break;
|
|
case '%':
|
|
if (*str++ != '%')
|
|
return num;
|
|
continue;
|
|
default:
|
|
return num;
|
|
}
|
|
str = skip_spaces(str);
|
|
digit = *str;
|
|
if (is_sign && digit == '-')
|
|
digit = *(str + 1);
|
|
if (!digit
|
|
|| (base == 16 && !isxdigit(digit))
|
|
|| (base == 10 && !isdigit(digit))
|
|
|| (base == 8 && (!isdigit(digit) || digit > '7'))
|
|
|| (base == 0 && !isdigit(digit)))
|
|
break;
|
|
|
|
switch (qualifier) {
|
|
case 'H':
|
|
if (is_sign) {
|
|
signed char *s = (signed char *)va_arg(args, signed char *);
|
|
*s = (signed char)simple_strtol(str, &next, base);
|
|
} else {
|
|
unsigned char *s = (unsigned char *)va_arg(args, unsigned char *);
|
|
*s = (unsigned char)simple_strtoul(str, &next, base);
|
|
}
|
|
break;
|
|
case 'h':
|
|
if (is_sign) {
|
|
short *s = (short *)va_arg(args, short *);
|
|
*s = (short)simple_strtol(str, &next, base);
|
|
} else {
|
|
unsigned short *s = (unsigned short *)va_arg(args, unsigned short *);
|
|
*s = (unsigned short)simple_strtoul(str, &next, base);
|
|
}
|
|
break;
|
|
case 'l':
|
|
if (is_sign) {
|
|
long *l = (long *)va_arg(args, long *);
|
|
*l = simple_strtol(str, &next, base);
|
|
} else {
|
|
unsigned long *l = (unsigned long *)va_arg(args, unsigned long *);
|
|
*l = simple_strtoul(str, &next, base);
|
|
}
|
|
break;
|
|
case 'L':
|
|
if (is_sign) {
|
|
long long *l = (long long *)va_arg(args, long long *);
|
|
*l = k_simple_strtoll(str, &next, base);
|
|
} else {
|
|
unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *);
|
|
*l = simple_strtoull(str, &next, base);
|
|
}
|
|
break;
|
|
case 'Z':
|
|
case 'z':
|
|
{
|
|
size_t *s = (size_t *)va_arg(args, size_t *);
|
|
*s = (size_t)simple_strtoul(str, &next, base);
|
|
}
|
|
break;
|
|
default:
|
|
if (is_sign) {
|
|
int *i = (int *)va_arg(args, int *);
|
|
*i = (int)simple_strtol(str, &next, base);
|
|
} else {
|
|
unsigned int *i = (unsigned int *)va_arg(args, unsigned int*);
|
|
*i = (unsigned int)simple_strtoul(str, &next, base);
|
|
}
|
|
break;
|
|
}
|
|
num++;
|
|
if (!next)
|
|
break;
|
|
str = next;
|
|
}
|
|
if (*fmt == '%' && *(fmt + 1) == 'n') {
|
|
int *p = (int *)va_arg(args, int *);
|
|
*p = str - buf;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
|
|
int k_sscanf(const char *buf, const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
int i;
|
|
va_start(args, fmt);
|
|
i = k_vsscanf(buf, fmt, args);
|
|
va_end(args);
|
|
return i;
|
|
}
|
|
|
|
|
|
int mac_to_hex(u8 *mac, u8 *mac_hex)
|
|
{
|
|
u32 mac_tmp[6];
|
|
int ret = 0, i = 0;
|
|
ret = sscanf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
(unsigned int *)&mac_tmp[0],
|
|
(unsigned int *)&mac_tmp[1],
|
|
(unsigned int *)&mac_tmp[2],
|
|
(unsigned int *)&mac_tmp[3],
|
|
(unsigned int *)&mac_tmp[4],
|
|
(unsigned int *)&mac_tmp[5]);
|
|
if (6 != ret)
|
|
return -1;
|
|
for (i = 0; i < 6; i++)
|
|
{
|
|
mac_hex[i] = mac_tmp[i];
|
|
}
|
|
return 0;
|
|
} |