Files
repo-smod-atsc/src/mini_httpd/mini_httpd_raw.c
T

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;
}