示例#1
0
pcp_errno psd_add_pcp_server(pcp_ctx_t *ctx, struct sockaddr *sa,
        uint8_t version)
{
    struct in6_addr pcp_ip=IN6ADDR_ANY_INIT;
    uint16_t pcp_port;
    uint32_t scope_id=0;
    pcp_server_t *pcps=NULL;

    PCP_LOG_BEGIN(PCP_LOGLVL_DEBUG);

    if (sa->sa_family == AF_INET) {
        S6_ADDR32(&pcp_ip)[0]=0;
        S6_ADDR32(&pcp_ip)[1]=0;
        S6_ADDR32(&pcp_ip)[2]=htonl(0xFFFF);
        S6_ADDR32(&pcp_ip)[3]=((struct sockaddr_in *)sa)->sin_addr.s_addr;
        pcp_port=((struct sockaddr_in *)sa)->sin_port;
    } else {
        IPV6_ADDR_COPY(&pcp_ip, &((struct sockaddr_in6*)sa)->sin6_addr);
        pcp_port=((struct sockaddr_in6 *)sa)->sin6_port;
        scope_id=((struct sockaddr_in6 *)sa)->sin6_scope_id;
    }

    if (!pcp_port) {
        pcp_port=ntohs(PCP_SERVER_PORT);
    }

    pcps=get_pcp_server_by_ip(ctx, (struct in6_addr *)&pcp_ip);
    if (!pcps) {
        int pcps_indx=pcp_new_server(ctx, &pcp_ip, pcp_port, scope_id);

        if (pcps_indx >= 0) {
            pcps=get_pcp_server(ctx, pcps_indx);
        }

        if (pcps == NULL) {
            PCP_LOG(PCP_LOGLVL_ERR, "%s", "Can't add PCP server.\n");
            PCP_LOG_END(PCP_LOGLVL_DEBUG);
            return PCP_ERR_UNKNOWN;
        }
    } else {
        pcps->pcp_port=pcp_port;
    }

    pcps->pcp_version=version;
    pcps->server_state=pss_allocated;

    if (psd_fill_pcp_server_src(pcps)) {
        pcps->server_state=pss_unitialized;
        PCP_LOG(PCP_LOGLVL_INFO, "Failed to add PCP server %s",
                pcps->pcp_server_paddr);

        PCP_LOG_END(PCP_LOGLVL_DEBUG);
        return PCP_ERR_UNKNOWN;
    }

    PCP_LOG(PCP_LOGLVL_INFO, "Added PCP server %s", pcps->pcp_server_paddr);

    PCP_LOG_END(PCP_LOGLVL_DEBUG);
    return (pcp_errno)pcps->index;
}
示例#2
0
void psd_add_gws(pcp_ctx_t *ctx)
{
    struct sockaddr_in6 *gws=NULL, *gw;
    int rcount=getgateways(&gws);

    gw=gws;

    for (; rcount > 0; rcount--, gw++) {
        int pcps_indx;

        if ((IN6_IS_ADDR_V4MAPPED(&gw->sin6_addr)) && (S6_ADDR32(&gw->sin6_addr)[3] == INADDR_ANY))
            continue;

        if (IN6_IS_ADDR_UNSPECIFIED(&gw->sin6_addr))
            continue;

        if (get_pcp_server_by_ip(ctx, &gw->sin6_addr))
            continue;

        pcps_indx=pcp_new_server(ctx, &gw->sin6_addr, ntohs(PCP_SERVER_PORT), gw->sin6_scope_id);
        if (pcps_indx >= 0) {
            pcp_server_t *s=get_pcp_server(ctx, pcps_indx);
            if (!s)
                continue;

            if (psd_fill_pcp_server_src(s)) {
                PCP_LOG(PCP_LOGLVL_ERR,
                        "Failed to initialize gateway %s as a PCP server.",
                        s?s->pcp_server_paddr:"NULL pointer!!!");
            } else {
                PCP_LOG(PCP_LOGLVL_INFO, "Found gateway %s. "
                "Added as possible PCP server.",
                        s?s->pcp_server_paddr:"NULL pointer!!!");
            }
        }
    }
    free(gws);
}
示例#3
0
文件: pcp_msg.c 项目: UIKit0/pcp
void *build_pcp_msg(pcp_flow_t *flow)
{
    ssize_t ret=-1;
    pcp_server_t *pcp_server=NULL;
    pcp_request_t *req;
    // pointer used for referencing next data structure in linked list
    void *next_data=NULL;

    PCP_LOG_BEGIN(PCP_LOGLVL_DEBUG);

    if (!flow) {
        return NULL;
    }

    pcp_server=get_pcp_server(flow->ctx, flow->pcp_server_indx);

    if (!pcp_server) {
        return NULL;
    }

    if (!flow->pcp_msg_buffer) {
        flow->pcp_msg_buffer=(char*)calloc(1, PCP_MAX_LEN);
        if (flow->pcp_msg_buffer == NULL) {
            PCP_LOG(PCP_LOGLVL_ERR, "%s",
                    "Malloc can't allocate enough memory for the pcp_flow.");
            PCP_LOG_END(PCP_LOGLVL_DEBUG);
            return NULL;
        }
    }

    req=(pcp_request_t *)flow->pcp_msg_buffer;

    if (pcp_server->pcp_version == 0) {
        // NATPMP
#ifndef PCP_DISABLE_NATPMP
        ret=build_natpmp_msg(flow);
#endif
    } else {

        req->ver=pcp_server->pcp_version;

        req->r_opcode|=(uint8_t)(flow->kd.operation & 0x7f); //set  opcode
        req->req_lifetime=htonl((uint32_t)flow->lifetime);

        memcpy(&req->ip, &flow->kd.src_ip, 16);
        // next data in the packet
        next_data=req->next_data;
        flow->pcp_msg_len=(uint8_t *)next_data - (uint8_t *)req;

        switch (flow->kd.operation) {
            case PCP_OPCODE_PEER:
                ret=build_pcp_peer(pcp_server, flow, next_data);
                break;
            case PCP_OPCODE_MAP:
                ret=build_pcp_map(pcp_server, flow, next_data);
                break;
#ifdef PCP_SADSCP
            case PCP_OPCODE_SADSCP:
                ret=build_pcp_sadscp(pcp_server, flow, next_data);
                break;
#endif
            case PCP_OPCODE_ANNOUNCE:
                ret=0;
                break;
        }
    }

    if (ret < 0) {
        PCP_LOG(PCP_LOGLVL_ERR, "%s", "Unsupported operation.");
        free(flow->pcp_msg_buffer);
        flow->pcp_msg_buffer=NULL;
        flow->pcp_msg_len=0;
        req=NULL;
    }

    PCP_LOG_END(PCP_LOGLVL_DEBUG);
    return req;
}
示例#4
0
int main(void)
{
    pcp_ctx_t * ctx;
    pcp_log_level = PCP_DEBUG_NONE;
    PD_SOCKET_STARTUP();
    ctx = pcp_init(0, NULL);
#ifndef PCP_DISABLE_NATPMP
    {   // TEST NATPMP - parsing
        nat_pmp_announce_resp_t natpmp_a;
        nat_pmp_map_resp_t natpmp_mt;
        nat_pmp_map_resp_t natpmp_mu;
        pcp_recv_msg_t msg;


        natpmp_a.ver = 0;
        natpmp_a.opcode = 0;
        natpmp_a.result =  htons(11);
        natpmp_a.epoch = htonl(1234);
        natpmp_a.ext_ip = 0x01020304;

        natpmp_mt.ver = 0;
        natpmp_mt.opcode = NATPMP_OPCODE_MAP_TCP;
        natpmp_mt.result = htons(11);
        natpmp_mt.epoch = htonl(1234);
        natpmp_mt.ext_port = htons(1234);
        natpmp_mt.int_port = htons(3456);
        natpmp_mt.lifetime = htonl(2233);

        natpmp_mu.ver = 0;
        natpmp_mu.opcode = NATPMP_OPCODE_MAP_UDP;
        natpmp_mu.result = htons(11);
        natpmp_mu.epoch = htonl(1234);
        natpmp_mu.ext_port = htons(1234);
        natpmp_mu.int_port = htons(3456);
        natpmp_mu.lifetime = htonl(2233);

        memset(&msg,0,sizeof(msg));
        memcpy(&msg.pcp_msg_buffer, &natpmp_a, sizeof(natpmp_a));
        msg.pcp_msg_len = sizeof(natpmp_a);
        TEST(parse_response(&msg)==PCP_ERR_SUCCESS);
        TEST(msg.recv_version==0);
        TEST(msg.recv_epoch==1234);
        TEST(msg.recv_result==11);
        msg.pcp_msg_len = sizeof(natpmp_a)-1;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);

        natpmp_a.ver++;
        memset(&msg,0,sizeof(msg));
        memcpy(&msg.pcp_msg_buffer, &natpmp_a, sizeof(natpmp_a));
        msg.pcp_msg_len = sizeof(natpmp_a);
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);

        msg.pcp_msg_len = sizeof(pcp_response_t);
        TEST(parse_response(&msg)==PCP_ERR_SUCCESS);
        TEST(msg.recv_version==1);
        TEST(msg.recv_result==11);

        natpmp_a.ver++;
        memset(&msg,0,sizeof(msg));
        memcpy(&msg.pcp_msg_buffer, &natpmp_a, sizeof(natpmp_a));
        msg.pcp_msg_len = sizeof(natpmp_a);
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);

        msg.pcp_msg_len = sizeof(pcp_response_t);
        TEST(parse_response(&msg)==PCP_ERR_SUCCESS);
        TEST(msg.recv_version==2);
        TEST(msg.recv_result==11);

        memset(&msg,0,sizeof(msg));
        memcpy(&msg.pcp_msg_buffer, &natpmp_mt, sizeof(natpmp_mt));
        msg.pcp_msg_len = sizeof(natpmp_mt);
        TEST(parse_response(&msg)==PCP_ERR_SUCCESS);
        TEST(msg.assigned_ext_port==htons(1234));
        TEST(msg.kd.map_peer.src_port==htons(3456));
        TEST(msg.kd.map_peer.protocol==IPPROTO_TCP);
        TEST(msg.recv_version==0);
        TEST(msg.recv_epoch==1234);
        TEST(msg.recv_lifetime==2233);
        TEST(msg.recv_result==11);

        memset(&msg,0,sizeof(msg));
        memcpy(&msg.pcp_msg_buffer, &natpmp_mu, sizeof(natpmp_mu));
        msg.pcp_msg_len = sizeof(natpmp_mu);
        TEST(parse_response(&msg)==PCP_ERR_SUCCESS);
        TEST(msg.assigned_ext_port==htons(1234));
        TEST(msg.kd.map_peer.src_port==htons(3456));
        TEST(msg.kd.map_peer.protocol==IPPROTO_UDP);
        TEST(msg.recv_version==0);
        TEST(msg.recv_epoch==1234);
        TEST(msg.recv_lifetime==2233);
        TEST(msg.recv_result==11);

        msg.pcp_msg_len = sizeof(natpmp_mu)-1;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);

        natpmp_mu.opcode=3;
        memset(&msg,0,sizeof(msg));
        memcpy(&msg.pcp_msg_buffer, &natpmp_mu, sizeof(natpmp_mu));

        msg.pcp_msg_len = sizeof(natpmp_mu);
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
    }
