#include #include #include #include #include #include #include #include #include "elog.h" #include "sys.h" #include "upgrade.h" #include "paras.h" #include "cfg.h" #if 0 //#define LOGE log_e //#define LOGD log_d #else #define LOGD printf #define LOGE printf #endif //#define USE_BASH #define USE_FILE //#define USE_API #define DFLT_NIC "eth0" //#define FILE_INTERFACE "/root/interfaces" #define FILE_INTERFACE "/etc/network/interfaces" typedef struct { char *pbuf; int dlen; int blen; }node_t; static int set_net(NetworkInfo_t *para); static int node_free(node_t *nd) { if(!nd) { return -1; } free(nd->pbuf); nd->pbuf = NULL; nd->dlen = 0; nd->blen = 0; } static int exe_cmd(char *cmd, node_t *nd) { int r=0; FILE *fp=NULL; char *pbuf=NULL; int onelen=1000; int dlen=0,blen=onelen; pbuf = malloc(onelen); if(!pbuf) { return -1; } fp = popen(cmd, "r"); if (fp == NULL) { return -1; } while(1) { r = fread(pbuf+dlen, sizeof(char), onelen, fp); if(r<=0) { LOGE("exe_cmd fread failed\n"); break; } dlen += r; if(dlen+onelen>blen) { char* p = realloc(pbuf, dlen+onelen); if(!p) { LOGE("exe_cmd relloac %d failed\n", dlen+onelen); free(pbuf); pclose(fp); return -1; } pbuf = p; blen = dlen+onelen; } } pclose(fp); nd->pbuf = pbuf; nd->dlen = dlen; nd->blen = blen; return 0; } //////////////////////////////////////////////////////////////////// int sys_reboot(void) { int r=0; r = system("reboot -f"); if(r) { LOGE("sys_reboot failed!\n"); return -1; } return r; } #include "upgrade.h" int sys_set_factory(void) { int r=0; #ifdef KEY_PARAS_IN_FILE r = paras_reset(); #else char dir[100],tmp[200]; extern GlobalDeviceManager __globalDeviceManage; sqlite_deinit(&__globalDeviceManage.db); sys_get_path(dir, ""); snprintf(tmp, "cp -f %s/%s %s/%s", dir, DATABASE_BAK_NAME, dir, DATABASE_NAME); LOGD("___ %s\n", tmp); r = system(tmp); if(r==0) { r = set_net(&DFLT_PARAS.dev._network_info); if(r==0) { exit(0); } } #endif return r; } int sys_get_path(char *path, char *name) { char tmp[500]; pid_t pid = getpid(); snprintf(tmp, sizeof(tmp), "/proc/%d/exe", pid); readlink(tmp, path, sizeof(tmp)); char *p = strrchr(path, '/'); if(p && strlen(path)>1) { *p = 0; if(p && strlen(name)>0) { strcat(path, "/"); strcat(path, name); } } return 0; } //////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include void print_net(char*s, NetworkInfo_t *p) { LOGD("__%s__net.mode: %d\n", s, p->mode); LOGD("__%s__net.addr: %s\n", s, p->ip_address); LOGD("__%s__net.mask: %s\n", s, p->mask); LOGD("__%s__net.gateway: %s\n", s, p->gateway); LOGD("__%s__net.dns1: %s\n", s, p->dns1); LOGD("__%s__net.dns2: %s\n", s, p->dns2); } void print_modbus(char*s, ModbusInfo_t *p) { LOGD("__%s__mbus.mode: %d\n", s, p->product_modbus_type); LOGD("__%s__mbus.addr: %d\n", s, p->product_modbus_baud); LOGD("__%s__mbus.mask: %d\n", s, p->product_modbus_addr); LOGD("__%s__mbus.mask: %s\n", s, p->product_relay_ctrl_port); } static int set_ipaddr(int family, const char* iface, const char* addr, const char* netmask) { struct ifreq ifr; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; int fd = socket(family, SOCK_DGRAM, 0); if (fd < 0) { LOGD("socket SOCK_DGRAM failed\n"); return -1; } strcpy(ifr.ifr_name, iface); sin = (struct sockaddr_in*)&ifr.ifr_addr; sin6 = (struct sockaddr_in6*)&ifr.ifr_addr; if(family==AF_INET) { sin->sin_family = family; sin->sin_port = 0; inet_pton(family, addr, &sin->sin_addr); if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) { LOGD("ioctl SIOCSIFADDR \n"); close(fd); return -1; } sin->sin_family = family; inet_pton(family, netmask, &sin->sin_addr); if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) { LOGD("ioctl SIOCSIFNETMASK \n"); close(fd); return -1; } } else { sin6->sin6_family = family; sin6->sin6_port = 0; inet_pton(family, addr, &sin6->sin6_addr); if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) { LOGD("ioctl SIOCSIFADDR \n"); close(fd); return -1; } sin6->sin6_family = family; inet_pton(family, netmask, &sin6->sin6_addr); if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) { LOGD("ioctl SIOCSIFNETMASK \n"); close(fd); return -1; } } close(fd); return 0; } static int get_ipaddr(int family, char* iface, char* addr, char* netmask) { struct ifaddrs *ifap, *ifa; if (getifaddrs(&ifap) == -1) { LOGE("getifaddrs() error\n"); return -1; } for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr != NULL && ifa->ifa_addr->sa_family == family) { if(family==IP_V4) { struct sockaddr_in *sa,*msk; sa = (struct sockaddr_in *) ifa->ifa_addr; msk = (struct sockaddr_in *) ifa->ifa_netmask; inet_ntop(family, &sa->sin_addr, addr, INET6_ADDRSTRLEN); inet_ntop(family, &msk->sin_addr, netmask, INET6_ADDRSTRLEN); } else { struct sockaddr_in6 *sa,*msk; sa = (struct sockaddr_in6 *) ifa->ifa_addr; msk = (struct sockaddr_in6 *) ifa->ifa_netmask; inet_ntop(family, &sa->sin6_addr, addr, INET6_ADDRSTRLEN); inet_ntop(family, &msk->sin6_addr, netmask, INET6_ADDRSTRLEN); } } } freeifaddrs(ifap); return 0; } static int set_gateway(int family, const char* gateway) { struct rtentry rt; int fd; fd = socket(family, SOCK_DGRAM, 0); if (fd < 0) { LOGE("socket SOCK_DGRAM failed\n"); return -1; } memset(&rt, 0, sizeof(rt)); if(family==AF_INET) { struct sockaddr_in* sin; sin = (struct sockaddr_in*)&rt.rt_gateway; sin->sin_family = family; sin->sin_port = 0; inet_pton(family, gateway, &sin->sin_addr); sin = (struct sockaddr_in*)&rt.rt_dst; sin->sin_family = family; sin->sin_addr.s_addr = 0; } else { struct sockaddr_in6* sin; sin = (struct sockaddr_in6*)&rt.rt_gateway; sin->sin6_family = family; sin->sin6_port = 0; inet_pton(family, gateway, &sin->sin6_addr); sin = (struct sockaddr_in6*)&rt.rt_dst; sin->sin6_family = family; //sin->sin6_addr.s_addr[0] = 0; } rt.rt_flags = RTF_GATEWAY; if (ioctl(fd, SIOCADDRT, &rt) < 0) { LOGE("ioctl SIOCADDRT failed\n"); close(fd); return -1; } close(fd); return 0; } static int get_gateway(int family, const char* gateway) { #if 0 int sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sockfd == -1) { log_e("set_gateway, socket AF_NETLINK error\n"); return -1; } struct sockaddr_nl sa; memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { log_e("set_gateway, bind error\n"); return -1; } struct nlreq req; memset(&req, 0, sizeof(req)); req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); req.hdr.nlmsg_type = RTM_GETROUTE; req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; req.msg.rtm_family = family; req.msg.rtm_table = RT_TABLE_MAIN; req.msg.rtm_protocol = RTPROT_UNSPEC; req.msg.rtm_scope = RT_SCOPE_UNIVERSE; req.msg.rtm_type = RTN_UNICAST; struct iovec iov; memset(&iov, 0, sizeof(iov)); iov.iov_base = &req; iov.iov_len = req.hdr.nlmsg_len; struct msghdr msg; memset(&msg, 0, sizeof(msg)); msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); msg.msg_iov = &iov; msg.msg_iovlen = 1; char buf[BUFSIZE]; memset(buf, 0, sizeof(buf)); struct nlmsghdr *hdr; int len; if (sendmsg(sockfd, &msg, 0) == -1) { log_e("set_gateway, sendmsg error\n"); return -1; } while ((len = recv(sockfd, buf, sizeof(buf), 0)) > 0) { for (hdr = (struct nlmsghdr *) buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) { if (hdr->nlmsg_type == NLMSG_DONE) { goto finish; } if (hdr->nlmsg_type == NLMSG_ERROR) { log_e("set_gateway, NLMSG_ERROR\n"); return -1; } struct rtmsg *rt = (struct rtmsg *) NLMSG_DATA(hdr); if (rt->rtm_family != family || rt->rtm_table != RT_TABLE_MAIN || rt->rtm_type != RTN_UNICAST) { continue; } struct rtattr *attr; int attrlen; for (attr = (struct rtattr *) RTM_RTA(rt), attrlen = RTM_PAYLOAD(hdr); RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) { if (attr->rta_type == RTA_GATEWAY) { char gw_addr[INET_ADDRSTRLEN]; struct in_addr addr; memcpy(&addr, RTA_DATA(attr), sizeof(addr)); if (inet_ntop(family, &addr, gateway, INET6_ADDRSTRLEN) == NULL) { log_e("set_gateway, inet_ntop error\n"); continue; } printf("Gateway address: %s\n", gw_addr); log_i("set_gateway, Gateway address: %s\n"); goto finish; } } } } finish: close(sockfd); #endif return 0; } static int set_dhcp(int on) { return 0; } static int set_dns(int family, const char* iface, char* dns1, char *dns2) { int fd; struct ifreq ifr; #if 0 fd = socket(family, SOCK_DGRAM, 0); if (fd < 0) { log_e("socket SOCK_DGRAM failed\n"); return -1; } memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); struct sockaddr_in* addr = (struct sockaddr_in*)&ifr.ifr_addr; addr->sin_family = family; inet_pton(family, dns1, &addr->sin_addr); if (ioctl(fd, SIOCSIFDNS, &ifr) < 0) { log_e("socket SIOCSIFDNS failed\n"); close(fd); return -1; } #endif close(fd); return 0; } static int get_dns(int family, const char* iface, char* dns1, char *dns2) { return 0; } static int ip_check(char* addr) { int flag = IP_ERR; int len = 0; int num = 0; int Count = 0; int first = 0; int i = 0,j=0; len = strlen(addr); if (strchr(addr,'.') != NULL) {// 含 .的情况,判断是否是IPv4 for(i = 0;i <= len-1; i++) { if(addr[i] >= '0' && addr[i] <= '9') { num = num * 10 + addr[i] - '0'; } else if(addr[i] == '.') { if((i == 0)||(i == len-1)) { break; } if(addr[i-1] < '0' || addr[i-1] > '9') { break; } if(addr[i] == '.') { Count++; if(Count > 3) { break; } } if(num > 255) { break; } if(num != 0 && addr[first] == '0') { break; } first = i+1; num = 0; } else { break; } } if(Count == 3) { flag = IP_V4; } } else if (strchr(addr,':') != NULL) {// 含 :的情况,判断是否是IPv6 for(i = 0;i <= len-1; i++) { if((addr[i] >= '0' && addr[i] <= '9')||(tolower(addr[i]) >= 'a' && tolower(addr[i]) <= 'f')) { j++; if (j > 4) { break; } } else if(addr[i] == ':') { if((i == 0)||(i == len-1)) { break; } if (j == 0) { break; } Count++; if(Count > 7) { break; } j = 0; } else { break; } } if((Count == 7)&&(j <= 4)) { flag = IP_V6; } } return flag; } /////////////////////////////////////////////// static int file_length(char* path) { int r; struct stat st; r = stat(path, &st); if (r) { return -1; } return st.st_size; } static int file_save(char *path, void *buf, int len) { int r; FILE *fp; fp = fopen(path, "w"); if(!fp) { LOGE("file_save, fopen %s failed, %d, %d\n", path); return -1; } r = fwrite(buf, 1, len, fp); if(r!=len) { LOGE("file_save %s failed, %d, %d\n", path, r, len); r = -1; } else { r = 0; } fclose(fp); return r; } static int file_load(char* path, void* buf, int len) { int r; FILE* fp; fp = fopen(path, "r"); if (!fp) { LOGE("file_load, fopen %s failed, %d, %d\n", path); return -1; } r = fread(buf, 1, len, fp); if (r != len) { LOGE("file_load %s failed, %d, %d\n", path, r, len); r = -1; } else { r = 0; } fclose(fp); return r; } typedef struct { char lo[500]; char e0[500]; char e1[500]; }net_t; static net_t sNet; typedef uint32_t u32; #define XLEN(a,b) ((u32)(a)-(u32)(b)) typedef struct { char *ptr; int len; }nic_t; static int find_str(char *buf, char *head, char *tail, char *nic) { int len; char *p,*p1,*p2; p1 = strstr(buf, head); p2 = strstr(buf, tail); if(p1 && p2) { p1 = p1 + sizeof(head); len = XLEN(p2,p1); if(len>0) { p = malloc(len+1); if(p) { memcpy(p, p1, len); p[len] = 0; if(strstr(p, nic)) { return p1; } free(p); } } } return NULL; } static int get_nic(char *nbuf, int nlen, char *nic, char *fbuf, int flen) { int r,len; char *p,*p1,*p2; char *fend=fbuf+flen-1; p = fbuf; while(p=len) { memcpy(nbuf, p1, len); nbuf[len] = 0; //LOGD("__x__%s:\n %s\n", nic, nbuf); return 0; } else { LOGD("___ nbuf is too small\n"); } } p = p+1; } return -1; } static int get_ip(char *nbuf, char *token, char *ipaddr) { int cnt=0; char *p,*p1,*p2; p = strstr(nbuf, token); if(p) { while(!isdigit(*p)) p++; p1 = p; while(!isspace(*p)) p++; p2 = p; for(p=p1; plo, sizeof(pNet->lo), "lo", fbuf, flen); get_nic(pNet->e0, sizeof(pNet->e0), "eth0", fbuf, flen); get_nic(pNet->e1, sizeof(pNet->e1), "eth1", fbuf, flen); if(strstr(pNet->e0, "dhcp")) { para->mode = 0; } else if(strstr(pNet->e0, "static")) { para->mode = 1; } get_ip(pNet->e0, "address", para->ip_address); get_ip(pNet->e0, "netmask", para->mask); get_ip(pNet->e0, "gateway", para->gateway); free(fbuf); return 0; } static int set_net(NetworkInfo_t *para) { int r; char *p1,*p2,*p3,*p4; char *fpath=FILE_INTERFACE; int xlen=10*1000; NetworkInfo_t para2; net_t *pNet=&sNet; memset(¶2, 0, sizeof(para2)); get_net(¶2); if(para->mode<2 && para->mode!=para2.mode) { para2.mode = para->mode; } if(ip_check(para->ip_address) && strcmp(para->ip_address, para2.ip_address)) { strcpy(para2.ip_address, para->ip_address); } if(ip_check(para->mask) && strcmp(para->mask, para2.mask)) { strcpy(para2.mask, para->mask); } if(ip_check(para->gateway) && strcmp(para->gateway, para2.gateway)) { strcpy(para2.gateway, para->gateway); } char *fbuf=malloc(xlen); if(!fbuf) { LOGE("___ malloc %d failed\n", xlen); return -1; } #if 0 file_load(fpath, fbuf, flen); fbuf[flen] = 0; get_nic(pNet->lo, sizeof(pNet->lo), "lo", fbuf, flen); get_nic(pNet->e1, sizeof(pNet->e1), "eth1", fbuf, flen); snprintf(pNet->e0, sizeof(pNet->e0), "auto eth0\niface eth0 inet %s\n address %s\n netmask %s\n gateway %s\n\n", para2.mode?"static":"dhcp", para2.ip_address, para2.mask, para2.gateway); strcpy(fbuf, pNet->lo); strcat(fbuf, pNet->e0); strcat(fbuf, pNet->e1); #else char *lo="auto lo\niface lo inet loopback\n\n"; char *eth1="auto eth1\niface eth1 inet dhcp\npre-up /etc/network/nfs_check\nwait-delay 5\nhostname $(hostname)\n"; char eth0[500]; snprintf(eth0, sizeof(eth0), "auto eth0\niface eth0 inet %s\n address %s\n netmask %s\n gateway %s\n\n", para2.mode?"static":"dhcp", para2.ip_address, para2.mask, para2.gateway); sprintf(fbuf, "%s%s%s", lo, eth0, eth1); #endif //LOGD("___interfaces___:\n%s", fbuf); r = file_save(fpath, fbuf, strlen(fbuf)); free(fbuf); if(r==0) { paras_get()->dev._network_info = para2; } return r; } ////////////////////////////////////////////////////////////////////////////// int sys_set_net(NetworkInfo_t *para, int ipVersion) { int r,ipv; #ifdef USE_BASH char cmd[200]; snprintf(cmd, sizeof(cmd), "ip addr flush dev %s", DFLT_NIC); r = system(cmd); if(r) { LOGE("set ipaddr failed\n"); return -1; } snprintf(cmd, sizeof(cmd), "ip addr add %s/%s dev %s", para->ip_address, para->mask, DFLT_NIC); r = system(cmd); if(r) { LOGE("set netmask %s failed\n", para->mask); return -1; } snprintf(cmd, sizeof(cmd), "ip route add default via %s dev %s", para->gateway, DFLT_NIC); r = system(cmd); if(r) { LOGE("set gateway %s failed\n", para->gateway); return -1; } snprintf(cmd, sizeof(cmd), "ip link set dev %s up", DFLT_NIC); r = system(cmd); if(r) { LOGE("restart %s failed\n", DFLT_NIC); return -1; } #elif defined USE_FILE NetworkInfo_t para2; r = get_net(¶2); if(r==0 && memcmp(para, ¶2, sizeof(NetworkInfo_t))) { r = set_net(para); } else { LOGE("get_net failed\n"); } #elif defined USE_API if(para->mode==IP_DHCP) { r = set_dhcp(1); } else { set_dhcp(0); int family=(ipv==IP_V4)?AF_INET:AF_INET6; r = set_ipaddr(family, "eth0", para->ip_address, para->mask); if(r) { LOGE("set_ipaddr failed\n"); return r; } r = set_gateway(family, para->gateway); if(r) { LOGE("set_gateway failed\n"); return r; } r = set_dns(family, "eth0", para->dns1, para->dns2); if(r) { LOGE("set_dns failed\n"); return r; } } #endif system("ifdown eth0 && ifup eth0"); //system("重启dns服务器"); //目前dns服务未启动 return r; } int sys_get_net(NetworkInfo_t *para, int ipVersion) { int r; int family=AF_INET; #ifdef USE_BASH #elif defined USE_FILE r = get_net(para); #elif defined USE_API r = get_ipaddr(family, DFLT_NIC, para->ip_address, para->mask); if(r) { LOGE("set_ipaddr failed\n"); return r; } r = get_gateway(family, para->gateway); if(r) { LOGE("set_gateway failed\n"); return r; } r = get_dns(family, DFLT_NIC, para->dns1, para->dns2); if(r) { LOGE("set_dns failed\n"); return r; } #endif return 0; } static thread_handle_t myThdHandles[THREAD_ID_MAX]={0}; int sys_start_thread(int id, thread_fn fn, void *arg) { int r; pthread_attr_t attr; if(id>=THREAD_ID_MAX) { return -1; } thread_handle_t *h=&myThdHandles[id]; h->arg = arg; h->quit = 0; pthread_attr_init(&attr); //pthread_attr_setstacksize(&attr, 1024*1024*2); r = pthread_create(&h->tid, NULL, fn, h); return r; } int sys_stop_thread(int id) { if(id>=THREAD_ID_MAX) { return -1; } thread_handle_t *h=&myThdHandles[id]; h->quit = 1; #ifdef USE_WEBAPP if(id==THREAD_ID_WEB) { extern void httpStopEndpoints(); httpStopEndpoints(); } #endif pthread_join(h->tid, NULL); h->tid = 0; h->arg = NULL; h->fn = NULL; return 0; } int sys_stop_all_thread(void) { int i; for(i=0; i