source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Cedar/Bridge.c @ a1bae3e

trunk
Last change on this file since a1bae3e was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

  • Property mode set to 100644
File size: 12.7 KB
Line 
1// SoftEther UT-VPN SourceCode
2//
3// Copyright (C) 2004-2010 SoftEther Corporation.
4// Copyright (C) 2004-2010 University of Tsukuba, Japan.
5// Copyright (C) 2003-2010 Daiyuu Nobori.
6// All Rights Reserved.
7//
8// http://utvpn.tsukuba.ac.jp/
9//
10// This program is free software; you can redistribute it and/or
11// modify it under the terms of the GNU General Public License
12// version 2 as published by the Free Software Foundation.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License version 2
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22//
23// このファイルは GPL バージョン 2 ライセンスで公開されています。
24// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
25// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
26// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
27// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
28//
29// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
30// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
31// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
32// ホストされています。
33// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
34// および、試験または研究のために利用が行われることを想定して配布
35// しています。
36// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
37// あります。
38// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
39// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
40// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
41// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
42// に組み込みさせていただきます。
43//
44// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
45// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
46//
47// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
48// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
49// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
50// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
51// ください。
52//
53// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
54// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
55// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
56// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
57// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
58// 公益保護にご協力いただきますようお願い申し上げます。
59//
60// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
61// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
62// を保護するための努力を行います。
63//
64// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
65// 日本国内の脆弱性情報届出受付公的機関:
66//         独立行政法人 情報処理推進機構
67//         http://www.ipa.go.jp/security/vuln/report/
68//
69// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
70// 連絡先: http://www.softether.co.jp/jp/contact/
71
72// -----------------------------------------------
73// [ChangeLog]
74// 2010.05.20
75//  新規リリース by SoftEther
76// -----------------------------------------------
77
78// Bridge.c
79// Ethernet ブリッジプログラム
80
81#define BRIDGE_C
82
83#ifdef  WIN32
84#define OS_WIN32
85#endif
86
87#ifdef  OS_WIN32
88
89// Win32 用
90#include "BridgeWin32.c"
91
92#else
93
94// Unix 用
95#include "BridgeUnix.c"
96
97#endif  // OS_WIN32
98
99// 現在の Ethernet デバイス一覧をハッシュする
100UINT GetEthDeviceHash()
101{
102#ifdef  OS_UNIX
103    // UNIX 版
104    UINT num;
105    UINT i;
106    char tmp[4096];
107    UCHAR hash[SHA1_SIZE];
108    TOKEN_LIST *t = GetEthList();
109
110    num = t->NumTokens;
111    tmp[0] = 0;
112    for (i = 0;i < t->NumTokens;i++)
113    {
114        StrCat(tmp, sizeof(tmp), t->Token[i]);
115    }
116    FreeToken(t);
117
118    Hash(hash, tmp, StrLen(tmp), true);
119
120    Copy(&num, hash, sizeof(UINT));
121
122    return num;
123#else   // OS_UNIX
124    // Win32 版
125    UINT ret = 0;
126    MS_ADAPTER_LIST *a = MsCreateAdapterListEx(true);
127    UINT num;
128    UINT i;
129    char tmp[4096];
130    UCHAR hash[SHA1_SIZE];
131
132    tmp[0] = 0;
133    if (a != NULL)
134    {
135        for (i = 0;i < a->Num;i++)
136        {
137            StrCat(tmp, sizeof(tmp), a->Adapters[i]->Title);
138        }
139    }
140    MsFreeAdapterList(a);
141
142    Hash(hash, tmp, StrLen(tmp), true);
143
144    Copy(&num, hash, sizeof(UINT));
145
146    return num;
147#endif  // OS_UNIU
148}
149
150// WinPcap が必要かどうか取得する
151bool IsNeedWinPcap()
152{
153    if (IsBridgeSupported() == false)
154    {
155        // Windows 以外
156        return false;
157    }
158    else
159    {
160        // Windows
161        if (IsEthSupported())
162        {
163            // すでに Ethernet デバイスへのアクセスに成功している
164            return false;
165        }
166        else
167        {
168            // Ethernet デバイスへのアクセスに失敗している
169            return true;
170        }
171    }
172}
173
174// 現在の OS でブリッジがサポートされているかどうか取得する
175bool IsBridgeSupported()
176{
177    UINT type = GetOsInfo()->OsType;
178
179    if (OS_IS_WINDOWS(type))
180    {
181        return true;
182    }
183    else
184    {
185        return IsEthSupported();
186    }
187}
188
189// ローカルブリッジの削除
190bool DeleteLocalBridge(CEDAR *c, char *hubname, char *devicename)
191{
192    bool ret = false;
193    // 引数チェック
194    if (c == NULL || hubname == NULL || devicename == NULL)
195    {
196        return false;
197    }
198
199    LockList(c->HubList);
200    {
201        LockList(c->LocalBridgeList);
202        {
203            UINT i;
204
205            for (i = 0;i < LIST_NUM(c->LocalBridgeList);i++)
206            {
207                LOCALBRIDGE *br = LIST_DATA(c->LocalBridgeList, i);
208
209                if (StrCmpi(br->HubName, hubname) == 0)
210                {
211                    if (StrCmpi(br->DeviceName, devicename) == 0)
212                    {
213                        if (br->Bridge != NULL)
214                        {
215                            BrFreeBridge(br->Bridge);
216                            br->Bridge = NULL;
217                        }
218
219                        Delete(c->LocalBridgeList, br);
220                        Free(br);
221
222                        ret = true;
223                        break;
224                    }
225                }
226            }
227        }
228        UnlockList(c->LocalBridgeList);
229    }
230    UnlockList(c->HubList);
231
232    return ret;
233}
234
235// ローカルブリッジの追加
236void AddLocalBridge(CEDAR *c, char *hubname, char *devicename, bool local, bool monitor, bool tapmode, char *tapaddr, bool fullbcast)
237{
238    UINT i;
239    HUB *h = NULL;
240    LOCALBRIDGE *br = NULL;
241    // 引数チェック
242    if (c == NULL || hubname == NULL || devicename == NULL)
243    {
244        return;
245    }
246
247    if (OS_IS_UNIX(GetOsInfo()->OsType) == false)
248    {
249        tapmode = false;
250    }
251
252    LockList(c->HubList);
253    {
254        LockList(c->LocalBridgeList);
255        {
256            bool exists = false;
257
258            // 全く同一のブリッジ設定が無いかどうか調べる
259            for (i = 0;i < LIST_NUM(c->LocalBridgeList);i++)
260            {
261                LOCALBRIDGE *br = LIST_DATA(c->LocalBridgeList, i);
262                if (StrCmpi(br->DeviceName, devicename) == 0)
263                {
264                    if (StrCmpi(br->HubName, hubname) == 0)
265                    {
266                        if (br->TapMode == tapmode)
267                        {
268                            exists = true;
269                        }
270                    }
271                }
272            }
273
274            if (exists == false)
275            {
276                // 設定を追加する
277                br = ZeroMalloc(sizeof(LOCALBRIDGE));
278                StrCpy(br->HubName, sizeof(br->HubName), hubname);
279                StrCpy(br->DeviceName, sizeof(br->DeviceName), devicename);
280                br->Bridge = NULL;
281                br->Local = local;
282                br->TapMode = tapmode;
283                br->FullBroadcast = fullbcast;
284                br->Monitor = monitor;
285                if (br->TapMode)
286                {
287                    if (tapaddr != NULL && IsZero(tapaddr, 6) == false)
288                    {
289                        Copy(br->TapMacAddress, tapaddr, 6);
290                    }
291                    else
292                    {
293                        GenMacAddress(br->TapMacAddress);
294                    }
295                }
296
297                Add(c->LocalBridgeList, br);
298
299                // HUB を検索する
300                for (i = 0;i < LIST_NUM(c->HubList);i++)
301                {
302                    HUB *hub = LIST_DATA(c->HubList, i);
303                    if (StrCmpi(hub->Name, br->HubName) == 0)
304                    {
305                        h = hub;
306                        AddRef(h->ref);
307                        break;
308                    }
309                }
310            }
311        }
312        UnlockList(c->LocalBridgeList);
313    }
314    UnlockList(c->HubList);
315
316    // 早速ブリッジを開始する
317    if (h != NULL && br != NULL && h->Type != HUB_TYPE_FARM_DYNAMIC)
318    {
319        Lock(h->lock_online);
320        {
321            if (h->Offline == false)
322            {
323                LockList(c->LocalBridgeList);
324                {
325                    if (IsInList(c->LocalBridgeList, br))
326                    {
327                        if (br->Bridge == NULL)
328                        {
329                            br->Bridge = BrNewBridge(h, br->DeviceName, NULL, br->Local, br->Monitor, br->TapMode, br->TapMacAddress, br->FullBroadcast);
330                        }
331                    }
332                }
333                UnlockList(c->LocalBridgeList);
334            }
335        }
336        Unlock(h->lock_online);
337    }
338
339    ReleaseHub(h);
340}
341
342// ローカルブリッジリストの初期化
343void InitLocalBridgeList(CEDAR *c)
344{
345    // 引数チェック
346    if (c == NULL)
347    {
348        return;
349    }
350
351    c->LocalBridgeList = NewList(NULL);
352}
353
354// ローカルブリッジリストの解放
355void FreeLocalBridgeList(CEDAR *c)
356{
357    UINT i;
358    // 引数チェック
359    if (c == NULL)
360    {
361        return;
362    }
363
364    for (i = 0;i < LIST_NUM(c->LocalBridgeList);i++)
365    {
366        LOCALBRIDGE *br = LIST_DATA(c->LocalBridgeList, i);
367        Free(br);
368    }
369
370    ReleaseList(c->LocalBridgeList);
371    c->LocalBridgeList = NULL;
372}
373
374// ブリッジ用スレッド
375void BrBridgeThread(THREAD *thread, void *param)
376{
377    BRIDGE *b;
378    CONNECTION *c;
379    SESSION *s;
380    HUB *h;
381    char name[MAX_SIZE];
382    // 引数チェック
383    if (thread == NULL || param == NULL)
384    {
385        return;
386    }
387
388    b = (BRIDGE *)param;
389
390    // コネクションの作成
391    c = NewServerConnection(b->Cedar, NULL, thread);
392    c->Protocol = CONNECTION_HUB_BRIDGE;
393
394    // セッションの作成
395    s = NewServerSession(b->Cedar, c, b->Hub, BRIDGE_USER_NAME, b->Policy);
396    HLog(b->Hub, "LH_START_BRIDGE", b->Name, s->Name);
397    StrCpy(name, sizeof(name), b->Name);
398    h = b->Hub;
399    AddRef(h->ref);
400    s->BridgeMode = true;
401    s->Bridge = b;
402    c->Session = s;
403    ReleaseConnection(c);
404
405    // ユーザー名
406    s->Username = CopyStr(BRIDGE_USER_NAME_PRINT);
407
408    b->Session = s;
409    AddRef(s->ref);
410
411    // 初期化完了を通知
412    NoticeThreadInit(thread);
413
414    // セッションのメイン関数
415    Debug("Bridge %s Start.\n", b->Name);
416    SessionMain(s);
417    Debug("Bridge %s Stop.\n", b->Name);
418
419    HLog(h, "LH_STOP_BRIDGE", name);
420
421    ReleaseHub(h);
422
423    ReleaseSession(s);
424}
425
426// ブリッジの解放
427void BrFreeBridge(BRIDGE *b)
428{
429    // 引数チェック
430    if (b == NULL)
431    {
432        return;
433    }
434
435    // セッション停止
436    StopSession(b->Session);
437    ReleaseSession(b->Session);
438    Free(b->Name);
439
440    Free(b);
441}
442
443// 新しいブリッジの作成
444BRIDGE *BrNewBridge(HUB *h, char *name, POLICY *p, bool local, bool monitor, bool tapmode, char *tapaddr, bool fullbcast)
445{
446    BRIDGE *b;
447    POLICY *policy;
448    THREAD *t;
449    // 引数チェック
450    if (h == NULL || name == NULL)
451    {
452        return NULL;
453    }
454
455    if (p == NULL)
456    {
457        policy = ClonePolicy(GetDefaultPolicy());
458    }
459    else
460    {
461        policy = ClonePolicy(p);
462    }
463
464    policy->CheckMac = true;
465
466#ifdef  UNIX_LINUX
467    policy->CheckMac = false;
468#endif  // UNIX_LINUX
469
470    policy->NoBroadcastLimiter = true;
471
472    b = ZeroMalloc(sizeof(BRIDGE));
473    b->Cedar = h->Cedar;
474    b->Hub = h;
475    b->Name = CopyStr(name);
476    b->Policy = policy;
477    b->Local = local;
478    b->Monitor = monitor;
479    b->TapMode = tapmode;
480    b->FullBroadcast = fullbcast;
481
482    if (b->TapMode)
483    {
484        if (tapaddr != NULL && IsZero(tapaddr, 6) == false)
485        {
486            Copy(b->TapMacAddress, tapaddr, 6);
487        }
488        else
489        {
490            GenMacAddress(b->TapMacAddress);
491        }
492    }
493
494    if (monitor)
495    {
496        // モニタリングモード
497        policy->MonitorPort = true;
498    }
499
500    if (b->FullBroadcast)
501    {
502        // ブロードキャストを制限しない
503        policy->NoBroadcastLimiter = true;
504    }
505
506    // スレッド作成
507    t = NewThread(BrBridgeThread, b);
508    WaitThreadInit(t);
509    ReleaseThread(t);
510
511    return b;
512}
513
Note: See TracBrowser for help on using the repository browser.