Ejemplo n.º 1
0
/** Encode an IP address in the base64 used by numnicks.
 * For IPv4 addresses (including IPv4-mapped and IPv4-compatible IPv6
 * addresses), the 32-bit host address is encoded directly as six
 * characters.
 *
 * For IPv6 addresses, each 16-bit address segment is encoded as three
 * characters, but the longest run of zero segments is encoded using an
 * underscore.
 * @param[out] buf Output buffer to write to.
 * @param[in] addr IP address to encode.
 * @param[in] count Number of bytes writable to \a buf.
 * @param[in] v6_ok If non-zero, peer understands base-64 encoded IPv6 addresses.
 */
const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count, int v6_ok)
{
    if (irc_in_addr_is_ipv4(addr)) {
        assert(count >= 6);
        inttobase64(buf, (ntohs(addr->in6_16[6]) << 16) | ntohs(addr->in6_16[7]), 6);
    } else if (!v6_ok) {
        assert(count >= 6);
        if (addr->in6_16[0] == htons(0x2002))
            inttobase64(buf, (ntohs(addr->in6_16[1]) << 16) | ntohs(addr->in6_16[2]), 6);
        else if ((addr->in6_16[0] == htons(0x2001)) && (addr->in6_16[1] == 0))
            inttobase64(buf, (ntohs(addr->in6_16[6] ^ 0xFFFF) << 16) | ntohs(addr->in6_16[7] ^ 0xFFFF), 6);
        else
            strcpy(buf, "AAAAAA");
    } else {
        unsigned int max_start, max_zeros, curr_zeros, zero, ii;
        char *output = buf;

        assert(count >= 25);
        /* Can start by printing out the leading non-zero parts. */
        for (ii = 0; (addr->in6_16[ii]) && (ii < 8); ++ii) {
            inttobase64(output, ntohs(addr->in6_16[ii]), 3);
            output += 3;
        }
        /* Find the longest run of zeros. */
        for (max_start = zero = ii, max_zeros = curr_zeros = 0; ii < 8; ++ii) {
            if (!addr->in6_16[ii])
                curr_zeros++;
            else if (curr_zeros > max_zeros) {
                max_start = ii - curr_zeros;
                max_zeros = curr_zeros;
                curr_zeros = 0;
            }
        }
        if (curr_zeros > max_zeros) {
            max_start = ii - curr_zeros;
            max_zeros = curr_zeros;
            curr_zeros = 0;
        }
        /* Print the rest of the address */
        for (ii = zero; ii < 8; ) {
            if ((ii == max_start) && max_zeros) {
                *output++ = '_';
                ii += max_zeros;
            } else {
                inttobase64(output, ntohs(addr->in6_16[ii]), 3);
                output += 3;
                ii++;
            }
        }
        *output = '\0';
    }
    return buf;
}
Ejemplo n.º 2
0
/** Set a server's numeric nick.
 * See @ref numnicks for more details.
 * @param[in] c %Server that is being assigned a numnick.
 * @param[in] numeric Numnick value for server.
 */
void SetYXXServerName(struct Client* c, unsigned int numeric)
{
    assert(0 != c);
    assert(numeric < NN_MAX_SERVER);

    inttobase64(cli_yxx(c), numeric, 2);
    if (numeric >= lastNNServer)
        lastNNServer = numeric + 1;
    server_list[numeric] = c;
}
Ejemplo n.º 3
0
void asuka_cmd_connect(void)
{
    if (!BadPtr(Numeric)) {
        inttobase64(p10id, atoi(Numeric), 2);
        me_server =
            do_server(NULL, ServerName, (char *) "0", ServerDesc, p10id);
        asuka_cmd_pass(RemotePassword);
        asuka_cmd_server(ServerName, 1, ServerDesc);
    } else {
        alog(LOG_NORMAL, "Numeric is required for P10 ircds");
        exit(1);
    }
}
Ejemplo n.º 4
0
/** Register numeric of new (local) client.
 * See @ref numnicks for more details.
 * Assign a numnick and add it to our client_list.
 * @param[in] cptr %User being registered.
 */
