Portál AbcLinuxu, 12. května 2025 08:18

Dotaz: C rozdělení ip rozsahu inet_net_ntop s AF_INET6

2.11.2015 19:20 foldy
C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Přečteno: 573×
Odpovědět | Admin

Mám problém s rozdělením rozsahu ipv6, potřebuji rozdělit ip rozsahy dle potřeby, s ipv4 mi to funguje v pořádku pomocí :
inet_net_ntop(AF_INET,odkud,24,kam,INET_ADDRSTRLEN); a vše je ok výstup: A.B.C.0/24 apod.

Knihovna arpa/inet.h to ale neumí s AF_INET6, snažil jsem se to nějak implementovat s postgresql databáze s knihovnou inet_net_ntop.c, ale nechci kvůli tomu includovat celý postgresql a tu část svobodné knihovny se mi nepodařilo správně vyvázat a rozchodit.

Potřebuju rozsekat ipv6 dle potřeby např.:
A:B:C:D:E:F:G:H/128 -> A:B:C:D::/64 apod.
Znáte nějakou jinou knihovnu/metodu, (nejlépe aby byla malá a v rámci GPL) jak na to ?
Díky

Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

3.11.2015 06:03 Sten
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Odpovědět | | Sbalit | Link | Blokovat | Admin
Vždyť je to celkem triviální to napsat, ne? Vezmeš adresu, vymaskuješ ji daným počtem bitů a vypíšeš, u IPv6 hexadecimálně v blocích po 16 bitech.
3.11.2015 07:31 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
No to si úplně nemyslím, můžou tam být zkráceniny, vynechány kvůli tomu některé bloky a další pravidla pro parsování, které jsou v ipv6 zavedené. Ten alg. z postgre to i zkracuje. Měl by vyrobit i výstup : 2001:ABCD::/64 apod..
3.11.2015 08:13 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6

Zkracování je jen možnost, není to povinné. Např.

  ::
  0000:0000:0000:0000:0000:0000:0000:0000
  0:0:0:0:0:0:0:0
  0:00:000:0000:0000:000:000:0
  0::0

jsou všechno korektní zápisy stejné adresy.

3.11.2015 10:10 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
joo to vím, ale to zkracování se mi právě docela hodí, budu to vkládat do DB.
3.11.2015 10:15 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Pro potřeby ukládání do databáze by mi přišla vhodnější nativní reprezentace než textová.
3.11.2015 11:27 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Zkracena textova bude právě zabírat méně, proto potřebuji to zkrácení a ten alg. to bude zkracovat stále na stejné dělky, pokud ten rozsah bude stejný. Jde mi také o velikost.
3.11.2015 11:40 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Jste si opravdu jistý, že vám to statisticky bude vycházet kratší než 16 B? A pokud ano, bude to o tolik kratší, aby to vyvážilo složitější (a pomalejší) práci s těmi adresami?
3.11.2015 11:41 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
(Nebo 17 B, pokud se bavíme o adrese a délce prefixu.)
3.11.2015 11:54 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Právě pro sqlite se doporučuje to mít ve stringu.
3.11.2015 12:52 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Miluju zdůvodnění typu "se doporučuje"…
3.11.2015 15:44 Sten
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
„Doporučuje se“ to, jen pokud nad těmi adresami nebudou prováděny žádné operace, takže je není potřeba parsovat a formátovat. Když už jsou naparsované, tak je tam rovnou lze uložit jako čísla.
3.11.2015 19:46 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
půjde jen o porovnání strcmp, takže string je akorát a nemusí se to zpětně převádět, pro mě, zbytečná ntop navíc.
3.11.2015 20:24 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Tak teď už jsem z toho úplně jelen. Pokud to dostáváte ve formě textové reprezentace a hodláte s tím pracovat výhradně v ní, proč vás vůbec zajímá funkce inet_net_ntop(). Pokud to dostanete v nativní reprezentaci, tak porovnání na rovnost můžete provést i v ní (a bude jednodušší).
3.11.2015 21:12 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6

Ok, vysvětlím, jen jsem vždy překvapený, že se každý musí ujistit, že to potřebuji.

je to fastcgi webapp v C, kdy chodí requesty do login systemu,ip přijde z getenv jako string, v normálním případě se převede na in6_addr strukturu a pracuje se s ní, vyhodnocuje apod., existuje ale prvotní kontrola, v určitých případech, kdy přijde request rovnou se vezme string z getenv, porovná se string v DB a v případě shody se komunikace zahazuje (typicky obrana před utoky apod)

Proto je důležité zkrácení a převod do /64,56 atd... dle toho co chci zahodit. Čím menší string (i menší data v DB), tím rychleji se odmítne komunikace s něčím s čím nechci komunikovat. Nechci tam mít konverzi na in6_addr, porovnání s intem atd.. zbytečné instrukce navíc pro ten případ.

Ve fázy zpracování (což je jiný případ) v in6_addr potřebuji zkonstruovat ten rozsah a zkrátit ho, proto ten int_net_ntop...

