/****************************************************************************** 版权所有: 文件名称: rt_socket.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2020-06-18 功能说明: 实时微系统网络接口.所有接口必须在线程中调用,不能在中断中调用。 其它说明: 修改记录: */ /*------------------------------- 头文件 -------------------------------------- */ #include #include "rt_socket.h" #include "rt_printf.h" #include #include "bspconfig.h" /*------------------------------- 宏定义 -------------------------------------- */ /*------------------------------ 类型结构 ------------------------------------- */ /*------------------------------ 全局变量 ------------------------------------- */ char *g_if_name[] = { "eth0", "eth1", "eth2", "eth3", "eth4", }; #define IF_NUM ((int)(sizeof(g_if_name) / 4)) int g_net_num = CFG_ETH_MAX_PHY; // 正常的网口数量 /*------------------------------ 函数声明 ------------------------------------- */ /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ int rt_socket_init(void) { unsigned int ret; // 目前工厂主板标准硬件版本为0,2个网口。 // 以后如果使用3个网口,需修改硬件版本号。 ret = 3; // gpio_get_version(); if (ret < 3) { g_net_num = 2; } return 0; } // 打开关闭 SOCKET rt_socket(int domain, int type, int protocol) { SOCKET s; s = socket(domain, type, protocol); return s; } int rt_socket_close(SOCKET s) { if (s > 0) { close(s); } return 0; } // 连接 SOCKET rt_accept(SOCKET s, struct sockaddr *addr, unsigned int *addr_len) { SOCKET newsock = 0; newsock = accept(s, addr, addr_len); return newsock; } int rt_bind(SOCKET s, struct sockaddr *addr, unsigned int len) { return bind(s, addr, len); } int rt_connect(SOCKET s, struct sockaddr *addr, unsigned int len) { return connect(s, addr, len); } int rt_listen(SOCKET s, int n) { return listen(s, n); } int rt_shutdown(SOCKET s, int how) { return shutdown(s, how); } // 接收发送 int rt_send(SOCKET s, void *buf, int n, int flags) { // flags加上MSG_NOSIGNAL标志,解决主循环在此断开的socket上继续发送数据,引起系统异常的问题。 // return rt_sendto(s,buf,n,flags,NULL,0); return sendto(s, buf, n, flags | MSG_NOSIGNAL, NULL, 0); } int rt_recv(SOCKET s, void *buf, int n, int flags) { return rt_recvfrom(s, buf, n, flags, NULL, 0); } int rt_sendto(SOCKET s, void *buf, int n, int flags, struct sockaddr *addr, unsigned int addr_len) { return sendto(s, buf, n, flags, addr, addr_len); } int rt_recvfrom(SOCKET s, void *buf, int n, int flags, struct sockaddr *addr, unsigned int *addr_len) { return recvfrom(s, buf, n, flags, addr, addr_len); } // 控制 int rt_getsockname(SOCKET s, struct sockaddr *addr, unsigned int *len) { return getsockname(s, addr, len); } int rt_getpeername(SOCKET s, struct sockaddr *addr, unsigned int *len) { return getpeername(s, addr, len); } int rt_getsockopt(SOCKET s, int level, int optname, void *optval, unsigned int *optlen) { return getsockopt(s, level, optname, optval, optlen); } int rt_setsockopt(SOCKET s, int level, int optname, void *optval, unsigned int optlen) { return setsockopt(s, level, optname, optval, optlen); } int rt_sockioctl(SOCKET s, int cmd, uint64_t arg) { return ioctl(s, cmd, arg); } int set_net_param_fun(char *NetNum, char *para, char *cmd) { int ret; char argv[256] = {0x00}; // sprintf(argv, "/bin/ifconfig %s %s %s", NetNum,para,cmd); sprintf(argv, "ifconfig %s %s %d.%d.%d.%d", NetNum, para, cmd[0], cmd[1], cmd[2], cmd[3]); #ifdef RT_SOCKET_DEBUG rt_printf("sh cmd=%s\r\n", argv); #endif ret = system(argv); return ret; } int set_gw_param_fun(char *ip, char *gw) { int ret; char argv[256] = {0x00}; // sprintf(argv, "/bin/ifconfig %s %s %s", NetNum,para,cmd); sprintf(argv, "route add %s gw %s", ip, gw); #ifdef RT_SOCKET_DEBUG rt_printf("sh cmd=%s\r\n", argv); #endif ret = system(argv); return ret; } #if 0 // 没有用到 int rt_sockconnected(SOCKET s) { struct tcp_info info; int len=sizeof(info); int ret=-1; if(!s) return ret; memset(&info, 0, sizeof(info)); ret=rt_getsockopt(s, IPPROTO_TCP, TCP_INFO, (char *)&info, &len); if(info.tcpi_state==1) { //处于链接状态 ret = 0; } else { //处于断开状态 ret = -1; } return ret; } int rt_net_set_KeepAlive(SOCKET s, int interval) { int val = interval; //开启keepalive机制 if (rt_setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1) { // printf("setsockopt SO_KEEPALIVE: %s", strerror(errno)); return -1; } /* Default settings are more or less garbage, with the keepalive time * set to 7200 by default on Linux. Modify settings to make the feature * actually useful. */ /* Send first probe after interval. */ val = interval; if (rt_setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { // printf("setsockopt TCP_KEEPIDLE: %s\n", strerror(errno)); return -1; } /* Send next probes after the specified interval. Note that we set the * delay as interval / 3, as we send three probes before detecting * an error (see the next setsockopt call). */ val = interval / 3; if (val == 0) val = 1; if (rt_setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { // printf("setsockopt TCP_KEEPINTVL: %s\n", strerror(errno)); return -1; } /* Consider the socket in error state after three we send three ACK * probes without getting a reply. */ val = 3; if (rt_setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { // printf("setsockopt TCP_KEEPCNT: %s\n", strerror(errno)); return -1; } return 0; } #endif /****************************************************************************** 函数名称:rt_if_up 函数版本:01.01 创建作者:sunxi 创建日期:2020-06-18 函数说明:UP一个接口。 参数说明: if_name: 接口名称,如eth0,fei1等。 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ #if 0 int rt_if_up(int index) { struct ifreq ifr; SOCKET sock; if(index >= IF_NUM) { return -1; } sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if (sock == RT_SOCKET_ERR) { rt_printf("rt_if_up:: rt_socket::error\n"); return -1; } memset(&ifr,0,sizeof(ifr)); strcpy(ifr.ifr_name,g_if_name[index]); /* 得到标志*/ if(rt_sockioctl(sock,SIOCGIFFLAGS,(uint32_t)&ifr) != 0) { rt_socket_close(sock); return -1; } /* 修改标志*/ ifr.ifr_ifru.ifru_flags |= IFF_UP; /* 写回标志*/ if(rt_sockioctl(sock,SIOCSIFFLAGS,(uint32_t)&ifr) != 0) { rt_socket_close(sock); return -1; } rt_socket_close(sock); return 0; } #endif int rt_if_up(int index) { int ret; char argv[256] = {0x00}; sprintf(argv, "/sbin/ifconfig eth%d up", index); ret = system(argv); return ret; } /****************************************************************************** 函数名称:rt_if_down 函数版本:01.01 创建作者:sunxi 创建日期:2020-06-18 函数说明:DOWN一个接口。 参数说明: if_name: 接口名称,如eth0,fei1等。 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ int rt_if_down(int index) { int ret; char argv[256] = {0x00}; sprintf(argv, "/sbin/ifconfig eth%d down", index); ret = system(argv); return ret; } int c2n(char c) { if (c >= '0' && c <= '9') { return c - '0'; } if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } return -1; } // 将标准MAC地址字符串转换为6字节MAC地址 // 80-81-00-b0-32-81 int rt_if_sz2mac(char *sz, unsigned char *mac) { int i; int c0, c1; if (sz == NULL || mac == NULL) { return -1; } if (strlen(sz) != 17) { return -1; } i = 0; while (i < 17) { if ((i % 3 == 2)) { if (sz[i++] != '-') { return -2; } } c0 = c2n(sz[i++]); if (c0 < 0) { return -3; } c1 = c2n(sz[i++]); if (c1 < 0) { return -4; } *mac++ = (c0 << 4) | c1; } return 0; } /* int rt_if_mac_set(int index, unsigned char *mac) { int ret; struct ifreq ifr; int sock; if((unsigned int)index >= IF_NUM) { return -1; } if(mac == NULL) { return -1; } memset(&ifr, 0, sizeof(struct ifreq)); //创建socket sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if(sock < 0) { rt_printf("Not create network rt_socket connection\\n"); return (-1); } strncpy(ifr.ifr_name,g_if_name[index],IFNAMSIZ); ifr.ifr_name[IFNAMSIZ - 1] = 0; //关闭网卡 ifr.ifr_flags &= ~IFF_UP; if(ioctl(sock,SIOCSIFFLAGS,(uint32_t)&ifr) < 0) { //rt_printf("SIOCSIFFLAGS"); close(sock); return (-1); } //获取Mac地址 ret = ioctl(sock,SIOCGIFHWADDR,(uint32_t)&ifr); if( ret < 0) { //rt_printf("Not setup SIOCGIFHWADDR(ret=%d)\n",ret); close(sock); return (-1); } //填充Mac地址 ifr.ifr_hwaddr.sa_data[0]=mac[0]; ifr.ifr_hwaddr.sa_data[1]=mac[1]; ifr.ifr_hwaddr.sa_data[2]=mac[2]; ifr.ifr_hwaddr.sa_data[3]=mac[3]; ifr.ifr_hwaddr.sa_data[4]=mac[4]; ifr.ifr_hwaddr.sa_data[5]=mac[5]; //修改Mac地址 ret = ioctl(sock, SIOCSIFHWADDR, (uint32_t)&ifr); if( ret < 0) { rt_printf("Not setup SIOCSIFHWADDR(ret=%d)\n",ret); close(sock); return (-1); } //启动网卡 ifr.ifr_flags |= IFF_UP|IFF_RUNNING; if(ioctl(sock,SIOCSIFFLAGS,(uint32_t)&ifr)<0) { rt_printf("SIOCSIFFLAGS"); close(sock); return (-1); } close(sock); return 0; } */ int rt_if_mac_set(int index, unsigned char *mac) { char argv[256] = {0x00}; int ret; char NetNum[20] = ""; sprintf(NetNum, "eth%d", index); sprintf(argv, "ifconfig %s hw ether %02X:%02X:%02X:%02X:%02X:%02X", NetNum, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); #ifdef RT_SOCKET_DEBUG rt_printf("sh cmd=%s\r\n", argv); #endif ret = system(argv); return ret; } int rt_if_mac_get(int index, unsigned char *mac) { int ret; struct ifreq ifr; int sock; if ((unsigned int)index >= IF_NUM) { return -1; } if (mac == NULL) { return -1; } memset(&ifr, 0, sizeof(struct ifreq)); // 创建socket sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { rt_printf("Not create network rt_socket connection\\n"); return (-1); } strncpy(ifr.ifr_name, g_if_name[index], IFNAMSIZ); ifr.ifr_name[IFNAMSIZ - 1] = 0; // 获取Mac地址 ret = ioctl(sock, SIOCGIFHWADDR, (uint64_t)&ifr); if (ret < 0) { // rt_printf("Not setup SIOCGIFHWADDR(ret=%d)\n",ret); close(sock); return (-1); } // 填充Mac地址 mac[0] = ifr.ifr_hwaddr.sa_data[0]; mac[1] = ifr.ifr_hwaddr.sa_data[1]; mac[2] = ifr.ifr_hwaddr.sa_data[2]; mac[3] = ifr.ifr_hwaddr.sa_data[3]; mac[4] = ifr.ifr_hwaddr.sa_data[4]; mac[5] = ifr.ifr_hwaddr.sa_data[5]; close(sock); return 0; } /****************************************************************************** 函数名称:rt_if_ip_set 函数版本:01.01 创建作者:sunxi 创建日期:2020-06-18 函数说明:设置一个接口的IP地址。 参数说明: if_name: 接口名称,如eth0,fei1等。 ip : IP地址。 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ int rt_if_ip_set(int index, unsigned char *ip) { int ret; char NetNum[20] = ""; if ((unsigned int)index >= IF_NUM) { return -1; } sprintf(NetNum, "eth%d", index); ret = set_net_param_fun(NetNum, " ", ip); // 设置ip return ret; } /****************************************************************************** 函数名称:rt_if_ip_get 函数版本:01.01 创建作者:sunxi 创建日期:2020-06-18 函数说明:得到一个接口的IP地址。 参数说明: if_name: 接口名称,如eth0,fei1等。 ip : 返回的IP地址在*if_addr中。 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ int rt_if_ip_get(int index, unsigned char *ip) { unsigned int addr; struct ifreq ifr; SOCKET sock; if ((unsigned int)index >= IF_NUM) { return -1; } if (ip == NULL) { return -1; } sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if (sock == RT_SOCKET_ERR) { rt_printf("%s:: rt_socket [%d]::error\n", __FUNCTION__, index); return -1; } memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, g_if_name[index]); if (rt_sockioctl(sock, SIOCGIFADDR, (uint64_t)&ifr) != 0) { rt_socket_close(sock); return -1; } addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; addr = ntohl(addr); memcpy(ip, &addr, 4); rt_socket_close(sock); return 0; } /****************************************************************************** 函数名称:rt_if_mask_set 函数版本:01.01 创建作者:sunxi 创建日期:2020-06-18 函数说明:设置一个接口的子网屏蔽。 参数说明: if_name: 接口名称,如eth0,fei1等。 mask : 子网屏蔽 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ int rt_if_mask_set(int index, unsigned char *mask) { int ret; char NetNum[20] = ""; if ((unsigned int)index >= IF_NUM) { return -1; } sprintf(NetNum, "eth%d", index); ret = set_net_param_fun(NetNum, "netmask", mask); // 设置子网掩码 return ret; } /****************************************************************************** 函数名称:rt_if_mask_get 函数版本:01.01 创建作者:sunxi 创建日期:2020-06-18 函数说明:得到一个接口的子网屏蔽。 参数说明: if_name: 接口名称,如eth0,fei1等。 mask : 返回的子网屏蔽在*if_mask中。 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ int rt_if_mask_get(int index, unsigned char *mask) { unsigned int addr; struct ifreq ifr; SOCKET sock; if ((unsigned int)index >= IF_NUM) { return -1; } if (mask == NULL) { return -1; } sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if (sock == RT_SOCKET_ERR) { rt_printf("rt_if_mask_get:: rt_socket::error\n"); return -1; } memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, g_if_name[index]); if (rt_sockioctl(sock, SIOCGIFNETMASK, (uint64_t)&ifr) != 0) { rt_socket_close(sock); return -1; } addr = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr; addr = ntohl(addr); memcpy(mask, &addr, 4); rt_socket_close(sock); return 0; } /****************************************************************************** 函数名称:rt_route_add 函数版本:01.01 创建作者:xxxxxx 创建日期:2008-04-09 函数说明:增加一个接口的路由。 参数说明: destination : 目标网络。 gateway : 网关 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ int rt_route_add(int index, unsigned char *destination, unsigned char *gateway) { int sock; unsigned int destination2, gateway2; struct rtentry rt; if (destination == NULL || gateway == NULL) { return -1; } memcpy(&destination2, destination, 4); memcpy(&gateway2, gateway, 4); sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { rt_printf("Create Socket Erro\r\n"); return -1; } memset(&rt, 0, sizeof(struct rtentry)); rt.rt_dev = g_if_name[index]; rt.rt_flags = RTF_UP | RTF_GATEWAY; ((struct sockaddr_in *)&rt.rt_gateway)->sin_family = AF_INET; ((struct sockaddr_in *)&rt.rt_gateway)->sin_addr.s_addr = htonl(gateway2); ((struct sockaddr_in *)&rt.rt_dst)->sin_family = AF_INET; ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = htonl(destination2); /* The netmask for the destination net; ’255.255.255.255’ for a host destination and ’0.0.0.0’ for the default route. */ ((struct sockaddr_in *)&rt.rt_genmask)->sin_family = AF_INET; ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = 0; if (-1 == ioctl(sock, SIOCADDRT, (uint64_t)&rt)) { rt_printf("rt_route_add fail"); close(sock); return -1; } close(sock); return 0; } /****************************************************************************** 函数名称:rt_route_delete 函数版本:01.01 创建作者:sunxi 创建日期:2020-6-19 函数说明:删除一个接口的路由。 参数说明: if_name_prefic : 接口名称前缀,如eth,fei等。 unit : 网卡编号,如,0,1,2等 返回值 : >=0 : 成功。 -1 : 失败。 更新记录: */ int rt_route_del(int index, unsigned char *destination, unsigned char *gateway) { int sock; unsigned int destination2, gateway2; struct rtentry rt; if (destination == NULL || gateway == NULL) { return -1; } memcpy(&destination2, destination, 4); memcpy(&gateway2, gateway, 4); sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { rt_printf("Create Socket Erro\r\n"); return -1; } memset(&rt, 0, sizeof(struct rtentry)); rt.rt_dev = g_if_name[index]; rt.rt_flags = RTF_UP | RTF_GATEWAY; // ((struct sockaddr_in *) &rt.rt_gateway)->sin_family = AF_INET; // ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = htonl(gateway2); ((struct sockaddr_in *)&rt.rt_dst)->sin_family = AF_INET; ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = htonl(destination2); /* The netmask for the destination net; ’255.255.255.255’ for a host destination and ’0.0.0.0’ for the default route. */ ((struct sockaddr_in *)&rt.rt_genmask)->sin_family = AF_INET; ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = 0; if (-1 == ioctl(sock, SIOCDELRT, (uint64_t)&rt)) { rt_printf("rt_route_del fail"); close(sock); return -1; } close(sock); return 0; } int net_gateway_set(unsigned char *gateway) { int ret; char argv_del[] = "/sbin/route del default"; char argv_add[256] = {0x00}; if (gateway == 0) { return -1; } sprintf(argv_add, "/sbin/route add default gw %d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]); ret = system(argv_del); ret = system(argv_add); return ret; } int net_if_set(int if_index, unsigned char *mac, unsigned char *ip, unsigned char *mask) { if ((unsigned int)if_index >= IF_NUM) { return -1; } if (mac) { rt_if_mac_set(if_index, mac); } if (ip) { rt_if_ip_set(if_index, ip); } if (mask) { rt_if_mask_set(if_index, mask); } return 0; } int net_if_get(int if_index, unsigned char *mac, unsigned char *ip, unsigned char *mask) { int ret; char buf[64]; if ((unsigned int)if_index >= IF_NUM) { return -1; } if (mac) { ret = rt_if_mac_get(if_index, mac); if (ret != 0) { return -1; } sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } if (ip) { ret = rt_if_ip_get(if_index, ip); if (ret != 0) { return -2; } sprintf(buf, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); } if (mask) { ret = rt_if_mask_get(if_index, mask); if (ret != 0) { return -3; } sprintf(buf, "%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3]); } return 0; } int rt_get_net_linkstatus(int if_index) { int skfd = -1; struct ifreq ifr; unsigned short *data, mii_val; unsigned phy_id; if (if_index < 0) { return -1; } if ((skfd = rt_socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return -1; } /* Get the vitals from the interface. */ strncpy(ifr.ifr_name, g_if_name[if_index], IFNAMSIZ); if (ioctl(skfd, SIOCGMIIPHY, (uint64_t)&ifr) < 0) { /* TODO usb扩展网口这里会报错 需要后期进行处理 */ rt_printf("if_index = %d, SIOCGMIIPHY on %s failed!\n", if_index, ifr.ifr_name); perror("err"); close(skfd); return -2; } data = (unsigned short *)(&ifr.ifr_data); phy_id = data[0]; data[1] = 1; if (ioctl(skfd, SIOCGMIIREG, (uint64_t)&ifr) < 0) { rt_printf("SIOCGMIIREG on %s failed!\n", ifr.ifr_name); close(skfd); return -3; } close(skfd); mii_val = data[3]; return (((mii_val & 0x0016) == 0x0004) ? 0 : 1); } #define NET_NUM_CNT 3 int rt_get_netcard_id_from_socket(SOCKET s) { struct sockaddr_in local_addr; unsigned int len = sizeof(local_addr); char buf[32] = {0}; unsigned int ip = 0; int i, j; int index; rt_getsockname(s, (struct sockaddr *)&local_addr, &len); // 此处需转换,否则匹配不到对应ip local_addr.sin_addr.s_addr = ntohl(local_addr.sin_addr.s_addr); index = -1; for (i = 0; i < g_net_num; i++) { // 获取网卡IP rt_if_ip_get(i, buf); memcpy(&ip, buf, 4); if (ip == local_addr.sin_addr.s_addr) { index = i; break; } else { for (j = 1; j <= NET_NUM_CNT; j++) { rt_if_ip_get2(i, j, buf); memcpy(&ip, buf, 4); if (ip == local_addr.sin_addr.s_addr) { return i; } } } } return index; } int net_route_set(unsigned char *routenet, unsigned char *routenetmask, unsigned char *routegate) { int ret; char buf_routenet[32]; char buf_routenetmask[32]; char buf_routegate[32]; char argv_add[512] = {0x00}; char argv_add2[512] = {0x00}; if ((routenet == 0) || (routenetmask == 0) || (routegate == 0)) { return -1; } if ((routenet[0] == 0) && (routenet[1] == 0) && (routenet[2] == 0) && (routenet[3] == 0)) { return 0; } if ((routegate[0] == 0) && (routegate[1] == 0) && (routegate[2] == 0) && (routegate[3] == 0)) { return 0; } sprintf(buf_routenet, "%d.%d.%d.%d", routenet[0], routenet[1], routenet[2], routenet[3]); sprintf(buf_routenetmask, "%d.%d.%d.%d", routenetmask[0], routenetmask[1], routenetmask[2], routenetmask[3]); sprintf(buf_routegate, "%d.%d.%d.%d", routegate[0], routegate[1], routegate[2], routegate[3]); sprintf(argv_add, "/sbin/route add -net %s netmask %s gw %s", buf_routenet, buf_routenetmask, buf_routegate); sprintf(argv_add2, "/sbin/route add -host %s gw %s", buf_routenet, buf_routegate); if ((routenetmask[0] == 0) && (routenetmask[1] == 0) && (routenetmask[2] == 0) && (routenetmask[3] == 0)) { ret = system(argv_add2); } else { ret = system(argv_add); } return ret; } int rt_if_ip_set2(int eth_id, int index, unsigned char *ip) { int ret; char NetNum[20] = ""; if ((unsigned int)index >= IF_NUM) { return -1; } sprintf(NetNum, "eth%d:%d", eth_id, index); ret = set_net_param_fun(NetNum, " ", ip); // 设置ip return ret; } int rt_if_mask_set2(int eth_id, int index, unsigned char *mask) { int ret; char NetNum[20] = ""; if ((unsigned int)index >= IF_NUM) { return -1; } sprintf(NetNum, "eth%d:%d", eth_id, index); ret = set_net_param_fun(NetNum, "netmask", mask); // 设置子网掩码 return ret; } int net_if_set2(int eth_id, int if_index, unsigned char *mac, unsigned char *ip, unsigned char *mask) { if ((unsigned int)if_index > IF_NUM) { return -1; } if (mac) { // rt_if_mac_set(if_index,mac); mac = mac; } if (ip) { rt_if_ip_set2(eth_id, if_index, ip); } if (mask) { rt_if_mask_set2(eth_id, if_index, mask); } return 0; } int rt_if_ip_get2(int eth_id, int index, unsigned char *ip) { unsigned int addr; char buf[32]; struct ifreq ifr; SOCKET sock; if ((unsigned int)eth_id >= IF_NUM) { return -1; } if (ip == NULL) { return -1; } sock = rt_socket(AF_INET, SOCK_DGRAM, 0); if (sock == RT_SOCKET_ERR) { rt_printf("%s:: rt_socket [%d][%d]::error\n", __FUNCTION__, eth_id, index); return -1; } sprintf(buf, "eth%d:%d", eth_id, index); memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, buf); if (rt_sockioctl(sock, SIOCGIFADDR, (uint64_t)&ifr) != 0) { rt_socket_close(sock); return -1; } addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; addr = ntohl(addr); memcpy(ip, &addr, 4); rt_socket_close(sock); return 0; } int rt_if_down2(int eth_id, int index) { int ret; char argv[256] = {0x00}; sprintf(argv, "/sbin/ifconfig eth%d:%d down", eth_id, index); ret = system(argv); return ret; } /*------------------------------ 内部函数 ------------------------------------- 内部函数以下划线‘_’开头,不需要检查参数的合法性. */ /*------------------------------ 测试函数 ------------------------------------- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数). */ #define IF_INDEX 1 int net_if_test(void) { // uint32_t us0; unsigned char mac[6]; unsigned char ip[4]; unsigned char mask[4]; unsigned char gateway[4]; rt_printf("net_if_test begin...\r\n"); // 得到并打印旧的网络参数 net_if_get(IF_INDEX, mac, ip, mask); rt_printf("old mac: %02x:%02x:%02x:%02x:%02x:%02x\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); rt_printf("old ip:%d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]); rt_printf("old mask:%d.%d.%d.%d\r\n", mask[0], mask[1], mask[2], mask[3]); rt_printf("old gateway:%d.%d.%d.%d\r\n", gateway[0], gateway[1], gateway[2], gateway[3]); // 设置接口MAC地址 mac[0] = 'H'; mac[1] = 'G'; mac[2] = 192; mac[3] = 168; mac[4] = 1; mac[5] = 240; // 设置IP memcpy(ip, mac + 2, 4); // 设置MASK mask[0] = 255; mask[1] = 255; mask[2] = 0; mask[3] = 0; // 设置网关 gateway[0] = 192; gateway[1] = 168; gateway[2] = 1; gateway[3] = 254; // 设置网络参数 // us0 = ustimer_get_origin(); net_if_set(IF_INDEX, mac, ip, mask); net_gateway_set(gateway); // rt_printf("net_if_set duration:%dus.\r\n",ustimer_get_duration(us0)); // 得到并打印新的网络参数 net_if_get(IF_INDEX, mac, ip, mask); rt_printf("new mac: %02x:%02x:%02x:%02x:%02x:%02x\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); rt_printf("new ip:%d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]); rt_printf("new mask:%d.%d.%d.%d\r\n", mask[0], mask[1], mask[2], mask[3]); rt_printf("new gateway:%d.%d.%d.%d\r\n", gateway[0], gateway[1], gateway[2], gateway[3]); rt_printf("net_if_test ok\r\n"); return 0; } int socket_test(void) { unsigned char buf[512]; SOCKET sock, new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size, portnumber; char hello[] = "Hello! Are You Fine?\n"; portnumber = 1111; /*服务器端开始建立socket描述符*/ if ((sock = rt_socket(AF_INET, SOCK_STREAM, 0)) == RT_SOCKET_ERR) { rt_printf("Socket error:%d\n\a", sock); } /*服务器端填充sockaddr结构*/ memset(&server_addr, 0, sizeof(struct sockaddr_in)); // 将 server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(portnumber); /*捆绑sock描述符*/ if (rt_bind(sock, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) { rt_printf("Bind error:%d\n\a", sock); } /*监听sock描述符*/ if (rt_listen(sock, 5) == -1) { rt_printf("Listen error:%d\n\a", sock); } while (1) { /*服务器阻塞,直到客户程序建立连接*/ sin_size = sizeof(struct sockaddr_in); if ((new_fd = rt_accept(sock, (struct sockaddr *)(&client_addr), &sin_size)) == RT_SOCKET_ACCEPT_RST) { rt_printf("Accept error:%d\n\a", sock); } rt_printf("Server get connection from %d\n", new_fd); if (rt_send(new_fd, hello, strlen(hello), 0) == -1) { rt_printf("Write Error:%d\n", new_fd); } while (1) { int flag; if ((flag = rt_recv(new_fd, buf, 512, 0)) < 0) { rt_printf("Reading data error!\n"); break; } if (flag == 0) { rt_printf("Ending current connection!\n"); break; } else { rt_printf("-->%s\n", buf); if (strstr(buf, "exit")) { rt_printf("Ending current connection!\n"); break; } } rt_socket_close(new_fd); } rt_socket_close(sock); } return 0; } /*------------------------------ 文件结束 ------------------------------------- */