blob: c35ba21f0b629841e0c908d7d645ca915ececd2d [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2/** \file /secure/master/cidr.c
3* Funktionen zur Interpretation und Umrechnung von IP-Adressen in CIDR-Notation.
4* \author Zesstra
5* \date 05.02.2010
6* \version $Id$
7*/
8/* Changelog:
9*/
10
11private int IPv4_addr2int(string addr) {
12 int mask;
13
14 if (!stringp(addr) || !sizeof(addr))
15 return 0;
16 // irgendwelche Zeichen ausser 0-9, . und / drin?
17 if (sizeof(addr-"0123456789./"))
18 return 0;
19
20 string *parts = explode(addr, "/") - ({""});
21 // Netzmaske gegeben? -> Netzwerkadresse bestimmen
22 if (sizeof(parts) == 2) {
23 // a.b.c.d/x oder a.b.c.d/w.x.y.z
24 int res = IPv4_addr2int(parts[0]); // erstmal Wert von a.b.c.d...
25 if (strstr(parts[1], ".") > -1
26 && sizeof(explode(parts[1],".")) == 4)
27 // a.b.c.d/w.x.y.z -> Wert von w.x.y.z bestimmen
28 mask = IPv4_addr2int(parts[1]);
29 else {
30 mask = to_int(parts[1]);
31 // Wert von /x
32 mask = 0xffffffff - (to_int(pow(2, 32-mask))-1);
33 }
34 // verunden und Ende.
35 return res & mask;
36 }
37
38 parts = explode(parts[0], ".");
39 // Abgrekuerzte Adresse a la a.b.? Rest mit 0 ergaenzen.
40 switch(sizeof(parts - ({""})) ) {
41 case 1:
42 parts += ({"0","0","0"});
43 case 2:
44 parts += ({"0","0"});
45 case 3:
46 parts += ({"0"});
47 case 4:
48 break;
49 default:
50 return 0;
51 }
52
53 return( to_int(parts[0]) << 24)
54 + ( to_int(parts[1]) << 16)
55 + ( to_int(parts[2]) << 8 )
56 + to_int(parts[3]);
57}
58
59private int IPv4_net_size(string addr) {
60 if (!stringp(addr) || !sizeof(addr))
61 return 0;
62 // irgendwelche Zeichen ausser 0-9, . und / drin?
63 if (sizeof(addr-"0123456789./"))
64 return 0;
65
66 string *parts = explode(addr, "/") - ({""});
67 // Netzmaske gegeben? -> Netzwerkadresse bestimmen
68 if (sizeof(parts) == 2) {
69 // a.b.c.d/x oder a.b.c.d/w.x.y.z
70 if (strstr(parts[1], ".") > -1
71 && sizeof(explode(parts[1],".")) == 4)
72 // a.b.c.d/w.x.y.z
73 return 0xffffffff - (IPv4_addr2int(parts[1]) || 1) + 1;
74 else {
75 // Einfach 2^(32-mask) Adressen.
76 return to_int(pow(2, 32 - to_int(parts[1]) ) );
77 }
78 }
79
80 parts = explode(parts[0], ".");
81 switch(sizeof(parts - ({""})) ) {
82 case 1: // Class A
83 return 256*256*256;
84 case 2: // Class B
85 return 256*256;
86 case 3: // Class C
87 return 256;
88 case 4: // einzelne Adresse
89 return 1;
90 default: // ungueltige Adresse
91 return __INT_MAX__;
92 }
93
94 // hier sollte man gar nicht ankommen.
95 return __INT_MAX__;
96}
97
98string IPv4_int2addr(int ip) {
99 int *parts=allocate(4);
100 parts[0] = (ip & 0xff000000) >> 24;
101 parts[1] = (ip & 0x00ff0000) >> 16;
102 parts[2] = (ip & 0x0000ff00) >> 8;
103 parts[3] = (ip & 0x000000ff);
104 // int is signed. Anything > 127 would wrap around to -128 if we are on a
105 // machine with 32-bit wide ints.
106 if (parts[0] < 0)
107 parts[0] = 128 + (128-abs(parts[0]));
108
109 return implode(map(parts,#'to_string), ".");
110}
111