3.11.2015 21:46 Sten
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Jak funguje porovnávání hodnoty z getenv s rozsahem /64 bez toho, abyste to musel parsovat?
3.11.2015 22:19 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Parsovat už to nemusím, stačí porovnat, pokud je rozumně zvolená část ip subnetu současně i názvem souboru a dat v ní, pak první sekvenci názvu použijete pro automatický výběr db a druhou část porovnáte binárním algoritmem, do první :: nebo /.
4.11.2015 05:52 Sten
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
No jestli podle IP adresy volíte databázi, pak už je úplně jedno, co dál to dělá
4.11.2015 11:30 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
ok
4.11.2015 01:46 Ivan
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Jses si jistej, ze to optimalizujes na spravnym miste? Opravdu je to tak, ze kratsi string => mensi data v DB => rychlejsi zpracovani? Pokud je tam nejaky index tak to bude vice-mene jedno. Dulezita je vyska indexu. A proc nepouzijes nejakou ldbm databazi?
4.11.2015 11:29 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Ten string může být pak i v texťáku, je to jedno, zatím to zkouším s sqlitem. LDBM db neznám.
4.11.2015 17:08 Ivan
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
dbm je primitivni key-value storage databaze. Poziva ji napriklad openldap jako svuj backend. Ten implementaci je vic - jedna z nich je napriklad sleepycat.
3.11.2015 15:40 Sten
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Zkrácenina je maximálně jedna a primitivní implementace to může buď nezkracovat či zkracovat podle zadané masky (např. /56 → posledních 72 bitů lze zkrátit). Problém je parsovat IPv6 adresy, vypsat je ve fungujícím tvaru je opravdu triviální.
pavlix avatar 4.11.2015 19:06 pavlix | skóre: 54 | blog: pavlix
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
No to si úplně nemyslím, můžou tam být zkráceniny,
Jaké zkráceniny? Maskuje se v binární podobě a to je prostě jenom sekvence 128 bitů, nic víc, nic míň.
Já už tu vlastně ani nejsem. Abclinuxu umřelo.
3.11.2015 08:10 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Odpovědět | | Sbalit | Link | Blokovat | Admin
Manuálová stránka výslovně uvádí
For both functions, af specifies the address family for the conversion; the only supported value is AF_INET.

Ale jak už bylo řečeno, napsat si vlastní implementaci je triviální: odmaskujete příslušný počet nejnižších bitů, převedete na textovou reprezentaci pomocí inet_ntop a na konec přidáte lomítko a délku prefixu. Třeba takhle:

const char *inet6_net_ntop(const struct in6_addr* addr, unsigned bits,
                           char* buff, unsigned len)
{
        struct in6_addr a6 = *addr;
        unsigned char* src = a6.s6_addr;
        const char* bp;
        char* p;
        unsigned i;

        if ((len < INET6_ADDRSTRLEN + 5) || (bits > 128))
                return NULL;

        for (i = (bits + 7) / 8; i < 16; i++)
                src[i] = 0;
        if (bits % 8)
                src[bits / 8] &= ~((1 << (8 - (bits % 8))) - 1);

        bp = inet_ntop(AF_INET6, src, buff, len - 4);
        if (!bp)
                return NULL;

        p = buff;
        while (*p)
                p++;
        *p++ = '/';
        snprintf(p, 4, "%u", bits);

        return buff;
}
3.11.2015 09:13 Radek Isa | skóre: 14
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Co takhle prevest masku i ipv6 na sitovou reprezentaci (v sitove reprezentaci nemuze byt ta ipv6 skracena) a pak to pomoci operace and vymaskovat a nasledne prevest na reprezentaci řetezcem.
3.11.2015 09:43 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Co takhle prevest masku i ipv6 na sitovou reprezentaci

Jak konkrétně se síťová reprezentace liší od toho, co je ve struct in6_addr?

3.11.2015 10:00 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Ale fuj...
--- addr.c.orig 2015-11-03 09:58:02.588426088 +0100
+++ addr.c      2015-11-03 09:57:35.660802261 +0100
@@ -11,13 +11,11 @@
        unsigned char* src = a6.s6_addr;
        const char* bp;
        char* p;
-       unsigned i;
 
        if ((len < INET6_ADDRSTRLEN + 5) || (bits > 128))
                return NULL;
 
-       for (i = (bits + 7) / 8; i < 16; i++)
-               src[i] = 0;
+       memset(src + (bits + 7) / 8, 0, 16 - (bits + 7) / 8);
        if (bits % 8)
                src[bits / 8] &= ~((1 << (8 - (bits % 8))) - 1);
 
10.11.2015 23:18 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Odpovědět | | Sbalit | Link | Blokovat | Admin
Tak jsem to našel, použil jsem funkční verzi z Bind 9.5.0.dfsg.P2, kdyby to někdo hledal, v pozdějších verzích už není. Je to s copyrightem ISC, ale dá se použít. Tam je int_net_ntop i pro AF_INET6 i s ořezáním.
10.11.2015 23:44 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Že jsem tak zvědavý: co je nefunkčního na té, kterou jsem vám sem před týdnem napsal?
11.11.2015 18:28 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Neobsahuje zkrácení a nevynechává to zbytečné nuly, které tamjsou nepotřebné, asi nejsem tak dobrý programátor abych to dal dohromady a dodělal do toho. Jinak to fungovalo ok. Cíl byl také dostat z toho nejkratší string a to ta implementace z bindu splňuje.Díky za pomoc.
11.11.2015 18:30 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Zkusil jste to aspoň? Vypadá to že ne…
13.11.2015 10:03 foldy
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Ano zkusil, měl jsem za to, že to zkrácení má udělat : inet_ntop(AF_INET6, src, buff, len - 4); , ale nezkrátilo mi to.
13.11.2015 10:37 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: C rozdělení ip rozsahu inet_net_ntop s AF_INET6
Pokud tvrdíte, že ta funkce vrací špatný výsledek, uveďte, prosím, konkrétní příklad, pro jakou adresu a jakou délku prefixu ten špatný výsledek dává.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.