bridgeソフトウェアの改造について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
愛美

bridgeソフトウェアの改造について

#1

投稿記事 by 愛美 » 3ヶ月前

提出の締め切り日が近く、1週間ぐらい悩んでも分からなかった為、皆様のお力を貸していただきたいと思い、当サイトを利用します。
課題としては、
1.これを改造して、ARP、IPv4、IPv6のパケットカウントを行い結果を表示するようにする。
2.0ms~20,sの間でランダムな回線遅延を起こすネットワークエミュレータに改造しなさい。
というものです。
私はプログラミング全体が苦手で先生の解説を聞いても理解することが難しく、この課題の問題も分かりません...
rand関数と何かを使えばできると言っていて、調べたりしたのですがやっぱりわかりませんでした...
そこで、教えて頂きたいことが、「何をどこに追加すれば2つの課題ができるようになるのか」です。
本当に申し訳ないのですが。お力を貸してください。

コード: 全て選択

#include	<stdio.h>
#include	<string.h>
#include	<unistd.h>
#include	<poll.h>
#include	<errno.h>
#include	<signal.h>
#include	<stdarg.h>
#include	<sys/socket.h>
#include	<arpa/inet.h>
#include	<netinet/if_ether.h>
#include	"netutil.h"

typedef struct	{
	char	*Device1;
	char	*Device2;
	int	DebugOut;
}PARAM;
PARAM	Param={"eth0","eth1",1};

typedef struct	{
	int	soc;
}DEVICE;
DEVICE	Device[2];

int	EndFlag=0;

int DebugPrintf(char *fmt,...)
{
	if(Param.DebugOut){
		va_list	args;

		va_start(args,fmt);
		vfprintf(stderr,fmt,args);
		va_end(args);
	}

	return(0);
}

int DebugPerror(char *msg)
{
	if(Param.DebugOut){
		fprintf(stderr,"%s : %s\n",msg,strerror(errno));
	}

	return(0);
}

int AnalyzePacket(int deviceNo,u_char *data,int size)
{
u_char	*ptr;
int	lest;
struct ether_header	*eh;

	ptr=data;
	lest=size;

	if(lest<sizeof(struct ether_header)){
		DebugPrintf("[%d]:lest(%d)<sizeof(struct ether_header)\n",deviceNo,lest);
		return(-1);
	}
	eh=(struct ether_header *)ptr;
	ptr+=sizeof(struct ether_header);
	lest-=sizeof(struct ether_header);
	DebugPrintf("[%d]",deviceNo);
	if(Param.DebugOut){
		PrintEtherHeader(eh,stderr);
	}

	return(0);
}

int Bridge()
{
struct pollfd	targets[2];
int	nready,i,size;
u_char	buf[2048];

	targets[0].fd=Device[0].soc;
	targets[0].events=POLLIN|POLLERR;
	targets[1].fd=Device[1].soc;
	targets[1].events=POLLIN|POLLERR;

	while(EndFlag==0){
		switch(nready=poll(targets,2,100)){
			case	-1:
				if(errno!=EINTR){
					perror("poll");
				}
				break;
			case	0:
				break;
			default:
				for(i=0;i<2;i++){
					if(targets[i].revents&(POLLIN|POLLERR)){
						if((size=read(Device[i].soc,buf,sizeof(buf)))<=0){
							perror("read");
						}
						else{
							if(AnalyzePacket(i,buf,size)!=-1){
								if((size=write(Device[(!i)].soc,buf,size))<=0){
									perror("write");
								}
							}
	
						}
					}
				}
				break;
		}
	}

	return(0);
}

int DisableIpForward()
{
FILE    *fp;

	if((fp=fopen("/proc/sys/net/ipv4/ip_forward","w"))==NULL){
		DebugPrintf("cannot write /proc/sys/net/ipv4/ip_forward\n");
		return(-1);
	}
	fputs("0",fp);
	fclose(fp);

	return(0);
}

void EndSignal(int sig)
{
	EndFlag=1;
}

int main(int argc,char *argv[],char *envp[])
{
	if((Device[0].soc=InitRawSocket(Param.Device1,1,0))==-1){
		DebugPrintf("InitRawSocket:error:%s\n",Param.Device1);
		return(-1);
	}
	DebugPrintf("%s OK\n",Param.Device1);

	if((Device[1].soc=InitRawSocket(Param.Device2,1,0))==-1){
		DebugPrintf("InitRawSocket:error:%s\n",Param.Device1);
		return(-1);
	}
	DebugPrintf("%s OK\n",Param.Device2);

	DisableIpForward();

	signal(SIGINT,EndSignal);
	signal(SIGTERM,EndSignal);
	signal(SIGQUIT,EndSignal);

	signal(SIGPIPE,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);
	signal(SIGTTOU,SIG_IGN);

	DebugPrintf("bridge start\n");
	Bridge();
	DebugPrintf("bridge end\n");

	close(Device[0].soc);
	close(Device[1].soc);

	return(0);
} 

sleep

Re: bridgeソフトウェアの改造について

#2

投稿記事 by sleep » 3ヶ月前

少し調べさせていただきましたが、
掲示されたコードは技術評論社から一般販売されている「ルーター自作でわかるパケットの流れ」のサンプルコードですよね。
愛美 さんが書きました: そこで、教えて頂きたいことが、「何をどこに追加すれば2つの課題ができるようになるのか」です。
私は代わりに課題を解くことはしません。
情報を出しておきます。

愛美 さんが書きました: 1.これを改造して、ARP、IPv4、IPv6のパケットカウントを行い結果を表示するようにする。
main.c の AnalyzePacket関数の62行目で、サイズ確認後に netutil.c の PrintEtherHeader関数にて表示するイーサネットのヘッダ情報を確認できる構造体を用意しています。
eh=(struct ether_header *)ptr;

netutil.c の PrintEtherHeader関数の89行目で、
ntohs(eh->ether_type)の結果を見てswitch文で分岐している箇所がありますが、ここでデータ部にどのプロトコルのデータが含まれているかを確認しています。

AnalyzePacket関数かPrintEtherHeader関数の中でカウントを行い、PrintEtherHeader関数で表示を行えば良いでしょう。

愛美 さんが書きました: 0ms~20,sの間でランダムな回線遅延を起こすネットワークエミュレータに改造しなさい。
main.c の Bridge関数の101行目で、write(Device[(!i)].soc,buf,size)にて、片方のデバイスで受信したデータをもう片方のデバイスへ送り出しています。

遅延を演出するためにrand関数から取得した0ms~20,sを演出するための値とその値を使用して100行目と101行目の間で先生のおっしゃってる何かを使えば良いでしょう。

愛美

返信ありがとうございます。

#3

投稿記事 by 愛美 » 3ヶ月前

返信ありがとうございます。
本当に申し訳ないのですが、全然分からないです...
締め切りが今週末で焦って頭も回らないです...すいません...
ほんの少しでいいので答えみたいなものを教えて頂きたいです。

返信

“C言語何でも質問掲示板” へ戻る