~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/VBox/HostDrivers/VBoxTAP/macinfo.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  TAP-Win32 -- A kernel driver to provide virtual tap device functionality
 
3
 *               on Windows.  Originally derived from the CIPE-Win32
 
4
 *               project by Damion K. Wilson, with extensive modifications by
 
5
 *               James Yonan.
 
6
 *
 
7
 *  All source code which derives from the CIPE-Win32 project is
 
8
 *  Copyright (C) Damion K. Wilson, 2003, and is released under the
 
9
 *  GPL version 2 (see below).
 
10
 *
 
11
 *  All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC,
 
12
 *  and is released under the GPL version 2 (see below).
 
13
 *
 
14
 *  This program is free software; you can redistribute it and/or modify
 
15
 *  it under the terms of the GNU General Public License version 2
 
16
 *  as published by the Free Software Foundation.
 
17
 *
 
18
 *  This program is distributed in the hope that it will be useful,
 
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
 *  GNU General Public License for more details.
 
22
 *
 
23
 *  You should have received a copy of the GNU General Public License
 
24
 *  along with this program (see the file COPYING included with this
 
25
 *  distribution); if not, write to the Free Software Foundation, Inc.,
 
26
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
27
 */
 
28
 
 
29
#include "macinfo.h"
 
30
 
 
31
int
 
32
HexStringToDecimalInt (const int p_Character)
 
33
{
 
34
  int l_Value = 0;
 
35
 
 
36
  if (p_Character >= 'A' && p_Character <= 'F')
 
37
    l_Value = (p_Character - 'A') + 10;
 
38
  else if (p_Character >= 'a' && p_Character <= 'f')
 
39
    l_Value = (p_Character - 'a') + 10;
 
40
  else if (p_Character >= '0' && p_Character <= '9')
 
41
    l_Value = p_Character - '0';
 
42
 
 
43
  return l_Value;
 
44
}
 
45
 
 
46
BOOLEAN
 
47
ParseMAC (MACADDR dest, const char *src)
 
48
{
 
49
  int c;
 
50
  int mac_index = 0;
 
51
  BOOLEAN high_digit = FALSE;
 
52
  int delim_action = 1;
 
53
 
 
54
  MYASSERT (src);
 
55
  MYASSERT (dest);
 
56
 
 
57
  CLEAR_MAC (dest);
 
58
 
 
59
  while (c = *src++)
 
60
    {
 
61
      if (IsMacDelimiter (c))
 
62
        {
 
63
          mac_index += delim_action;
 
64
          high_digit = FALSE;
 
65
          delim_action = 1;
 
66
        }
 
67
      else if (IsHexDigit (c))
 
68
        {
 
69
          const int digit = HexStringToDecimalInt (c);
 
70
          if (mac_index < sizeof (MACADDR))
 
71
            {
 
72
              if (!high_digit)
 
73
                {
 
74
                  dest[mac_index] = (char)(digit);
 
75
                  high_digit = TRUE;
 
76
                  delim_action = 1;
 
77
                }
 
78
              else
 
79
                {
 
80
                  dest[mac_index] = (char)(dest[mac_index] * 16 + digit);
 
81
                  ++mac_index;
 
82
                  high_digit = FALSE;
 
83
                  delim_action = 0;
 
84
                }
 
85
            }
 
86
          else
 
87
            return FALSE;
 
88
        }
 
89
      else
 
90
        return FALSE;
 
91
    }
 
92
 
 
93
  return (mac_index + delim_action) >= sizeof (MACADDR);
 
94
}
 
95
 
 
96
/*
 
97
 * Generate a MAC using the GUID in the adapter name.
 
98
 *
 
99
 * The mac is constructed as 00:FF:xx:xx:xx:xx where
 
100
 * the Xs are taken from the first 32 bits of the GUID in the
 
101
 * adapter name.  This is similar to the Linux 2.4 tap MAC
 
102
 * generator, except linux uses 32 random bits for the Xs.
 
103
 *
 
104
 * In general, this solution is reasonable for most
 
105
 * applications except for very large bridged TAP networks,
 
106
 * where the probability of address collisions becomes more
 
107
 * than infintesimal.
 
108
 *
 
109
 * Using the well-known "birthday paradox", on a 1000 node
 
110
 * network the probability of collision would be
 
111
 * 0.000116292153.  On a 10,000 node network, the probability
 
112
 * of collision would be 0.01157288998621678766.
 
113
 */
 
114
 
 
115
VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name)
 
116
{
 
117
  unsigned const char *cp = adapter_name;
 
118
  unsigned char c;
 
119
  unsigned int i = 2;
 
120
  unsigned int byte = 0;
 
121
  int brace = 0;
 
122
  int state = 0;
 
123
 
 
124
  CLEAR_MAC (mac);
 
125
 
 
126
  mac[0] = 0x00;
 
127
  mac[1] = 0xFF;
 
128
 
 
129
  while (c = *cp++)
 
130
    {
 
131
      if (i >= sizeof (MACADDR))
 
132
        break;
 
133
      if (c == '{')
 
134
        brace = 1;
 
135
      if (IsHexDigit (c) && brace)
 
136
        {
 
137
          const unsigned int digit = HexStringToDecimalInt (c);
 
138
          if (state)
 
139
            {
 
140
              byte <<= 4;
 
141
              byte |= digit;
 
142
              mac[i++] = (unsigned char) byte;
 
143
              state = 0;
 
144
            }
 
145
          else
 
146
            {
 
147
              byte = digit;
 
148
              state = 1;
 
149
            }
 
150
        }
 
151
    }
 
152
}
 
153
 
 
154
VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta)
 
155
{
 
156
  COPY_MAC (dest, src);
 
157
  dest[2] += (UCHAR) delta;
 
158
}
 
159