Thread: [IPv6 IRC-DEV] IP en formato base 64 en el IRCU de Undernet
Brought to you by:
zolty
|
From: <zo...@te...> - 2003-02-01 08:35:40
|
Como todos sabemos, en el comando NICK de servidor en protocolo P10 se
incluye la IP en formato base64, bien, hay un problema que es lo
siguiente y habr=EDa que pensar en como resolverlo ya que de todas las
implementaciones existentes de IPv6 no hay ninguna en el ircu de
undernet o en cualquiera de sus variantes como el ircd universal de
Carlo Wood.
La IP en formato base64 es un valor de 6 caracteres si se trata de una
ip IPv4 (32 bits), pero para IPv6 (128 bits) hace falta 22 caracteres
para garantizar la reversibilidad. Esto es muy necesario para las IPS
virtuales que se calculan a partir de la ip num=E9rica, clones a la IP,
glines a la IP, respuesta del USERIP, etc.. (OJO no es lo mismo el
hostname que la IP).
Se podr=EDa hacer que un nodo mande 22 caracteres si el usuario est=E1 =
por
una conexi=F3n de IPv6 y 6 en el resto. Y un nodo, aunque sea solo IPv4,
ha de poderse parsear y guardar.
Actualmente, el ircd manda con lo siguiente...=20
inttobase64(ip_base64, ntohl(sptr->ip.s_addr), 6)
El nthol es para pasar a formato base2, o sea si mi ip es 80.59.255.83,
seria 1010011111111111110111010000 y el inttobase64 es para pasar a
base64 para hacerlo mas corto, en solo 6 caracteres en vez de 32.
Y cuando recibe, hace lo siguiente=20
sptr->ip.s_addr =3D htonl(base64toint(parv[parc - 3]));
El parv[parc - 3] se refiere a capturar el 3 par=E1metro a partir de la
derecha, que en P10 es la ip en formato base64.
Hab=E9is visto que la info esta en sptr->ip, siendo sptr un struct =
Client,
ahora mismo lo tengo en...
#ifdef INET6
struct in6_addr ip;
#else
struct in_addr ip;
#endif
Para resolver el problema del IP-Base64, la soluci=F3n que meti no es la
m=E1s adecuada, porque un nodo IPv4 ha de poder almacenar IPv6 de =
usuarios
remotos e viceversa. La mas adecuada seria lo siguiente...
Definir un nuevo struct, llamado "irc_inaddr" (se usa en el hybrid de
EFNet) para sustituir a struct "in_addr" y que estar=EDa definido de la
siguiente forma:
struct irc_inaddr =20
{
union
{
struct in_addr sin; =20
#ifdef INET6
struct in6_addr sin6;=20
#else
unsigned long ip6;
=F3
char *ip6; =20
#endif
} sins;
};
El "if def" esta pensado para que los nodos que no compilan con INET6,
que habr=E1 nodos con sistema operativo tan viejo que no tendr=E1 ni
librer=EDas de IPv6 como el sunos de gaia, puedan tener algo para
almacenar el valor. Dudo en un "unsigned long" o un "char *". =BFCual
seria la mejor soluci=F3n?
=BFComentarios? =BFOpiniones?
Un saludo
zoltan
=20
|
|
From: <zo...@te...> - 2003-02-01 08:43:54
|
> struct in_addr sin; =20 > #ifdef INET6 > struct in6_addr sin6;=20 > #else > unsigned long ip6; > =F3 > char *ip6; =20 Quiero decir unsigned long ip6[0]; unsigned long ip6[1]; unsigned long ip6[2]; unsigned long ip6[3]; Porque un int o un long en una maquina de 32 bits, es de 32 bits y como la ipv6 tiene 128.... :) |
|
From: Ruben C. <ni...@te...> - 2003-02-01 10:27:49
|
Hola, > El "if def" esta pensado para que los nodos que no compilan con INET6, > que habrá nodos con sistema operativo tan viejo que no tendrá ni > librerías de IPv6 como el sunos de gaia, puedan tener algo para > almacenar el valor. Dudo en un "unsigned long" o un "char *". ¿Cual > seria la mejor solución? Como luego la manipulacion de los hosts se hace a base de examinar la cadena (todo el tema de match.c, por ejemplo), para mi que se deja un char * y asi ya luego no hay que hacer conversiones. Saludos, NiKoLaS |
|
From: <zo...@te...> - 2003-02-01 11:07:56
|
> > Como luego la manipulacion de los hosts se hace a base de > examinar la cadena (todo el tema de match.c, por ejemplo), > para mi que se deja un char * y asi ya luego no hay que > hacer conversiones. > Cuando se tiene que imprimir en formato humano una ip se hace un "inetntoa(sptr->ip);" Un saludo zoltan |
|
From: Ruben C. <ru...@ar...> - 2003-02-01 11:12:29
|
Toni Garc=EDa wrote: >> Como luego la manipulacion de los hosts se hace a base de=20 >>examinar la cadena (todo el tema de match.c, por ejemplo), >>para mi que se deja un char * y asi ya luego no hay que >>hacer conversiones. >> >=20 >=20 > Cuando se tiene que imprimir en formato humano una ip se hace un > "inetntoa(sptr->ip);" Hablo de manipularla, no de imprimirla :P Saludos, NiKoLaS |
|
From: Daniel <fre...@un...> - 2003-02-03 09:55:20
|
El s=E1b, 01-02-2003 a las 09:35, Toni Garc=EDa escribi=F3:
> El "if def" esta pensado para que los nodos que no compilan con INET6,
> que habr=E1 nodos con sistema operativo tan viejo que no tendr=E1 ni
> librer=EDas de IPv6 como el sunos de gaia, puedan tener algo para
> almacenar el valor. Dudo en un "unsigned long" o un "char *". =BFCual
> seria la mejor soluci=F3n?
>=20
Pues habria que crear un tipo de datos nuevo que almacene los 128 bits,
por ejemplo, haciendo una union como hacen en las propias librerias de
IPv6, el problema esta en que no todos los compiladores de C usan el
mismo rango para los int, ya que algunos usan 32 bits, y otros usan 16
bits.
La creacion de un entero de 128 bits se podria hacer bien con un array
de enteros que posteriormente serian usados como un tipo de 128 mediante
casts (para no complicarse la existencia) o haciendo como hacen las
propias librerias IPv6 (para hacerlo mas correcto):
(Sacado de las propias librerias de IPv6)
struct in6_addr {
union {
u_int8_t __u6_addr8[16];
u_int16_t __u6_addr16[8];
u_int32_t __u6_addr32[4];
} __u6_addr; /* 128-bit IP6 address */
};
Por cierto, creo que en el configure se detectan los tama=F1os de los
tipos de datos del compilador, hay que verlo.
S2
--=20
Daniel Fern=E1ndez <fre...@un...>
|
|
From: <zo...@te...> - 2003-02-05 12:30:34
|
>=20
> struct in6_addr {
> union {
> u_int8_t __u6_addr8[16];
> u_int16_t __u6_addr16[8];
> u_int32_t __u6_addr32[4];
> } __u6_addr; /* 128-bit IP6 address */
> };
>=20
Al final har=E9 lo siguiente...
En la estructura del Client, hay un campo para almacenar la ip de los
usuarios locales y remotos:
struct in_addr ip;
Y lo cambiar=E9 a...
struct irc_inaddr ip;
Cuya estructura ser=E1 lo siguiente:
Struct irc_inaddr
{
union
{
struct in_addr sin; =20
#ifdef INET6
struct in6_addr sin6;=20
#else
u_int32_t irc6_addr[4]; /* 4 partes de 32 bits cada una =3D> 128 =
bits
:) */
#endif
} sins;
};
De esta forma, los nodos IPv4 (que muchas m=E1quinas no tienen ni las
librerias IPv6) puedan almacenar la ip en formato binario que reciba de
los usuarios remotos partiendo de la ip en formato base64 del comando
NICK de servidor.
Todos los nodos, tengan IPv6 activado o no, han de mandar 6 caracteres
si son ip's de IPv4 o ip's mapeadas IPv6-to-IPv4 (ejemplo
::ffff:80.59.255.83, que el ircd la trunca y muestra 80.59.255.83). Y 24
(6+6+6+6, 6 por cada 32 bits) si son ip's de IPv6.
He encontrado un parche para el ircu de undernet que lo hacian de esta
forma, de esta manera el comando /USERIP funcionar=E1 correctamente, asi
como las ip's virtuales y otros comandos que hagan uso de la ip en
formato num=E9rico (hexadecimal).
Este fin de semanaa los pondr=E9 en el CVS. Tambien meter=E9 parches =
para la
resoluci=F3n DNS, que meter=E9 ya de entrada el dominio "ip6.arpa" para =
las
inversas ya que me han delegado una.
Un saludo
zoltan
|