?? 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 + -