#include #include #include #include #include #include #include #include #include #include "mini_httpd_raw.h" #define MINI_BASEMAC_LEN 15 #define MINI_BASE_MACFILE "/proc/mos/basemac" unsigned char minidstmac[6] = {0x01, 0x80, 0x56, 0x00, 0x08, 0x6d}; unsigned char minisrcmac[6]; extern netlinksock_t mini_http_raw_pkt_sock; extern int httpd_ifindex; int mini_str2mac(const char *buf, raw_mac_t mac) { if (strlen (buf) != 14) return -1; if(sscanf(buf, "%2hhx%2hhx-%2hhx%2hhx-%2hhx%2hhx", (unsigned char *) &mac[0], (unsigned char *) &mac[1], (unsigned char *) &mac[2], (unsigned char *) &mac[3], (unsigned char *) &mac[4], (unsigned char *) &mac[5]) != 6) { return -1; } return 0; } int mini_get_mac(raw_mac_t mac) { int fd; int ret; char buf[MINI_BASEMAC_LEN]; memset(buf, 0, MINI_BASEMAC_LEN); FILE *fp; //if((fp=fopen(MAC_MENU_CONFIG_FILE, "r"))) if((fp=fopen("/etc/mymac", "r"))) { int i = 0, count = 0; // fomart; xxxx-xxxx-xxxx fread(buf, MINI_BASEMAC_LEN, 1, fp); while(buf[i++]) { if(buf[i] == '-') count++; } fclose(fp); if(count == 2) goto end; } memset(buf, 0, MINI_BASEMAC_LEN); fd = open(MINI_BASE_MACFILE, O_RDWR); if (fd < 0) { printf("open %s fail\n", MINI_BASE_MACFILE); return -1; } ret = read(fd, buf,MINI_BASEMAC_LEN); if (ret < 0) { printf("read %s failed\n", MINI_BASE_MACFILE); } close(fd); buf[MINI_BASEMAC_LEN - 1] = '\0'; end: return mini_str2mac( buf, mac); } int mini_raw_socket(netlinksock_t *sock, int module, int protocol) { memset(sock, 0, sizeof(netlinksock_t)); sock->sock = socket(AF_NETLINK, SOCK_RAW, protocol); sock->saddr.nl_family = AF_NETLINK; sock->saddr.nl_pid = module; sock->saddr.nl_groups = 0; bind(sock->sock, (struct sockaddr*)&sock->saddr, sizeof(sock->saddr)); sock->daddr.nl_family = AF_NETLINK; sock->daddr.nl_pid = 0; sock->daddr.nl_groups = 0; return 0; } /* used for recv packet */ int mini_raw_recv_pkt(netlinksock_t *sock, int type, void *recv_buf, int *recv_len) { struct nlmsghdr *nlhdr = NULL; struct msghdr msg; struct iovec iov; int ret; #define MAX_MSGSIZE 2000 nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_MSGSIZE)); if(nlhdr == NULL) { return 0; } memset(&msg, 0 ,sizeof(struct msghdr)); nlhdr->nlmsg_len = NLMSG_LENGTH(MAX_MSGSIZE); nlhdr->nlmsg_pid = sock->saddr.nl_pid; nlhdr->nlmsg_flags = 0; nlhdr->nlmsg_type = type; iov.iov_base = (void *)nlhdr; iov.iov_len = nlhdr->nlmsg_len; msg.msg_name = (void *)&sock->daddr; msg.msg_namelen = sizeof(struct sockaddr_nl); msg.msg_iov = &iov; msg.msg_iovlen = 1; ret = recvmsg(sock->sock, &msg, 0); if (ret <= 0) { //printf("recvmsg err: %d.(errno : %s)\n", ret, strerror(errno)); perror("recvmsg"); free(nlhdr); return 0; } else { *recv_len = nlhdr->nlmsg_len; memcpy(recv_buf, NLMSG_DATA(nlhdr), *recv_len); free(nlhdr); return ret; } } /* used for send packet */ int hal_httpd_send_pkt(netlinksock_t *sock, int type, void *buf, int len) { struct nlmsghdr *nlhdr = NULL; struct msghdr msg; struct iovec iov; int ret; #define MAX_MSGSIZE 2000 nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_MSGSIZE)); if(nlhdr == NULL) { return 0; } memcpy(NLMSG_DATA(nlhdr), buf, len); memset(&msg, 0 ,sizeof(struct msghdr)); nlhdr->nlmsg_len = NLMSG_LENGTH(len); nlhdr->nlmsg_pid = sock->saddr.nl_pid; nlhdr->nlmsg_flags = 0; nlhdr->nlmsg_type = type; iov.iov_base = (void *)nlhdr; iov.iov_len = nlhdr->nlmsg_len; msg.msg_name = (void *)&sock->daddr; msg.msg_namelen = sizeof(struct sockaddr_nl); msg.msg_iov = &iov; msg.msg_iovlen = 1; ret = sendmsg(sock->sock, &msg, 0); free(nlhdr); return ret; } int mini_raw_shutdown() { int size = 0; int ret; HAL_HTTPDPKT_T pkt; memset(&pkt, 0, sizeof(pkt)); int rawsize; pkt.ifindex = httpd_ifindex; struct httpd_eth_hdr *eth; eth = (struct httpd_eth_hdr *)pkt.data; memcpy(eth->dmac, minidstmac, 6); memcpy(eth->smac, minisrcmac, 6); eth->proto = htons(0x7081); eth->framenums = htonl(0); eth->datalen = htonl(size); rawsize = size + 8+sizeof(struct httpd_eth_hdr); pkt.len = rawsize; ret = hal_httpd_send_pkt(&mini_http_raw_pkt_sock, MOS_RAW_PKT_FOR_WEB, (void *)&pkt, rawsize); } int mini_raw_send_pkt(void *buf, int size) { int framenums=1; int datalen=0; ssize_t ret; HAL_HTTPDPKT_T pkt; memset(&pkt, 0, sizeof(pkt)); int rawsize; pkt.ifindex = httpd_ifindex; struct httpd_eth_hdr *eth; eth = (struct httpd_eth_hdr *)pkt.data; memcpy(eth->dmac, minidstmac, 6); memcpy(eth->smac, minisrcmac, 6); eth->proto = htons(0x7081); size_t limitsize = 1100; int cnt = 1; //framenums = size/limitsize; int aa = (size/limitsize); framenums = aa +1; printf("<%s,%d>need send size=%u, aa=%d, framenums=%d\n", __FUNCTION__, __LINE__, size, aa, framenums); if(framenums > 1) { size_t last = size-(framenums*limitsize); int i; unsigned char *p = (unsigned char *)buf; unsigned char *ptmp = pkt.data; for(i=0; iframenums = htonl(cnt); cnt++; datalen = limitsize; eth->datalen = htonl(limitsize); rawsize = limitsize + 8+sizeof(struct httpd_eth_hdr); pkt.len = rawsize; ret = hal_httpd_send_pkt(&mini_http_raw_pkt_sock, MOS_RAW_PKT_FOR_WEB, (void *)&pkt, rawsize ); } if(!last) last = limitsize; eth->framenums = htonl(cnt); datalen = last; eth->datalen = htonl(last); rawsize = last + 8+sizeof(struct httpd_eth_hdr); pkt.len = rawsize; ret = hal_httpd_send_pkt(&mini_http_raw_pkt_sock, MOS_RAW_PKT_FOR_WEB, (void *)&pkt, rawsize ); } else { eth->framenums = htonl(cnt); datalen = size; eth->datalen = htonl(size); memcpy(&pkt.data[sizeof(struct httpd_eth_hdr)], buf, size); rawsize = size + 8+sizeof(struct httpd_eth_hdr); pkt.len = rawsize; ret = hal_httpd_send_pkt(&mini_http_raw_pkt_sock, MOS_RAW_PKT_FOR_WEB, (void *)&pkt, rawsize); } //printf("send ret=%u, framenums=%d, size=%u, httpd_ifindex=0x%x\n", ret, framenums, datalen, httpd_ifindex); return datalen; }