Nesen mÄs ieguvÄm LIR statusu un \/29 IPv6 bloku. Un drÄ«z radÄs nepiecieÅ”amÄ«ba uzskaitÄ«t pieŔķirtÄs apakÅ”tÄ«klus. Un tÄ kÄ mÅ«su rÄÄ·inÄÅ”anas sistÄma ir uzrakstÄ«ta PHP, nÄcÄs nedaudz iepazÄ«ties ar Å”o jautÄjumu un saprast, ka Ŕī valoda nav visdraudzÄ«gÄkÄ IPv6 apstrÄdei. ZemÄk ā mÅ«su risinÄjums radÄ«tajÄm problÄmÄm ar adresÄm un diapazoniem. VarbÅ«t ne visai elegants, bet uzdevumi tiek izpildÄ«ti.

Nedaudz teorijas
Atruna. Ja esat pazÄ«stams ar to, kas ir IPv6 un kÄ tas darbojas, Ŕī daļa var jums likties garlaicÄ«ga. VarbÅ«t arÄ« nÄ.
CilvÄkus, kuri pirmo reizi redz IPv6 anotÄciju, tÄ var pat nobiedÄt. PÄc elegantiem 64.233.177.101 mÄs pÄkÅ”Åi saskaramies ar 2607:f8b0:4002:c08::8b un varam apjukt. Abas ir cilvÄkiem saprotamas 32 un 128 bitu attÄlojumos attiecÄ«gi. Ikviens IP datu pakets satur galveni ar stingri standartizÄtu katra bita mÄrÄ·i. NeiegrimuÅ”i vÄl dziļÄk galvenes struktÅ«rÄ, no Å”ejienes mums jÄsecina: IP adresu un diapazonu operÄcijÄm galvenokÄrt ir Ärti izmantot binÄro matemÄtiku un bitu operÄcijas. VisÄrtÄk ir saglabÄt tos datubÄzÄ kÄ BINARY(4) IPv4 un BINARY(16) IPv6.
VÄl viens svarÄ«gs aspekts, ko vÄrts pieminÄt, ir tÄ«kla maskas un CIDR notÄcija. CIDR ir akronÄ«ms no Classless Inter-Domain Routing (). Å Ä« koncepcija aizstÄja klasisko pieeju attiecÄ«bÄ uz to, kÄda daļa IP adreses ir tÄ«kla prefikss, un kÄda daļa ir adreses tÄ«kla saskarnÄ. PraksÄ pirmajiem n bitiem, kas atbilst prefiksam, bÅ«s vÄrtÄ«bas 1, bet pÄrÄjiem ā 0.
CilvÄkiem saprotamÄ veidÄ to raksta kÄ ip.add.re.ss\/cidr. PiemÄram, 64.233.177.0/24 norÄda, ka pirmie 24 bitu pieder prefiksam. PÄdÄjie 8 biti, kas ir pÄdÄjais skaitlis cilvÄkam saprotamÄ ierakstÄ, attiecas uz adresi apakÅ”tÄ«klÄ. VÄl pÄris vingrinÄjumu. 64.233.177.101/32 un 2607:f8b0:4002:c08::8b\/128 ā viens konkrÄts adrese. 2607:f8b0:4002:c08::\/64 ā pirmie 64 biti (pirmÄs 4 grupas) ir prefikss, pÄrÄjie 64 biti ir lokÄlÄ daļa. Starp citu, ja kÄdu mulsina "::" ierakstÄ, divreiz kolons aizstÄj neierobežotu skaitu sekciju, kurÄs ir 0. Tas var parÄdÄ«ties anotÄcijÄ tikai 1 reizi. CitÄdi sakot, 2607:f8b0:4002:c08::8b = 2607:f8b0:4002:c08:0:0:0:8b.
Kas no tÄ visa mums jÄÅem? PirmkÄrt, pirmo un pÄdÄjo apakÅ”netes adresi var iegÅ«t, izmantojot binÄros AND un OR, zinot masku binÄrÄ formÄtÄ. OtrkÄrt, nÄkamo apakÅ”neti izmÄra (t.i., ar CIDR) n var aprÄÄ·inÄt, pievienojot 1 n-tÄ pozÄ«cijÄ binÄrajÄ attÄlÄ. Zem binÄrÄ es domÄju rezultÄtu, izmantojot funkcijas pack() un inet_pton() un turpmÄko bitu operatoru izmantoÅ”anu, base_convert() Bezklasiskai iepriekÅ”Äja klasiskÄ segregÄcija adresÄÅ”ana. TajÄs senajÄs dienÄs neviens negaidÄ«ja, ka bÅ«s tik daudz apakÅ”netu, tÄs pieŔķīra pa kreisi un pa labi lielos blokos: klase A ā prefikss bija pirmie 8 biti (t.i., pirmais skaitlis), ar vadoÅ”o bitu 0; klase B ā pirmie 16 (pirmie divi skaitļi), vadoÅ”ie biti 10; klase C ā pirmie 24 biti, vadoÅ”ie biti 110. Å ie vadoÅ”ie biti noteica diapazonus, kuros tika pieŔķirta adresi attiecÄ«gajÄ klasÄ:.
VÄsturiskÄ informÄcijaklase A, 0.0.0.0 ā 127.255.255.255 ā klase B, 192.0.0.0 ā 223.255.255.255 ā klase C. Laika gaitÄ, kÄ internets izplatÄ«jÄs pa planÄtu, regulatoriem kļuva skaidrs, ka viÅi kļūdÄ«jÄs, un 90-to gadu sÄkumÄ tika izstrÄdÄta bezklasiskÄ koncepcija, kas ļÄva neierobežoties ar vadoÅ”ajiem bitiem. Mazliet vairÄk detaļu var uzzinÄt, piemÄram, 128.0.0.0 ā 191.255.255.255 lielajÄ un viszinÄ«gajÄ .
PraksÄ Ä«stenosim trÄ«s visdrÄ«zÄkÄs, kÄ man Ŕķita, uzdevumus:
pirmÄs un pÄdÄjÄs adreses iegūŔana diapazonÄ;
- nÄkamÄ diapazona iegūŔana noteikta izmÄra (CIDR);
- pÄrbaude par adreses piederÄ«bu diapazonam.
- IevieÅ”ana bÅ«s IPv6, taÄu, ja nepiecieÅ”ams, loÄ£iku var viegli pielÄgot. Dažas idejas es ieguvu
, bet Ä«stenoju nedaudz citÄdÄk. ArÄ« piemÄros nav ievades kļūdu pÄrbaudes. Labi, sÄksim. KÄ jau minÄju, pirmo un pÄdÄjo adresi diapazonÄ var noteikt, izmantojot bitu operÄcijas, zinot diapazona sÄkumu un binÄro apakÅ”netes masku. AttiecÄ«gi pirmkÄrt mums jÄpÄrveido CIDR binÄrÄ maske. TÄpÄc mÄs apkoposim tÄs hex attÄlojumu un iepakosim binÄrÄ.
function cidrToMask ($cidr) { $mask = str_repeat('f', ceil($cidr / 4)); $mask .= dechex(4 * ($cidr % 4)); $mask = str_pad($mask, 32, '0'); return pack('H*', $mask); }
pack(āH*ā, $mask)Izsaukt iepako hex attÄlojumu tieÅ”i tÄdÄ paÅ”Ä veidÄ kÄ . Ar to atŔķirÄ«bu, ka izsaukuma gadÄ«jumÄ inet_pton(). VienÄ«gÄ atŔķirÄ«ba ir tÄ, ka izsaukuma laikÄ pack() VisÄm 0 jÄbÅ«t savÄs vietÄs, un rakstÄ nedrÄ«kst bÅ«t kolonnas, atŔķirÄ«bÄ no cilvÄkam saprotama ieraksta.
NÄkamais solis ir noteikt diapazona sÄkumu un beigas. Un Å”eit var rasties nianses. Bitu operÄcijas ir ierobežotas procesora bitu skaitam. AttiecÄ«gi, manÄ 32 bitu CubieTruck, ko es dažreiz izmantoju dažÄdiem testÄÅ”anas eksperimenti, nav iespÄjams apstrÄdÄt visus 128 bitus adreses vienÄ operÄcijÄ. TomÄr nekas neliedz mums to sadalÄ«t grupÄs pa 32 bitiem (uz visiem gadÄ«jumiem, kas zina, uz kÄdiem procesoriem palaižam).
function getRangeBoundary ($ip, $cidr, $which, $ipIsBin = false, $returnBin = false) {
$mask = cidrToMask($cidr);
if (!$ipIsBin) {
$ip = inet_pton($ip);
}
$ipParts = str_split($ip, 4);
$maskParts = str_split($mask, 4);
$rangeParts = [];
for ($i = 0; $i < count($ipParts); $i++) {
if ($which == 'start') {
/* ŠŠ¾Š±ŠøŃŠ¾Š²ŃŠ¹ & Š°Š“ŃŠµŃа Šø Š¼Š°ŃŠŗŠø оŃŃŠ°Š²ŠøŃ ŃŠ¾Š»Ńко биŃŃ ŠæŃŠµŃŠøŠŗŃŠ°. */
$rangeParts[$i] = $ipParts[$i] & $maskParts[$i];
} else {
/* ŠŠ¾Š±ŠøŃŠ¾Š²ŃŠ¹ | Ń Š¾Š±ŃŠ°Ńной Š¼Š°Ńкой (~) оŃŃŠ°Š²ŠøŃ биŃŃ ŠæŃŠµŃŠøŠŗŃŠ° Šø ŃŃŃŠ°Š½Š¾Š²ŠøŃ Š²ŃŠµ биŃŃ Š»Š¾ŠŗŠ°Š»ŃŠ½Š¾Š¹ ŃŠ°ŃŃŠø в 1. */
$rangeParts[$i] = $ipParts[$i] | ~$maskParts[$i];
}
}
$rangeBoundary = implode($rangeParts);
if ($returnBin) {
return $rangeBoundary;
} else {
return inet_ntop($rangeBoundary);
}
}NÄkotnÄ mÄs paredzÄsim iespÄju pÄrsÅ«tÄ«t IP un saÅemt rezultÄtu gan binÄrÄ, gan cilvÄkam saprotamÄ formÄ. Parametrs $which Å”eit nosaka, vai mÄs vÄlamies saÅemt sÄkumu vai beigas diapazonam (vÄrtÄ«bas āstartā vai āendā attiecÄ«gi).
NÄkamÄ uzdevuma (turklÄt vispraktiskÄkÄ mÅ«su uzÅÄmumam) ir nÄkamÄ diapazona noteikÅ”ana. Å im uzdevumam nekas labÄks nenÄca prÄtÄ, kÄ sadalÄ«t adresi binÄrajÄ virknei un pievienot 1 vajadzÄ«gajÄ pozÄ«cijÄ, pÄc tam saliekot visu atpakaļ. Lai neparÄdÄ«tos artefakti, es nolÄmu, ka, iznÄkot un saliekot, adrese jÄizsara pa baitiem.
function getNextBlock ($ipStart, $cidr, $ipIsBin = false, $returnBin = false) {
if (!$ipIsBin) {
$ipStart = inet_pton($ipStart);
}
$ipParts = str_split($ipStart, 1);
$ipBin = '';
foreach ($ipParts as $ipPart) {
$ipBin .= str_pad(base_convert(unpack('H*', $ipPart)[1], 16, 2), 8, '0', STR_PAD_LEFT);
}
/* ŠŠ¾Š±Š°Š²Š»Ńем 1 в Š½Ńжном ŃŠ°Š·ŃŃŠ“е Š“Š²Š¾ŠøŃŠ½Š¾Š³Š¾ ŠæŃŠµŠ“ŃŃŠ°Š²Š»ŠµŠ½ŠøŃ ŃŃŃŠ¾ŠŗŠø "влоб" :) */
$i = $cidr - 1;
while ($i >= 0) {
if ($ipBin[$i] == '0') {
$ipBin[$i] = '1';
break;
} else {
$ipBin[$i] = '0';
}
$i--;
}
$ipBinParts = str_split($ipBin, 8);
foreach ($ipBinParts as $key => $ipBinPart) {
$ipParts[$key] = pack('H*', str_pad(base_convert($ipBinPart, 2, 16), 2, '0', STR_PAD_LEFT));
}
$nextIp = implode($ipParts);
if ($returnBin) {
return $nextIp;
} else {
return inet_ntop($nextIp);
}
}RezultÄtÄ mÄs iegÅ«sim nÄkamÄ diapazona prefiksu, kura izmÄrs ir norÄdÄ«ts $cidr.Ar Å”o funkciju mÄs pieŔķiram adreses blokiem mÅ«su klientiem.
Visbeidzot, jÄnodroÅ”ina, vai adrese pieder diapazonam. PiemÄram, mÄs pieŔķīrÄm vienu bloku /48 klientiem, lai pieŔķirtu blokiem /64, un mums jÄnodroÅ”ina, ka pieŔķirÅ”anas procesÄ neiznÄkam Ärpus pieŔķirtÄ bloka (praktiski tas notiks reti, bet iespÄja tomÄr ir). Å eit viss ir vienkÄrÅ”i. IegÅ«stam diapazona sÄkumu un beigas binÄrÄ veidÄ un pÄrbaudÄm, vai adrese atrodas tai piemÄrotajÄs robežÄs.
function ipInRange ($ip, $rangeStart, $cidr) {
$start = getRangeBoundary($rangeStart, $cidr, 'start',false, true);
$end = getRangeBoundary($rangeStart, $cidr, 'end',false, true);
$ipBin = inet_pton($ip);
return ($ipBin >= $start && $ipBin <= $end);
}Ceru, ka tas bija noderÄ«gi. KÄdas vÄl funkcijas darbam ar adresÄm, jÅ«suprÄt, varÄtu bÅ«t noderÄ«gas? JebkÄdi papildinÄjumi, komentÄri un koda pÄrskatīŔana tiek laipni gaidÄ«ti komentÄros.
Ja, ja esat mÅ«su klients vai tikai domÄjat par kļūŔanu par to, Ŕī raksta izdoÅ”anas gadÄ«jumÄ piedÄvÄjam saÅemt /64 bloku pilnÄ«gi bez maksas visÄm VPS vai dedikÄtÄ servera pakalpojumiem datu centrÄ Equinix Tier IV NÄ«derlandÄ, iesniedzot pieprasÄ«jumu pÄrdoÅ”anas nodaļÄ, norÄdot saiti uz Å”o rakstu biļetÄ. PiedÄvÄjums ir spÄkÄ lÄ«dz 2020. gada martam.
Mazliet reklÄmas š
Paldies, ka paliekat ar mums. Vai jums patÄ«k mÅ«su raksti? VÄlaties redzÄt vairÄk interesantus materiÄlus? Atbalstiet mÅ«s, veicot pasÅ«tÄ«jumu vai ieteicot draugiem, , unikÄls ieejas lÄ«meÅa serveru analogs, kuru mÄs izstrÄdÄjÄm jums: (pieejami varianti ar RAID1 un RAID10, lÄ«dz 24 kodoliem un lÄ«dz 40GB DDR4).
Dell R730xd divas reizes lÄtÄk datu centrÄ Equinix Tier IV AmsterdamÄ? Tikai pie mums NÄ«derlandÄ! Dell R420 ā 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB ā no $99! Lasiet par to
Avots: habr.com
