This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-tfe/plugin/business/decrypt-mirroring/src/sendpkt.cpp

468 lines
11 KiB
C++
Raw Normal View History

2018-09-02 16:34:15 +08:00
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <unistd.h>
#include <net/if.h>
#include <sendpkt-inl.h>
static volatile uint64_t g_rand_seed = 0x013579ABCDEF;
#define SENDPACKET_CKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
unsigned int deliver_rand(void)
{
return g_rand_seed ^ (unsigned int)random();
}
unsigned int deliver_rand_range(unsigned int start, unsigned int end)
{
unsigned int rand_num = deliver_rand();
if(start > end)
{
return end + rand_num % (start - end + 1);
}
return start + rand_num % (end - start + 1);
}
/* ascii字符转16进制 */
char MESA_ascii_to_hex(char ascii)
{
char c = 0;
switch(ascii)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
c = ascii - 0x30;
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
c = 10 + ascii - 0x61;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
c = 10 + ascii - 0x41;
break;
}
return c;
}
/* 2012-04-10 LiJia add, 获取网卡MAC地址
:
device:
mac: MAC地址的数组,,
MAC地址为11:22:33:44:55:66,mac[0]0x11,mac[5]0x66.
:
0:
-1:
*/
int deliver_get_dev_mac(const char *device, unsigned char mac[6])
{
struct ifreq ifr;
int fd;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
{
return -1;
}
memset(ifr.ifr_ifrn.ifrn_name, 0, sizeof(ifr.ifr_ifrn.ifrn_name));
strncpy(ifr.ifr_ifrn.ifrn_name, device, sizeof(ifr.ifr_ifrn.ifrn_name));
if(ioctl(fd, SIOCGIFHWADDR, &ifr) == -1)
{
printf("Cann't get hwaddr of %s:%s\n", device, strerror(errno));
goto err_exit;
}
if(ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
{
printf("'%s' is not ethernet interface!\n", device);
goto err_exit;
}
memcpy(mac, ifr.ifr_ifru.ifru_addr.sa_data, 6);
close(fd);
return 0;
err_exit:
close(fd);
return -1;
}
/* 2012-04-11 LiJia add,将MAC字符串形式转换为16进制MAC地址.
:
str: MAC地址字符串
delim: ':', '-',: xx:xx:xx:xx:xx:xx
delim设为-1.
mac: MAC地址的数组(),,
MAC地址为11:22:33:44:55:66,mac[0]0x11,mac[5]0x66.
:
0:
-1:
*/
int deliver_mac_pton(const char *str, int delim, char *mac)
{
#define MAC_STR_LEN_DELIM (17) /* length of "11:22:33:44:55:66" */
#define MAC_STR_LEN_NODELIM (12) /* length of "112233445566" */
const char *s = str;
int i;
/* 检查输入合法性 */
if(delim != -1)
{
if(strlen(str) != MAC_STR_LEN_DELIM)
{
printf("MAC string length error!\n");
return -1;
}
}
else
{
if(strlen(str) != MAC_STR_LEN_NODELIM)
{
printf("MAC string length error!\n");
return -1;
}
}
/* 检查输入合法性同时转换成16进制值 */
for(i = 0; i < 6; i++)
{
mac[i] = 0; /* 先清零,赋值语句都是或操作 */
if(isxdigit(*s)==0)
{
printf("MAC string type error!\n");
return -1;
}
mac[i] |= MESA_ascii_to_hex(*s) << 4;
s++;
if(isxdigit(*s)==0)
{
printf("MAC string type error!\n");
return -1;
}
mac[i] |= MESA_ascii_to_hex(*s);
s++;
if((delim != -1) && i<5 && (*s++ != (char)delim))
{
printf("MAC string type error!\n");
return -1;
}
}
return 0;
}
int sendpacket_in_cksum(unsigned short *addr, int len)
{
int sum;
int nleft;
unsigned short ans;
unsigned short *w;
sum = 0;
ans = 0;
nleft = len;
w = addr;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(char *)(&ans) = *(char *)w;
sum += ans;
}
return (sum);
}
int deliver_do_checksum(unsigned char *buf, int protocol, int len)
{
struct mesa_ip4_hdr *iph_p;
struct mesa_ip6_hdr *ip6h_p;
int ip_hl;
int sum;
int is_ipv6 = 0;
sum = 0;
iph_p = (struct mesa_ip4_hdr *)buf;
if(4 == iph_p->ip_v) /* IP版本号字段IPv4和IPv6格式是相同的 */
{
ip_hl = iph_p->ip_hl << 2;
ip6h_p = NULL;
}
else if(6 == iph_p->ip_v)
{
ip6h_p = (struct mesa_ip6_hdr *)buf;
iph_p = NULL;
ip_hl = sizeof(struct mesa_ip6_hdr);
is_ipv6 = 1;
}
else
{
return (-1);
}
switch (protocol)
{
case IPPROTO_TCP:
{
struct mesa_tcp_hdr *tcph_p = (struct mesa_tcp_hdr *)(buf + ip_hl);
tcph_p->th_sum = 0;
if(is_ipv6)
{
sum = sendpacket_in_cksum((unsigned short*)&ip6h_p->ip6_src, 32);
}
else
{
sum = sendpacket_in_cksum((unsigned short *)&iph_p->ip_src, 8);
}
sum += ntohs(IPPROTO_TCP + len);
sum += sendpacket_in_cksum((unsigned short *)tcph_p, len);
tcph_p->th_sum = SENDPACKET_CKSUM_CARRY(sum);
break;
}
case IPPROTO_UDP:
{
struct mesa_udp_hdr *udph_p =(struct mesa_udp_hdr *)(buf + ip_hl);
udph_p->uh_sum = 0;
if(is_ipv6)
{
sum = sendpacket_in_cksum((unsigned short*)&ip6h_p->ip6_src, 32);
}
else
{
sum = sendpacket_in_cksum((unsigned short*)&iph_p->ip_src, 8);
}
sum += ntohs(IPPROTO_UDP + len);
sum += sendpacket_in_cksum((unsigned short*)udph_p, len);
udph_p->uh_sum = SENDPACKET_CKSUM_CARRY(sum);
break;
}
case IPPROTO_IP:
{
iph_p->ip_sum = 0;
sum = sendpacket_in_cksum((unsigned short*)iph_p, len);
iph_p->ip_sum = SENDPACKET_CKSUM_CARRY(sum);
break;
}
default:
{
return (-1);
}
}
return (1);
}
/*
if playload2 is not NULL, it means that there is ip spice, it must be copied first, then
playload is copied
otherwise, only payload is copied and it includes ip header
*/
int deliver_build_ethhdr(unsigned char *dst, unsigned char *src, unsigned short type,unsigned char *buf)
{
struct mesa_ethernet_hdr eth_hdr;
if (!buf)
{
return (-1);
}
memcpy(eth_hdr.ether_dhost, dst, ETHER_ADDR_LEN); /* destination address */
memcpy(eth_hdr.ether_shost, src, ETHER_ADDR_LEN); /* source address */
eth_hdr.ether_type = htons(type); /* packet type */
memcpy(buf, &eth_hdr, sizeof(eth_hdr));
return (0);
}
/*
if playload2 is not NULL, it means that there is ip spice, it must be copied first, then
playload is copied
otherwise, only payload is copied and it includes ip header
*/
int deliver_build_ethernet(unsigned char *dst, unsigned char *src, unsigned short type,
const unsigned char *payload, int payload_s, unsigned char *buf)
{
struct mesa_ethernet_hdr eth_hdr;
if (!buf)
{
return (-1);
}
memcpy(eth_hdr.ether_dhost, dst, ETHER_ADDR_LEN); /* destination address */
memcpy(eth_hdr.ether_shost, src, ETHER_ADDR_LEN); /* source address */
eth_hdr.ether_type = htons(type); /* packet type */
if (payload && payload_s)
{
memcpy(buf + SENDPACKET_ETH_H, payload, payload_s);
}
memcpy(buf, &eth_hdr, sizeof(eth_hdr));
return (0);
}
int deliver_build_ipv6(unsigned char traffic_class, unsigned int flow_lable,
unsigned short len, unsigned char next_header, unsigned char hop,
const struct in6_addr *src, const struct in6_addr *dst,
const char *payload, int payload_s, unsigned char *buf)
{
struct mesa_ip6_hdr *ip6_h;
if(!buf){
return -1;
}
ip6_h = (struct mesa_ip6_hdr *)buf;
memset(ip6_h, 0, sizeof(struct mesa_ip6_hdr));
ip6_h->ip6_flags[0] = 0x60 | ((traffic_class & 0xF0) >> 4);
ip6_h->ip6_flags[1] = ((traffic_class & 0x0F) << 4) | ((flow_lable & 0xF0000) >> 16);
ip6_h->ip6_flags[2] = flow_lable & 0x0FF00 >> 8;
ip6_h->ip6_flags[3] = flow_lable & 0x000FF;
ip6_h->ip6_payload_len = htons(len);
ip6_h->ip6_nxt_hdr = next_header;
ip6_h->ip6_hop = hop;
memcpy(&ip6_h->ip6_src, src, sizeof(struct in6_addr));
memcpy(&ip6_h->ip6_dst, dst, sizeof(struct in6_addr));
if(payload && payload_s)
{
memcpy(buf + sizeof(struct mesa_ip6_hdr), payload, payload_s);
}
return 0;
}
int deliver_build_ipv4(unsigned short carry_layer_len, unsigned char tos, unsigned short id,
unsigned short frag, unsigned char ttl, unsigned char prot, unsigned int src, unsigned int dst,
const char *payload,int payload_s, unsigned char *buf)
{
struct mesa_ip4_hdr *ip_hdr;
if (!buf)
{
return (-1);
}
ip_hdr = (struct mesa_ip4_hdr *)buf;
ip_hdr->ip_v = 4; /* version 4 */
ip_hdr->ip_hl = 5; /* 20 byte header */
ip_hdr->ip_tos = tos; /* IP tos */
ip_hdr->ip_len = htons(SENDPACKET_IP_H + carry_layer_len); /* total length */
ip_hdr->ip_id = htons(id); /* IP ID */
ip_hdr->ip_off = htons(frag); /* fragmentation flags */
ip_hdr->ip_ttl = ttl; /* time to live */
ip_hdr->ip_p = prot; /* transport protocol */
ip_hdr->ip_sum = 0; /* do this later */
ip_hdr->ip_src.s_addr = src; /* 为什么地址用网络序? 历史遗留原因, 改动太多,只能这么继续了 */
ip_hdr->ip_dst.s_addr = dst; /* 为什么地址用网络序? 历史遗留原因, 改动太多,只能这么继续了 */
if (payload && payload_s)
{
memcpy(buf + SENDPACKET_IP_H, payload, payload_s);
}
return (0);
}
int deliver_build_tcp(unsigned short sp, unsigned short dp, unsigned int seq, unsigned int ack,
unsigned char th_flags, unsigned short win, unsigned short urg,
const char *payload, int payload_s, unsigned char *buf)
{
struct mesa_tcp_hdr *tcp_hdr;
if (!buf)
{
return (-1);
}
tcp_hdr = (struct mesa_tcp_hdr *)buf;
tcp_hdr->th_sport = htons(sp); /* source port */
tcp_hdr->th_dport = htons(dp); /* destination port */
tcp_hdr->th_seq = htonl(seq); /* sequence number */
tcp_hdr->th_ack = htonl(ack); /* acknowledgement number */
tcp_hdr->th_flags = th_flags; /* control flags */
tcp_hdr->th_x2 = 0; /* UNUSED */
tcp_hdr->th_off = 5; /* 20 byte header */
tcp_hdr->th_win = htons(win); /* window size */
tcp_hdr->th_sum = 0; /* checksum done in userland */
tcp_hdr->th_urp = urg; /* urgent pointer */
if (payload && payload_s)
{
// memcpy(buf + SENDPACKET_TCP_H, payload, payload_s);
memcpy(buf + sizeof(struct mesa_tcp_hdr), payload, payload_s);
}
return (0);
}