int SetLocalNumNick(struct Client *cptr)
{
    static unsigned int last_nn     = 0;
    struct Client**     client_list = cli_serv(&me)->client_list;
    unsigned int        mask        = cli_serv(&me)->nn_mask;
    unsigned int        count       = 0;

    assert(cli_user(cptr)->server == &me);

    while (client_list[last_nn & mask]) {
        if (++count == NN_MAX_CLIENT) {
            assert(count < NN_MAX_CLIENT);
            return 0;
        }
        if (++last_nn == NN_MAX_CLIENT)
            last_nn = 0;
    }
    client_list[last_nn & mask] = cptr;  /* Reserve the numeric ! */

    inttobase64(cli_yxx(cptr), last_nn, 3);
    if (++last_nn == NN_MAX_CLIENT)
        last_nn = 0;
    return 1;
}
Ejemplo n.º 5
0
/** Set a server's capacity.
 * @param[in] c %Server whose capacity is being set.
 * @param[in] capacity Maximum number of clients the server supports.
 */
void SetYXXCapacity(struct Client* c, unsigned int capacity)
{
    unsigned int max_clients = 16;
    /*
     * Calculate mask to be used for the maximum number of clients
     */
    while (max_clients < capacity)
        max_clients <<= 1;
    /*
     * Sanity checks
     */
    if (max_clients > NN_MAX_CLIENT) {
        fprintf(stderr, "MAXCLIENTS (or MAXCONNECTIONS) is (at least) %d "
                "too large ! Please decrease this value.\n",
                max_clients - NN_MAX_CLIENT);
        exit(-1);
    }
    --max_clients;
    inttobase64(cli_serv(c)->nn_capacity, max_clients, 3);
    cli_serv(c)->nn_mask = max_clients;       /* Our Numeric Nick mask */
    cli_serv(c)->client_list = (struct Client**) MyCalloc(max_clients + 1,
                               sizeof(struct Client*));
    server_list[base64toint(cli_yxx(c))] = c;
}
Ejemplo n.º 6
0
bool CProtocol::Initialize ( const CSocket& socket, const CConfig& config )
{
    m_socket = socket;
    m_config = config;

    // Inicializamos la autenticación
    CString szHost;
    if ( ! m_config.GetValue ( szHost, "bots", "host" ) )
        return false;
    CString szNumeric;
    if ( ! m_config.GetValue ( szNumeric, "bots", "numeric" ) )
        return false;
    CString szPass;
    if ( ! m_config.GetValue ( szPass, "server", "password" ) )
        return false;
    CString szDesc;
    if ( ! m_config.GetValue ( szDesc, "bots", "description" ) )
        return false;
    CString szFlags;
    if ( ! m_config.GetValue ( szFlags, "bots", "flags" ) )
        return false;
    if ( ! m_config.GetValue ( m_szHiddenAddress, "bots", "hiddenAddress" ) )
        return false;
    if ( ! m_config.GetValue ( m_szHiddenDesc, "bots", "hiddenDesc" ) )
        return false;

    // Generamos el numérico
    char szYXX [ 4 ];
    memset ( szYXX, 0, sizeof ( szYXX ) );
    unsigned long ulNumeric = atol ( szNumeric );
    if ( ulNumeric > 4095 )
        inttobase64 ( szYXX, ulNumeric, 2 );
    else
        inttobase64 ( szYXX, ulNumeric, 1 );

    // Limpiamos los flags
    if ( *szFlags == '+' )
        szFlags = szFlags.substr ( 1 );

    // Creamos nuestra estructura de servidor
    m_me.Create ( 0, szYXX, szHost, szDesc, szFlags );

    // Negociamos la conexión
    unsigned long ulMaxusers;
    if ( ulNumeric > 63 )
        ulMaxusers = 262143;
    else
        ulMaxusers = 4095;

    Send ( CMessagePASS ( szPass ) );
    Send ( CMessageSERVER ( szHost, 1, time ( 0 ), "J10", szYXX, ulMaxusers, szFlags, szDesc ) );

    // Enviamos la versión de base de datos
    Send ( CMessageDB ( "*", 0, 0, 0, "", "", 2 ), &m_me );

    // Solicitamos las tablas
    for ( unsigned char ucTable = 'a'; ucTable <= 'z'; ++ucTable )
        Send ( CMessageDB ( "*", 'J', 0, ucTable, "", "", 0 ), &m_me );
    for ( unsigned char ucTable = 'A'; ucTable <= 'Z'; ++ucTable )
        Send ( CMessageDB ( "*", 'J', 0, ucTable, "", "", 0 ), &m_me );

    // Registramos eventos
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageEND_OF_BURST(), PROTOCOL_CALLBACK ( &CProtocol::evtEndOfBurst, this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessagePING(),   PROTOCOL_CALLBACK ( &CProtocol::evtPing,   this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageSERVER(), PROTOCOL_CALLBACK ( &CProtocol::evtServer, this ) );
    InternalAddHandler ( HANDLER_AFTER_CALLBACKS,  CMessageSQUIT(),  PROTOCOL_CALLBACK ( &CProtocol::evtSquit,  this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageNICK(),   PROTOCOL_CALLBACK ( &CProtocol::evtNick,   this ) );
    InternalAddHandler ( HANDLER_AFTER_CALLBACKS,  CMessageQUIT(),   PROTOCOL_CALLBACK ( &CProtocol::evtQuit,   this ) );
    InternalAddHandler ( HANDLER_AFTER_CALLBACKS,  CMessageKILL(),   PROTOCOL_CALLBACK ( &CProtocol::evtKill,   this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageMODE(),   PROTOCOL_CALLBACK ( &CProtocol::evtMode,   this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageBMODE(),  PROTOCOL_CALLBACK ( &CProtocol::evtBmode,  this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageBURST(),  PROTOCOL_CALLBACK ( &CProtocol::evtBurst,  this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageTBURST(), PROTOCOL_CALLBACK ( &CProtocol::evtTburst, this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageTOPIC(),  PROTOCOL_CALLBACK ( &CProtocol::evtTopic,  this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageCREATE(), PROTOCOL_CALLBACK ( &CProtocol::evtCreate, this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageJOIN(),   PROTOCOL_CALLBACK ( &CProtocol::evtJoin,   this ) );
    InternalAddHandler ( HANDLER_AFTER_CALLBACKS,  CMessagePART(),   PROTOCOL_CALLBACK ( &CProtocol::evtPart,   this ) );
    InternalAddHandler ( HANDLER_AFTER_CALLBACKS,  CMessageKICK(),   PROTOCOL_CALLBACK ( &CProtocol::evtKick,   this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageDB(),     PROTOCOL_CALLBACK ( &CProtocol::evtDB,     this ) );
    InternalAddHandler ( HANDLER_IN_CALLBACKS,     CMessageRAW(),    PROTOCOL_CALLBACK ( &CProtocol::evtRaw,    this ) );
    InternalAddHandler ( HANDLER_BEFORE_CALLBACKS, CMessageAWAY(),   PROTOCOL_CALLBACK ( &CProtocol::evtAway,   this ) );
    InternalAddHandler ( HANDLER_AFTER_CALLBACKS,  CMessageWHOIS(),  PROTOCOL_CALLBACK ( &CProtocol::evtWhois,  this ) );

    // Inicializamos los servicios
    CService::RegisterServices ( m_config );

    // Finalizamos el negociado
    Send ( CMessageEND_OF_BURST (), &m_me );

    return true;
}