#endif
    {   // TEST validate MSG
        pcp_recv_msg_t msg;
        pcp_response_t* resp = (pcp_response_t*)msg.pcp_msg_buffer;

        memset(&msg, 0, sizeof(msg));
        resp->r_opcode=0x81;
        resp->ver=1;
        msg.pcp_msg_len=sizeof(pcp_response_t);

        TEST(validate_pcp_msg(&msg));
        msg.pcp_msg_len=sizeof(pcp_response_t)-1;
        TEST(!validate_pcp_msg(&msg));
        msg.pcp_msg_len=sizeof(pcp_response_t)-4;
        TEST(validate_pcp_msg(&msg));
        msg.pcp_msg_len=1104;
        TEST(!validate_pcp_msg(&msg));
        msg.pcp_msg_len=0;
        TEST(!validate_pcp_msg(&msg));

        msg.pcp_msg_len=sizeof(pcp_response_t);
        resp->ver=2;
        TEST(validate_pcp_msg(&msg));
        resp->ver=3;
        TEST(!validate_pcp_msg(&msg));
        resp->ver=2;
        resp->r_opcode=0x1;
        TEST(!validate_pcp_msg(&msg));
        resp->r_opcode=0x7f;
        TEST(!validate_pcp_msg(&msg));

        resp->r_opcode=0x81;
        msg.pcp_msg_len=sizeof(pcp_response_t)-1;
        resp->ver=1;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->ver=2;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->r_opcode=0x82;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->ver=1;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->r_opcode=0x83;
        resp->ver=2;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);

        resp->r_opcode=0x81;
        msg.pcp_msg_len=sizeof(pcp_response_t)+1;
        resp->ver=1;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->ver=2;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->r_opcode=0x82;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->ver=1;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->r_opcode=0x83;
        resp->ver=2;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);

        msg.pcp_msg_len=sizeof(pcp_response_t);
        resp->r_opcode=0x84;
        resp->ver=2;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->ver=1;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
        resp->ver=3;
        resp->r_opcode=0x82;
        TEST(parse_response(&msg)!=PCP_ERR_SUCCESS);
    }
    {  //TEST build msg
        struct pcp_flow_s fs;
        pcp_server_t *s;

        memset(&fs, 0, sizeof(fs));
        fs.ctx=ctx;
        TEST(build_pcp_msg(&fs)==NULL);
        fs.pcp_server_indx=pcp_add_server(ctx, Sock_pton("127.0.0.1"),1);
        s=get_pcp_server(ctx, fs.pcp_server_indx);
        fs.kd.operation = PCP_OPCODE_ANNOUNCE;
        TEST(build_pcp_msg(&fs)!=NULL);
        fs.kd.operation = 0x7f;
        TEST(build_pcp_msg(&fs)==NULL);
        fs.kd.operation = PCP_OPCODE_SADSCP;
        TEST(build_pcp_msg(&fs)==NULL);
        s->pcp_version = 3;
        TEST(build_pcp_msg(&fs)==NULL);
        fs.kd.operation = PCP_OPCODE_MAP;
        TEST(build_pcp_msg(&fs)==NULL);
        fs.kd.operation = PCP_OPCODE_PEER;
        TEST(build_pcp_msg(&fs)==NULL);
        s->pcp_version = 2;
#ifdef PCP_EXPERIMENTAL
        {
            uint16_t i;

            pcp_db_add_md(&fs, 0, NULL,sizeof("string"));
            pcp_db_add_md(&fs, 1, "string", 0);
            for (i=2; i<256; ++i) {
                pcp_db_add_md(&fs, i, "string",sizeof("string"));
            }
            TEST(build_pcp_msg(&fs)!=NULL);
            TEST(fs.pcp_msg_len<=PCP_MAX_LEN);
        }
#endif
        TEST(build_pcp_msg(NULL)==NULL);
    }

    PD_SOCKET_CLEANUP();
    return 0;
}
示例#5
0
int main(void)
{
    pcp_flow_t *f1, *f2;
    pcp_ctx_t *ctx;

    pcp_log_level = PCP_DEBUG_NONE;

    PD_SOCKET_STARTUP();
    //test pcp_init & terminate
    ctx = pcp_init(DISABLE_AUTODISCOVERY, NULL);
    TEST(get_pcp_server(ctx, 0)==NULL);
    pcp_terminate(ctx, 1);
    ctx = pcp_init(ENABLE_AUTODISCOVERY, NULL);
    TEST(get_pcp_server(ctx, 0)!=NULL);
    pcp_terminate(ctx, 1);
    TEST(get_pcp_server(ctx, 0)==NULL);

    ctx = pcp_init(DISABLE_AUTODISCOVERY, NULL);
    TEST(pcp_add_server(ctx, Sock_pton("127.0.0.1:5351"), 2)==0);
#ifdef PCP_USE_IPV6_SOCKET
    TEST(pcp_add_server(ctx, Sock_pton("[::1]:5351"), 1)==1);
#endif
    pcp_terminate(ctx, 1);

#ifdef PCP_SADSCP
    //TEST learn DSCP
    {
        pcp_flow_t* l1;
        ctx = pcp_init(DISABLE_AUTODISCOVERY, NULL);
        TEST((l1=pcp_learn_dscp(ctx, 1,1,1,NULL))==NULL); //NO PCP server to send req

        TEST(pcp_add_server(ctx, Sock_pton("127.0.0.1:5351"), 2)==0);
        TEST((l1=pcp_learn_dscp(ctx, 1,1,1,NULL))!=NULL);
        TEST(l1->kd.operation==PCP_OPCODE_SADSCP);
        TEST(l1->sadscp_app_name==NULL);
        TEST(l1->sadscp.app_name_length==0);
        TEST(l1->sadscp.toler_fields==84);
        pcp_close_flow(l1);
        pcp_delete_flow(l1);

        TEST((l1=pcp_learn_dscp(ctx, 2,2,2,"test"))!=NULL);
        TEST(l1->sadscp.app_name_length==4);
        TEST(strncmp(l1->sadscp_app_name,"test",l1->sadscp.app_name_length)==0);
        TEST(l1->sadscp.toler_fields==168);

        pcp_terminate(ctx, 1);
    }
#endif

    ctx = pcp_init(DISABLE_AUTODISCOVERY, NULL);
    TEST(pcp_add_server(ctx, Sock_pton("127.0.0.1:5351"), 2)==0);
    TEST((pcp_new_flow(ctx, Sock_pton("[::1]:1234"), Sock_pton("[::1]"), NULL,
            IPPROTO_TCP, 100, NULL))==NULL);

    pcp_pulse(NULL, NULL);
    pcp_pulse(ctx, NULL);
    pcp_flow_get_info(NULL, NULL, NULL);

    //PCP PEER/MAP tests
    TEST(pcp_new_flow(NULL, NULL, NULL, NULL, 0, 0, NULL)==NULL);
    TEST(pcp_new_flow(ctx, NULL, NULL, NULL, 0, 0, NULL)==NULL);

    TEST((f1=pcp_new_flow(ctx, Sock_pton("127.0.0.1:1234"), Sock_pton("127.0.0.1"), NULL,
            IPPROTO_TCP, 100, NULL))!=NULL);
    TEST((f2=pcp_new_flow(ctx, Sock_pton("127.0.0.1:1234"), NULL, NULL,
            IPPROTO_TCP, 100, NULL))!=NULL);
    pcp_flow_set_prefer_failure_opt(f2);
    pcp_flow_set_prefer_failure_opt(f2);

    pcp_flow_set_lifetime(f1, 1000);
    TEST((f1->lifetime)>=99);
    TEST((f1->timeout.tv_sec>0)||(f1->timeout.tv_usec>0));

    f1->timeout.tv_sec=0;
    f1->timeout.tv_usec=0;
    pcp_flow_set_lifetime(f1, 0);
    TEST(f1->lifetime==0);
    TEST((f1->timeout.tv_sec>0)||(f1->timeout.tv_usec>0));

    pcp_set_3rd_party_opt(f1,NULL);

    printf("Tests succeeded.\n\n");

    PD_SOCKET_CLEANUP();
    return 0;
}