295 lines
6.9 KiB
C
295 lines
6.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/fcntl.h>
|
|
#include <sys/socket.h>
|
|
#include <linux/if_ether.h>
|
|
#include <linux/netlink.h>
|
|
|
|
#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; i<framenums-1; i++)
|
|
{
|
|
memset(ptmp, 0, limitsize);
|
|
memcpy(ptmp, p, limitsize);
|
|
p+=limitsize;
|
|
|
|
|
|
eth->framenums = 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;
|
|
}
|
|
|
|
|