446 lines
11 KiB
C
446 lines
11 KiB
C
//
|
|
// Created by xajhu on 2021/7/2 0002.
|
|
//
|
|
#include <string.h>
|
|
#include <uv.h>
|
|
#include <sys/vfs.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <sys/sendfile.h>
|
|
#include <linux/if.h>
|
|
#include <sys/ioctl.h>
|
|
#include <linux/if_ether.h>
|
|
#include <sys/time.h>
|
|
#include <netinet/udp.h>
|
|
#include <netinet/ip.h>
|
|
|
|
#include "user_errno.h"
|
|
#include "misc.h"
|
|
#include "zlog_module.h"
|
|
#include "common.h"
|
|
#include "sds/sds.h"
|
|
|
|
PSYS_NIC_INFO g_sysNicInfo = NULL;
|
|
|
|
const char *basename_v2(const char *path) {
|
|
const char *tail = strrchr(path, '/');
|
|
return tail ? tail + 1 : path;
|
|
}
|
|
|
|
int dirname_v2(const char *path, char *dir) {
|
|
const char *tail = strrchr(path, '/');
|
|
|
|
if (tail) {
|
|
memcpy(dir, path, tail - path);
|
|
dir[tail - path] = 0;
|
|
} else {
|
|
strcpy(dir, "./");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
unsigned long long get_partition_free_size(const char *pPartPath) {
|
|
struct statfs myStatfs;
|
|
unsigned long long freeSize;
|
|
|
|
if (statfs(pPartPath, &myStatfs) == -1) {
|
|
return 0;
|
|
}
|
|
|
|
freeSize = myStatfs.f_bsize * myStatfs.f_bfree;
|
|
|
|
return freeSize;
|
|
}
|
|
|
|
int copy_file(const char *pSrc, const char *pDest) {
|
|
int fdSrc, fdDest;
|
|
struct stat st;
|
|
ssize_t sz;
|
|
|
|
if (stat(pSrc, &st) != 0) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Get File %s Size Error\n", pSrc);
|
|
return (-ERR_GET_FILE_SIZE);
|
|
}
|
|
|
|
fdSrc = open(pSrc, O_RDONLY);
|
|
|
|
if (fdSrc < 0) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Open File %s Error\n", pSrc);
|
|
return (-ERR_OPEN_FILE);
|
|
}
|
|
|
|
fdDest = open(pDest, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
|
|
|
if (fdDest < 0) {
|
|
close(fdSrc);
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Open File %s Error\n", pDest);
|
|
return (-ERR_OPEN_FILE);
|
|
}
|
|
|
|
sz = sendfile(fdDest, fdSrc, NULL, st.st_size);
|
|
|
|
if (sz != st.st_size) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Copy File Size Error: %zd, %ld\n", sz, st.st_size);
|
|
close(fdSrc);
|
|
close(fdDest);
|
|
return (-ERR_COPY_FILE);
|
|
}
|
|
|
|
fsync(fdDest);
|
|
|
|
close(fdSrc);
|
|
close(fdDest);
|
|
|
|
return (0);
|
|
}
|
|
|
|
char *bin2hex(char *p, const unsigned char *cp, unsigned int count) {
|
|
static const char hex_asc[] = "0123456789abcdef";
|
|
while (count) {
|
|
unsigned char c = *cp++;
|
|
/* put lowercase hex digits */
|
|
*p++ = (char)(0x20 | hex_asc[c >> 4]);
|
|
*p++ = (char)(0x20 | hex_asc[c & 0xf]);
|
|
count--;
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
int shell_with_output(const char *pCmd, char **pResult) {
|
|
FILE *pFile = NULL;
|
|
unsigned int uRdSize;
|
|
char *pCmdOut;
|
|
|
|
*pResult = NULL;
|
|
|
|
if (pCmd == NULL || strlen(pCmd) == 0) {
|
|
return (-ERR_INPUT_PARAMS);
|
|
}
|
|
|
|
pFile = popen(pCmd, "r");
|
|
|
|
if (pFile == NULL) {
|
|
return (-ERR_OPEN_FILE);
|
|
}
|
|
|
|
*pResult = (char *)malloc(4096);
|
|
pCmdOut = *pResult;
|
|
|
|
uRdSize = fread(pCmdOut, sizeof(char), 4096, pFile);
|
|
|
|
pCmdOut[uRdSize] = 0;
|
|
|
|
if (pCmdOut[strlen(pCmdOut) - 1] == '\n') {
|
|
pCmdOut[strlen(pCmdOut) - 1] = 0;
|
|
}
|
|
|
|
pclose(pFile);
|
|
return ERR_SUCCESS;
|
|
}
|
|
|
|
int file_exists(const char *pPath) {
|
|
if ((access(pPath, F_OK)) == -1) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
const char *get_cur_process_dir() {
|
|
static char g_exePath[4096] = {0};
|
|
|
|
size_t bufSize = 4096L;
|
|
|
|
if (strlen((const char *)g_exePath) == 0) {
|
|
memset(g_exePath, 0, 4096);
|
|
uv_cwd(g_exePath, &bufSize);
|
|
}
|
|
|
|
return (const char *)g_exePath;
|
|
}
|
|
|
|
unsigned long long get_current_time_ms() {
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
|
}
|
|
|
|
int str_to_mac(const char *str, unsigned char mac[6]) {
|
|
int i;
|
|
char *s, *e;
|
|
|
|
if ((mac == NULL) || (str == NULL)) {
|
|
return -ERR_INPUT_PARAMS;
|
|
}
|
|
|
|
s = (char *)str;
|
|
for (i = 0; i < 6; ++i) {
|
|
mac[i] = s ? strtoul(s, &e, 16) : 0;
|
|
if (s) {
|
|
s = (*e) ? e + 1 : e;
|
|
}
|
|
}
|
|
return ERR_SUCCESS;
|
|
}
|
|
|
|
int str_to_ipaddr(const char *pIp, unsigned int *ipAddr) {
|
|
struct in_addr addr;
|
|
int ret = inet_aton(pIp, &addr);
|
|
|
|
if (ret != 0) {
|
|
*ipAddr = addr.s_addr;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int get_nic_info(const char *pName,
|
|
unsigned int *pIp,
|
|
unsigned int *pNetmask,
|
|
unsigned int *pBoardcast,
|
|
unsigned char *pMac) {
|
|
int sock;
|
|
struct ifreq ifr;
|
|
int err = ERR_SUCCESS;
|
|
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
|
if (sock < 0) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Get local NIC information failed\n");
|
|
return -ERR_SYS_INIT;
|
|
}
|
|
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
strcpy(ifr.ifr_name, pName);
|
|
|
|
if (pIp) {
|
|
if (ioctl(sock, SIOCGIFADDR, &ifr) != 0) {
|
|
err = ERR_MISC_GET_IPADDR;
|
|
} else {
|
|
*pIp = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
|
}
|
|
}
|
|
|
|
if (pNetmask) {
|
|
if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
|
|
*pNetmask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
|
} else {
|
|
err = ERR_MISC_GET_NETMASK;
|
|
}
|
|
}
|
|
|
|
if (pBoardcast) {
|
|
if (ioctl(sock, SIOCGIFBRDADDR, &ifr) == 0) {
|
|
*pBoardcast = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
|
} else {
|
|
err = ERR_MISC_GET_GATEWAY;
|
|
}
|
|
}
|
|
|
|
if (pMac) {
|
|
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
|
|
memcpy(pMac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
|
} else {
|
|
err = ERR_MISC_GET_MACADDR;
|
|
}
|
|
}
|
|
|
|
close(sock);
|
|
return err;
|
|
}
|
|
|
|
const char *u32_to_str_ip(unsigned int ip) {
|
|
struct in_addr s = {.s_addr = ip};
|
|
return inet_ntoa(s);
|
|
}
|
|
|
|
int get_all_network_info(PSYS_NIC_INFO pInfo) {
|
|
int i;
|
|
unsigned long nicCnt;
|
|
struct ifreq buf[4096];
|
|
struct ifconf ifc;
|
|
PSYS_NIC_INFO pNicInfo;
|
|
PNIC_CTX pNic;
|
|
|
|
if (pInfo == NULL) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Malloc memory failed, size: %lu\n", sizeof(SYS_NIC_INFO));
|
|
return -ERR_INPUT_PARAMS;
|
|
}
|
|
|
|
if (g_sysNicInfo != NULL) {
|
|
pInfo->nicCnt = g_sysNicInfo->nicCnt;
|
|
pInfo->pNicCtx = g_sysNicInfo->pNicCtx;
|
|
return ERR_SUCCESS;
|
|
}
|
|
|
|
pNicInfo = (PSYS_NIC_INFO)malloc(sizeof(SYS_NIC_INFO));
|
|
|
|
if (pNicInfo == NULL) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Malloc memory failed, size: %lu\n", sizeof(SYS_NIC_INFO));
|
|
return -ERR_MALLOC_MEMORY;
|
|
}
|
|
|
|
memset(pNicInfo, 0, sizeof(SYS_NIC_INFO));
|
|
|
|
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
|
if (sock == -1) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Create socket failed\n");
|
|
free(pNicInfo);
|
|
return -ERR_SOCK_CREATE;
|
|
}
|
|
memset(&ifc, 0, sizeof(struct ifconf));
|
|
ifc.ifc_len = sizeof(struct ifreq) * 4096;
|
|
ifc.ifc_buf = (char *)buf;
|
|
|
|
if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
|
|
close(sock);
|
|
free(pNicInfo);
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "IOCTL SIOCGIFCONF socket failed\n");
|
|
return -ERR_SYS_CALL;
|
|
}
|
|
|
|
nicCnt = ifc.ifc_len / sizeof(struct ifreq);
|
|
pNicInfo->pNicCtx = (PNIC_CTX)malloc(sizeof(NIC_CTX) * nicCnt);
|
|
|
|
if (pNicInfo->pNicCtx == NULL) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Malloc memory failed, size: %lu * %lu\n", sizeof(NIC_CTX), nicCnt);
|
|
free(pNicInfo);
|
|
close(sock);
|
|
return -ERR_MALLOC_MEMORY;
|
|
}
|
|
|
|
LOG_MOD(trace, ZLOG_MOD_MISC, "Malloc memory size: %lu * %lu\n", sizeof(NIC_CTX), nicCnt);
|
|
|
|
memset(pNicInfo->pNicCtx, 0, sizeof(NIC_CTX) * nicCnt);
|
|
|
|
pNic = &pNicInfo->pNicCtx[0];
|
|
for (i = 0; i < nicCnt; i++) {
|
|
U32 ipAddr;
|
|
U32 netmaskAddr;
|
|
U32 bcAddr;
|
|
U8 mac[ETH_ALEN];
|
|
int ret = get_nic_info(buf[i].ifr_name, &ipAddr, &netmaskAddr, &bcAddr, mac);
|
|
|
|
if (ret == ERR_SUCCESS) {
|
|
strcpy(pNic->ethName, buf[i].ifr_name);
|
|
pNic->ipv4Addr = ipAddr;
|
|
pNic->ipv4Mask = netmaskAddr;
|
|
pNic->ipv4Boardcast = bcAddr;
|
|
memcpy(pNic->mac, mac, ETH_ALEN);
|
|
|
|
LOG_MOD(trace, ZLOG_MOD_MISC, "Network intreface(%d): %s\n", pNicInfo->nicCnt, pNic->ethName);
|
|
LOG_MOD(trace, ZLOG_MOD_MISC, "\t\tIP Address\t:%s\n", u32_to_str_ip(ipAddr));
|
|
LOG_MOD(trace, ZLOG_MOD_MISC, "\t\tNetmask Address\t:%s\n", u32_to_str_ip(netmaskAddr));
|
|
LOG_MOD(trace, ZLOG_MOD_MISC, "\t\tBoardcast Address\t:%s\n", u32_to_str_ip(bcAddr));
|
|
|
|
pNicInfo->nicCnt++;
|
|
pNic++;
|
|
} else {
|
|
LOG_MOD(warn,
|
|
ZLOG_MOD_MISC,
|
|
"Get system nic(%s) information error:%s(%d)\n",
|
|
buf[i].ifr_name,
|
|
getErrorEnumNameString(ret),
|
|
ret);
|
|
}
|
|
}
|
|
close(sock);
|
|
|
|
g_sysNicInfo = pNicInfo;
|
|
pInfo->nicCnt = g_sysNicInfo->nicCnt;
|
|
pInfo->pNicCtx = g_sysNicInfo->pNicCtx;
|
|
return ERR_SUCCESS;
|
|
}
|
|
|
|
const char *get_cur_process_name() {
|
|
static char g_exeName[1024] = {0};
|
|
|
|
if (strlen(g_exeName) > 0) {
|
|
return basename_v2(g_exeName);
|
|
}
|
|
|
|
memset(g_exeName, 0, 1024);
|
|
if (readlink("/proc/self/exe", g_exeName, 1023) <= 0) {
|
|
return NULL;
|
|
}
|
|
|
|
return basename_v2(g_exeName);
|
|
}
|
|
|
|
unsigned short calc_checksum(unsigned short *buffer, int size, U32 sum) {
|
|
unsigned long cksum = ((sum & 0xFFFF0000) >> 16) + (sum & 0xFFFF);
|
|
|
|
while (size > 1) {
|
|
cksum += *buffer++;
|
|
size -= sizeof(unsigned short);
|
|
}
|
|
|
|
if (size) {
|
|
cksum += *(unsigned short *)buffer;
|
|
}
|
|
|
|
cksum = (cksum >> 16) + (cksum & 0xffff);
|
|
cksum += (cksum >> 16);
|
|
|
|
return cksum;
|
|
//return (unsigned short)(~cksum);
|
|
}
|
|
|
|
unsigned short ip_checksum(unsigned char *pIp) {
|
|
unsigned int csum;
|
|
struct iphdr *pIph = (struct iphdr *)pIp;
|
|
pIph->check = 0;
|
|
|
|
csum = calc_checksum((unsigned short *)pIp, 20, 0);
|
|
|
|
csum = ((csum & 0xFFFF0000) >> 16) + (csum & 0xFFFF);
|
|
return (unsigned short)(~csum);
|
|
}
|
|
|
|
unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned char *pUdp) {
|
|
unsigned char padBuf[12];
|
|
unsigned int csum;
|
|
struct udphdr *pUhd = (struct udphdr *)pUdp;
|
|
|
|
memcpy(&padBuf[0], &saddr, 4);
|
|
memcpy(&padBuf[4], &daddr, 4);
|
|
padBuf[8] = 0;
|
|
padBuf[9] = 17;
|
|
padBuf[10] = pUdp[4];
|
|
padBuf[11] = pUdp[5];
|
|
|
|
pUhd->check = 0;
|
|
csum = calc_checksum((unsigned short *)pUdp, ntohs(pUhd->len), 0);
|
|
csum = calc_checksum((unsigned short *)padBuf, 12, csum);
|
|
|
|
csum = ((csum & 0xFFFF0000) >> 16) + (csum & 0xFFFF);
|
|
return (unsigned short)(~csum);
|
|
}
|
|
|
|
int string_mac_to_bytes(const char *pStrMac, unsigned char macByte[6]) {
|
|
sds *tokens;
|
|
int i, nCnt;
|
|
|
|
if (pStrMac == NULL || strlen(pStrMac) != strlen("00:00:00:00:00:00")) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Input params error\n");
|
|
return -ERR_INPUT_PARAMS;
|
|
}
|
|
|
|
tokens = sdssplitlen(pStrMac, (int)strlen(pStrMac), ":", 1, &nCnt);
|
|
|
|
if (nCnt != 6) {
|
|
LOG_MOD(error, ZLOG_MOD_MISC, "Input MAC[%s] error: %d\n", pStrMac, nCnt);
|
|
return -ERR_INPUT_PARAMS;
|
|
}
|
|
|
|
for (i = 0; i < nCnt; i++) {
|
|
macByte[i] = strtoul(tokens[i], NULL, 16);
|
|
}
|
|
|
|
if (tokens) {
|
|
sdsfreesplitres(tokens, nCnt);
|
|
}
|
|
|
|
return ERR_SUCCESS;
|
|
} |