===================================帧的接收和发送==========================
-----------文件名称:sendfile.c, 帧的发送
采用libnet,#define VERSION "1.1.0"
gcc -DHAVE_CONFIG_H -I. -I. -I../include -g -O2 -Wall -c sendfile.c
gcc -g -O2 -Wall -o sendfile sendfile.o ../src/libnet.a
======================代码===============================
#if (HAVE_CONFIG_H)
#include "../include/config.h"
#endif
#include "./libnet_test.h"
int packetl=0;
int send_payload(char *payload)
{
int c;
libnet_t *l;
libnet_ptag_t t;
char errbuf[LIBNET_ERRBUF_SIZE];
/******************** 定义设备环境***********************/
char *device="eth0";
u_char enet_src[6] = {0x00, 0x0c, 0x29, 0x90, 0xf4, 0xaa}; //160 ip
//u_char enet_dst[6] = {0x00, 0x07, 0xe9, 0x82, 0xcf, 0xba}; //209 ip
//u_char enet_dst[6] = {0x00, 0x0B, 0x2F, 0x15, 0x9A, 0x45}; //163 ip
//000c2990f4aa
u_char enet_dst[6] = {0x00, 0x0c, 0x29, 0x90, 0xf4, 0xaa}; //160 ip
/********************************************************/
/// printf("libnet 1.1 packet shaping: TCP + options[link]\n");
/*
* Initialize the library. Root priviledges are required.
*/
l = libnet_init(
LIBNET_LINK, /* injection type */
device, /* network interface */
errbuf); /* error buffer */
if (l == NULL)
{
fprintf(stderr, "libnet_init() failed: %s", errbuf);
exit(EXIT_FAILURE);
}
int frame_len=1400; //最大mtu定义为1314
if(strlen(payload)>frame_len)
{
fprintf(stderr, "frame too long");
exit(EXIT_FAILURE);
}
t = libnet_build_ethernet(
enet_dst, /* ethernet destination */
enet_src, /* ethernet source */
ETHERTYPE_IP, /* protocol type */
payload, /* payload */
frame_len, /* payload size */
l, /* libnet handle */
0); /* libnet id */
if (t == -1)
{
fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(l));
libnet_destroy(l);
return (EXIT_FAILURE);
}
/*
* Write it to the wire.
*/
c = libnet_write(l);
if (c == -1)
{
fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
libnet_destroy(l);
return (EXIT_FAILURE);
}
else
{
// fprintf(stderr, "Wrote %d byte TCP packet; check the wire.\n", c);
}
libnet_destroy(l);
return (EXIT_SUCCESS);
}
int sendfile(char *filename,long int filelong)
{
FILE *fp;
char payload[1300];
bzero(payload,1300);
char strline[1300];
int i=0;
int j=11;
for(i=0;i {
bzero(payload,1300);
strcpy(payload,"NTSW0000000000000000000000000000000000000000");//NTSW+20位0的清零标志+20位的0内容crc校验码,发送10次,表示文件开始传输
send_payload(payload);
printf("\npayload=%s\n",payload);
i++;
}
bzero(payload,1300);
for(i=0;i {
bzero(payload,1300);
sprintf(payload,"NTSWffffffffffffffffffff00000000000000000000%s",filename);//NTSW+20位f的文件名位+20位的0内容crc校验码+剩余的文件名,发送10次,表示传送的是文件名
send_payload(payload);
printf("\npayload=%s\n",payload);
i++;
}
bzero(payload,1300);
for(i=0;i {
bzero(payload,1300);
sprintf(payload,"NTSWllllllllllllllllllll00000000000000000000%ld",filelong);//NTSW+20位l的文件长度位+20位的0内容crc校验码+剩余的文件大小,发送10次,表示传送的是文件大小
send_payload(payload);
printf("\npayload=%s\n",payload);
i++;
}
//filelong=0;
char rowflag[20];
long int m=1;
long int reallen=0,p=0,pp=0;
char tmpfilename[256];
sprintf(tmpfilename,"/tmp/%s",filename);
if((fp=fopen(tmpfilename,"rb"))==NULL)
{
printf("\n______error cant open tmpfile %s_____\n",tmpfilename);
return -1;
}
while(!feof(fp))
{
if((reallen=fread(strline,1,1200,fp))<=0)
{
break;
}
/*
printf("\nstrline=");
for(pp=0;pp<1200;pp++)
printf("%c",strline[pp]);
*/
bzero(rowflag,20);
sprintf(rowflag,"%010ld",m);
bzero(payload,1300);
sprintf(payload,"NTSWssssssssss%s00000000000000000000",rowflag); ////NTSW+10位的s文件内容位+10文件行数位(不足补0)+20位的内容crc校验码+传送的文件内容,发送10次,表示传送的是文件内容
// printf("\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& %ld&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n",reallen);
for(p=0;(p<1200)&&(p {
payload[44+p]=strline[p];
}
int tempchar=strline[p-1]+12;
for(pp=0;pp<(1200-reallen);pp++)
payload[44+p+pp]=tempchar;
for(i=0;i {
send_payload(payload);
packetl++;
// printf("\n____packetl=%d",packetl);
/*
printf("\npayload=");
for(pp=0;pp<1200;pp++)
printf("%c ",payload[pp]);*/
i++;
}
if(m%20==0)
{
printf("\nn_________m=%ld__________sleep\n",m);
usleep(100);
bzero(strline,1300);
}
m++;
}
fclose(fp);
//printf("\nfilelong=%ld,payload=%s\n",filelong,payload);
return (EXIT_SUCCESS);
}
int main()
{
char filename[256];
long int filelong=0;
char strline[1300];
FILE *fp;
//int i;
//for(i=0;i<1;i++)
//while(1)
//{
filelong=0;
strcpy(filename,"/tmp/test");
if((fp=fopen(filename,"rb"))==NULL)
{
printf("can not open file %s",filename);
return -1;
}
while(!feof(fp))
{
if(fread(strline,1,1200,fp)<=0)
//if(fgets(strline,255,fp)==NULL)
{
break;
}
filelong++;
}
fclose(fp);
sendfile("test",filelong);
//}
return (EXIT_SUCCESS);
}
=============================================================================
-----------文件名称:receive.c,
帧的接收采用libpcap,#define VERSION 0.9.5
gcc receivefile.c -l pcap -o receivefile
======================代码===============================
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*定义一个全局的session,存储关于新建立文件的信息*/
struct session_t {
int fileflag; //是否在新建文件状态中
char filename[256]; //文件名称
long int filelong ;//文件长度
long int fileline;
long int timeout;//文件传输开始时间,为了记录延时
};
struct session_t session;
int free_session()
{
session.fileflag=0;
bzero(session.filename,sizeof(session.filename));
session.filelong=0;
session.fileline=0;
return 0;
}
/*文件内容缓冲区,把每个文件内容存储起来*/
char wbuf[500][1300]; //第一纬里边现在帧的个数,第二纬记录帧的内容
int wbufline=0; //记录缓冲区里边有多少个内容
/*对捕获的包进行切割成结构*/
struct packet_ntsw {
char head[5]; //帧头内容为NTSW,所有帧头是以这开头,否则过滤掉,不要。
char flag[21]; //标志位,20位,接收到20个全0,并且接收到10次,表示开始传输文件
char crc[21]; //每个数据段的crc校验码
char filestring[1300];
};
int file_lstat(char * path) ///判断文件的类型
{
struct stat buf;
if (lstat(path,&buf)<0)
{
return -1; //////file no exits;
}
if (S_ISREG(buf.st_mode))
return 1; ///regular file
if (S_ISDIR(buf.st_mode))
return 2; ///dir file
return 0;
}
int packet_struct(char *payload,struct packet_ntsw *packet_t) //对传输进来的数据进行切割,如果格式不正确返回NULl
{
int i=0,j=0;
while(payload[i])
{
i++;
}
if(i<44)
return -1;
i=0,j=0;
//while(payload[i])
for(i=0;i<1244;i++)
{
if(i<4)
{
packet_t->head[j]=payload[i];
j++;
}
if(i==4)
{
j=0;
packet_t->head[4]='\0';
}
if((i>=4)&&(i<=23))
{
packet_t->flag[j]=payload[i];
j++;
}
if(i==24)
{
j=0;
packet_t->flag[20]='\0';
}
if((i>=24)&&(i<=43))
{
packet_t->crc[j]=payload[i];
j++;
}
if(i==44)
{
j=0;
packet_t->crc[20]='\0';
}
if(i>=44)
{
packet_t->filestring[j]=payload[i];
j++;
}
}
packet_t->filestring[j]='\0';
return 0;
}
int makenewfile(struct packet_ntsw *packet_t)
{
FILE *fp;
if(strcmp(packet_t->head,"NTSW")!=0) //表示帧不是我们要的
{
return -1;
}
//printf("session.filename=%s\n",session.filename);
// printf("fileflag=%s,crc=%s,filestring=%s\n",packet_t->flag,packet_t->crc,packet_t->filestring);
if((strcmp(packet_t->flag,"00000000000000000000")==0)&&!session.fileflag) //开始生成新的文件
{
//session=(struct session_t)malloc(sizeof(struct session_t));
/// memset(&session,'\0', sizeof(session));
free_session();
session.fileflag=1;
printf("session.fileflag=%d\n",session.fileflag);
//file_buf=(struct file_buf_t *)malloc(sizeof(struct file_buf_t)*50)
}
if((strcmp(packet_t->flag,"ffffffffffffffffffff")==0)&&session.fileflag==1) //表示传输的是文件名
{
if(strlen(session.filename)<1)
{
strcpy(session.filename,packet_t->filestring);//记录文件名
printf("session.filename=%s\n",session.filename);
}
}
if(strcmp(packet_t->flag,"llllllllllllllllllll")==0&&session.fileflag==1) //表示传输的是文件长度
{
if(session.filelong==0)
{
//初始化文件信息
/// printf("fileflag=%s,crc=%s,filestring=%s\n",packet_t->flag,packet_t->crc,packet_t->filestring);
session.filelong=atol(packet_t->filestring); //记录文件长度
session.fileline=1; //文件发送到哪一行 ,初始化为1
printf("session.filelong=%ld\n",session.filelong);
}
}
///printf("\nfileflag=%s,crc=%s,filestring=%s\n",packet_t->flag,packet_t->crc,packet_t->filestring);
if((strncmp(packet_t->flag,"ssssssssss",10)==0)&&(session.fileflag==1)&&session.filelong&&session.filename) //传输文件内容
{
int i=10;
char fileline[256];
while(packet_t->flag[i]) //这时候记录的内容为文件里边的行数
{
if(packet_t->flag[i]!='0')
break;
i++;
}
int j=0;
while(packet_t->flag[i]) //这时候记录的内容为文件里边的行数
{
fileline[j]=packet_t->flag[i];
i++;
j++;
}
fileline[j]='\0';
// printf("session.fileline=%d,fileline=%s,packet_t->filestring=%s\n",session.fileline,fileline,packet_t->filestring);
if(session.fileline==atol(fileline)) //行数正确开始记录数据内容
{
//packet_t->filestring 存储到缓冲区去,接收到50个包时候写一次文件
strncpy(wbuf[wbufline],packet_t->filestring,1200);
for(i=0;i<1200;i++)
{
wbuf[wbufline][i]=packet_t->filestring[i];
}
///printf("\nwbuf[%d]=%s\n",wbufline,wbuf[wbufline]);
if(wbufline==100) //每收到50个包时候,写入文件里边
{
char tmpfilename[256];
sprintf(tmpfilename,"/tmp/tmpdir/%s",session.filename);
if((fp=fopen(tmpfilename,"ab+"))==NULL)
{
printf("\n______error cant open tmpfile %s_____\n",tmpfilename);
return -1;
}
for(i=0;i<=wbufline;i++)
{
//printf("\n \n \n \n___write file ___wbufline=%d,i=%d,wbuf[%d]=%s\n\n \n \n \n",wbufline,i,i,wbuf[i]);
//fprintf(fp,wbuf[i]);
/*
int mm=0;
printf("\n{{{{{{wbufline[%d]=",i);
for(mm=0;mm<1200;mm++)
printf("%c",wbuf[i][mm]);
*/
printf("\nwrite file11 wbufline=%ld",wbufline);
fwrite(wbuf[i],1,1200,fp);
}
fclose(fp);
wbufline=0;
}else
{
wbufline++;
}
session.fileline=session.fileline+1;//行数加1
// printf("session.filename=%s,session.filelong=%ld,session.fileflag=%d,session.fileline=%ld,fileline=%ld,filestring=%s\n",session.filename,session.filelong,session.fileflag,session.fileline,atol(fileline),packet_t->filestring);
}
if(session.fileline==session.filelong+1)
{
//文件传输结束,把缓冲区里边的内容写到文件里边去
char tmpfilename[256];
sprintf(tmpfilename,"/tmp/tmpdir/%s",session.filename);
if((fp=fopen(tmpfilename,"ab+"))==NULL)
{
printf("\n______error cant open tmpfile %s_____\n",tmpfilename);
free_session();
return -1;
}
int pp=1200,nn=1200;
for(i=0;i {
printf("\n end ___write file ___wbufline=%d,i=%d\n",wbufline,i);
if(i<(wbufline-1))
{
printf("\nwrite file22 wbufline=%ld",wbufline);
fwrite(wbuf[i],1,1200,fp);
}
else
{
for(pp=1200;(wbuf[i][pp-1]==wbuf[i][1199])&&pp>0;pp--);
{
printf("\nwrite file33 wbufline=%ld",wbufline);
fwrite(wbuf[i],1,pp,fp);
}
}
}
fclose(fp);
wbufline=0;
char realfilename[256];
sprintf(realfilename,"/tmp/realfile/%s",session.filename);
if (file_lstat(realfilename)==-1)
{
rename(tmpfilename,realfilename);
printf("\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@receive file ");
}
//printf("\naddddddddddddddddd\n");
//packet_t->filestring 存储到缓冲区去,接收到50个包时候写一次文件,文件接收完毕,把缓冲区里边的内容写到文件去
free_session();
return 0;
}
}
return 0;
}
/* callback function that is passed to pcap_loop(..) and called each time
* a packet is recieved */
void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*
packet)
{
static int count = 1;
int i=0;
char payload[1314];
struct packet_ntsw *payload_t;
///strncpy(payload ,(u_char *)(packet+14),1200+44); //packet内容减去14为我们传输的数据内容,14为mac头,
for(i=0;i<1200+44;i++)
{
payload[i]=packet[i+14];
}
/*
int mm=0;
printf("\npayload=");
for(mm=14;mm<1244;mm++)
printf("%c",packet[mm]);
*/
payload_t=(struct packet_ntsw *)malloc(sizeof(struct packet_ntsw)); //每发送一次,都申请结构空间,使用后释放掉。
if (payload_t)
{
memset(payload_t, '\0', sizeof(payload_t));
if(packet_struct(payload,payload_t)!=-1)
{
/*
printf("\nwbuf=");
for(mm=0;mm<1200;mm++)
printf("%c",payload_t->filestring[mm]);
*/
//printf("\n----------count=%d--------\n",count);
///printf("\n----------head=%s,flag=%s,crc=%s,filestring=%s----------\n",payload_t->head,payload_t->flag,payload_t->crc,payload_t->filestring);
makenewfile(payload_t);
free(payload_t);//释放掉
}else{
/// printf("\n----------count=%d--------\n",count);
// printf("\n----------error packet-------%s\n",payload);
}
}
count++;
}
int main()
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr; /* pcap.h */
struct ether_header *eptr; /* net/ethernet.h */
dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{
printf("%s\n",errbuf); exit(1);
}
/// descr = pcap_open_live(dev,1314,1,500,errbuf); //模式为混杂模式,可以接受所有的数据包
descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
if(descr == NULL)
{
printf("pcap_open_live(): %s\n",errbuf);
exit(1);
}
pcap_loop(descr, -1, my_callback, NULL); //捕获50个包
// packet = pcap_next(descr,&hdr);
///fprintf(stdout,"packet=%s\n",packet);
pcap_close(descr);
}