📄 packet_gen.c
字号:
/**********************************************************
* 版权所有 (C)2007, 深圳市中兴通讯股份有限公司。
*
* 文件名称:packet_gen.c
* 文件标识:
* 内容摘要: 模拟ENPU演示程序处理函数
* 其它说明:
* 当前版本:
* 作 者:丁 鹏
* 完成日期:2007/12/11
*
* 修改记录1:
* 修改日期:
* 版 本 号:
* 修 改 人:
* 修改内容:
**********************************************************/
/***********************************************************
* 头文件 *
***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define __FAVOR_BSD
#include <netinet/tcp.h>
#include <netinet/udp.h>
#undef __FAVOR_BSD
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
/***********************************************************
* 全局变量 *
***********************************************************/
unsigned short ip_id;
/***********************************************************
* 全局函数 *
***********************************************************/
void UdpHdrGen(struct udphdr *udpHdr, unsigned short int idport, unsigned short int isport, unsigned short int msglen);
void IpHdrGen(struct ip *ipHdr, unsigned char *sdaddr, unsigned char *ssaddr, unsigned int msglen, unsigned char proto);
void ethHdrGen(struct ethhdr *ethhdr, unsigned char *cdmac, unsigned char *csmac);
unsigned short checksum(unsigned short *buffer, int size);
int getMac(unsigned char *ipaddr, unsigned char *mac);
/**********************************************************************
* 函数名称:UdpHdrGen
* 功能描述:构造udp头
* 输入参数:
udpHdr 构造的udp头的存放地址
idport 源udp端口
isport 目的udp端口
msglen udp负荷长度,不包括udp头长
* 输出参数:无
* 返 回 值:无
* 其它说明:无
* 修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
* 2007/12/11 丁鹏 创建
************************************************************************/
void UdpHdrGen(struct udphdr *udpHdr, unsigned short int idport, unsigned short int isport, unsigned short int msglen)
{
if(udpHdr == NULL)
{
printf("UdpHdrGen get udpHdr err\n");
return ;
}
udpHdr->uh_dport = htons(idport);
udpHdr->uh_sport = htons(isport);
udpHdr->uh_ulen = htons(msglen+sizeof(struct udphdr)); /* updhdr + msgdatalen */
udpHdr->uh_sum = 0;
}
/**********************************************************************
* 函数名称:IpHdrGen
* 功能描述:构造IP头
* 输入参数:
ipHdr 构造的ip头的存放地址
sdaddr 源IP地址
ssaddr 目的udp端口
msglen 发送消息体长度,不包括upd头,ip头,eth头
proto
* 输出参数:无
* 返 回 值:无
* 其它说明:无
* 修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
* 2007/12/11 丁鹏 创建
************************************************************************/
void IpHdrGen(struct ip *ipHdr, unsigned char *sdaddr, unsigned char *ssaddr, unsigned int msglen, unsigned char proto)
{
if( ipHdr == NULL)
{
printf("IpHdrGen get ipHdr err\n");
return ;
}
ipHdr->ip_hl = 5; /* ip_hl << 2 ----ip头长度,这里我们选为标准的20字节 */
ipHdr->ip_v = 4; /* ip版本, ipv4 */
ipHdr->ip_tos = 0; /* normal service */ /*这个8bit字段由3bit的优先权子字段(现在已经被忽略),4 bit的TOS子字段以及1 bit的未用字段(现在为
0)构成。4 bit的TOS子字段包含:最小延时、最大吞吐量、最高可靠性以及最小费用
构成,这四个1 bit位最多只能有一个为1,本例中都为0,表示是一般服务。 */
ipHdr->ip_len = htons(msglen + sizeof(struct udphdr)+sizeof(struct ip)); /* 包括ip头长 */
ipHdr->ip_id = htons(ip_id++); /* 包括ip头长 */
ipHdr->ip_off = 0; /* 其中第一位是IP协议目前没有用上的,为0。接着的是两个标志DF和MF。
DF为1表示不要分段,MF为1表示还有进一步的分段(本例为0)。
然后的“0 0000”是分段片移(Fragment Offset)。 */
ipHdr->ip_ttl = IPDEFTTL; /* time to live, 64 by default,linux */
ipHdr->ip_p = proto;
ipHdr->ip_sum = 0; /* check crc */
ipHdr->ip_src.s_addr = inet_addr(ssaddr);
ipHdr->ip_dst.s_addr = inet_addr(sdaddr);
ipHdr->ip_sum = htons(checksum((unsigned short *)ipHdr,sizeof(struct ip)));
}
/**********************************************************************
* 函数名称:ethHdrGen
* 功能描述:构造eth头
* 输入参数:
ipHdr 构造的eth头的存放地址
sdmac 源MAC地址
ssmac 目的方MAC地址
* 输出参数:无
* 返 回 值:无
* 其它说明:无
* 修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
* 2007/12/11 丁鹏 创建
************************************************************************/
void ethHdrGen(struct ethhdr *ethhdr, unsigned char *sdmac, unsigned char *ssmac)
{
memcpy(ethhdr->h_dest,sdmac, ETH_ALEN);
memcpy(ethhdr->h_source,ssmac, ETH_ALEN);
ethhdr->h_proto = htons(ETH_P_IP);
}
/**********************************************************************
* 函数名称:checksum
* 功能描述:校验和计算
* 输入参数:
buffer 开始地址处,从这开始计算内存内容的校验和
size 计算多少个字节的校验和
* 输出参数:
* 返 回 值:校验和数值
* 其它说明:无
* 修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
* 2007/12/11 丁鹏 创建
************************************************************************/
unsigned short checksum(unsigned short *buffer, int size)
{
register unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(unsigned short);
}
if(size)
cksum += *(unsigned short*)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (unsigned short)(~cksum);
}
/**********************************************************************
* 函数名称:getMac
* 功能描述:取得MAC地址
* 输入参数:
ipaddr ip地址
* 输出参数:
Mac 对应ip的MAC地址
* 返 回 值:
对应ip地址的序列号
* 其它说明:无
* 修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
* 2007/12/11 丁鹏 创建
************************************************************************/
int getMac(unsigned char *ipaddr, unsigned char *Mac)
{
int ret = 0;
printf("ipaddr:%s", ipaddr);
if(rules_memcmp(ipaddr, "10.16.8.53", sizeof("10.16.8.53")) == 0)
{
*(unsigned char *)Mac=0x00;
*(unsigned char *)(Mac+1)=0x11;
*(unsigned char *)(Mac+2)=0x5B;
*(unsigned char *)(Mac+3)=0x29;
*(unsigned char *)(Mac+4)=0x7F;
*(unsigned char *)(Mac+5)=0x3A;
ret = 1;
}
else if(rules_memcmp(ipaddr, "10.16.8.55", sizeof("10.16.8.55")) == 0)
{
*(unsigned char *)Mac=0x00;
*(unsigned char *)(Mac+1)=0x11;
*(unsigned char *)(Mac+2)=0x85;
*(unsigned char *)(Mac+3)=0xBA;
*(unsigned char *)(Mac+4)=0xE9;
*(unsigned char *)(Mac+5)=0x18;
ret = 2;
}
else if(rules_memcmp(ipaddr, "10.16.8.51", sizeof("10.16.8.51")) == 0)
{
*(unsigned char *)Mac=0x00;
*(unsigned char *)(Mac+1)=0x0E;
*(unsigned char *)(Mac+2)=0x0C;
*(unsigned char *)(Mac+3)=0x50;
*(unsigned char *)(Mac+4)=0x72;
*(unsigned char *)(Mac+5)=0x32;
ret = 3;
}
else if(rules_memcmp(ipaddr, "10.16.8.63", sizeof("10.16.8.63")) == 0)
{
*(unsigned char *)Mac=0x00;
*(unsigned char *)(Mac+1)=0x15;
*(unsigned char *)(Mac+2)=0x58;
*(unsigned char *)(Mac+3)=0x12;
*(unsigned char *)(Mac+4)=0x9E;
*(unsigned char *)(Mac+5)=0x5E;
ret = 4;
}
else if(rules_memcmp(ipaddr, "10.16.8.54", sizeof("10.16.8.54")) == 0)
{
*(unsigned char *)Mac=0x00;
*(unsigned char *)(Mac+1)=0x12;
*(unsigned char *)(Mac+2)=0x79;
*(unsigned char *)(Mac+3)=0xD0;
*(unsigned char *)(Mac+4)=0x71;
*(unsigned char *)(Mac+5)=0x9D;
ret = 5;
}
else
{
ret = 0;
}
return ret;
}
/**********************************************************************
* 函数名称:ipcrcCheck
* 功能描述:判断收到的ip报文的ip校验和是否正确
* 输入参数:
ipHdr 收到报文的ip头
* 输出参数:无
* 返 回 值:
校验和正确
校验和错误
* 其它说明:无
* 修改日期 版本号 修改人 修改内容
* ---------------------------------------------------------------------
* 2007/12/11 丁鹏 创建
************************************************************************/
int ipcrcCheck(struct ip *ipHdr)
{
unsigned short crcPacket;
unsigned short crcCheck;
crcPacket = ntohs(ipHdr->ip_sum);
ipHdr->ip_sum = 0;
crcCheck = checksum((unsigned short *)ipHdr,sizeof(struct ip));
if(crcPacket != crcCheck)
{
printf("ip crc check wrong ...packet(%02x), my(receive %x)---\n", crcPacket, crcCheck);
return ERR_IP_CRCC_WRONG;
}
else
{
printf("ip crc:packet %x, my %x---\n", crcPacket, crcCheck);
}
ipHdr->ip_sum = crcCheck;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -