合計 昨日 今日

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

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: 愛美
[URL]
Date: 2018年1月10日(水) 16:09
No: 1
(OFFLINE)

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

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

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#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);
}

Name: sleep
[URL]
Date: 2018年1月10日(水) 19:26
No: 2
(OFFLINE)

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

少し調べさせていただきましたが、
掲示されたコードは技術評論社から一般販売されている「ルーター自作でわかるパケットの流れ」のサンプルコードですよね。

愛美 さんが書きました:そこで、教えて頂きたいことが、「何をどこに追加すれば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行目の間で先生のおっしゃってる何かを使えば良いでしょう。

Name: 愛美
[URL]
Date: 2018年1月11日(木) 02:15
No: 3
(OFFLINE)

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

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


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[25人]