Example #1
0
/*
 *===========================================================================
 *                    ipcom_shellalias_find
 *===========================================================================
 * Description: Find a given alias based on name.
 * Parameters:  name        - The alias name.
 * Returns:     The alias if found.
 *
 */
IP_STATIC struct Ipcom_shellalias_alias *
ipcom_shellalias_find(const char *name)
{
    struct Ipcom_shellalias_alias   *alias;

    /* Go through the aliases */
    for (alias = IPCOM_LIST_FIRST(&ipcom_shellalias_head);
         alias != IP_NULL;
         alias = IPCOM_LIST_NEXT(&alias->next))
    {
        if (name == IP_NULL)
        {
            int i;
            ipcom_printf("%-15s\t'", alias->name);
            for (i = 0; i < alias->argc; i++)
            {
                ipcom_printf("%s%s",
                             alias->argv[i],
                             (i == alias->argc - 1)? "" : " ");
            }
            ipcom_printf("'"IP_LF);
        }
        /* Did it match? */
        else if (ipcom_strcmp(alias->name, name) == 0)
        {
            /* Return it */
            return alias;
        }
    }

    /* No go */
    return IP_NULL;
}
/*
 *===========================================================================
 *                    ipcom_shell_cmd_help
 *===========================================================================
 * Description:     Shell command: Get help on command or display all commands
 * Parameters:      argc - number of arguments
 *                  argv - pointer to pointer to the arguments
 * Returns:         0
 *
 */
IP_STATIC int
ipcom_shell_cmd_help(int argc, char **argv)
{
    Ipcom_shell_cmd *cmd;
    Ipcom_shell_intcmd *intcmd;

    Ip_s32 i = 0;

    /* Check if argument is supplied */
    if (argc > 1)
    {
        intcmd = IP_NULL;

        /* Find shell internal command */
        while(shell_intcmd[i].name[0] != 0)
        {
            intcmd = (Ipcom_shell_intcmd *)&shell_intcmd[i];
            if (ipcom_strcmp(intcmd->name, argv[1]) == 0)
                break;

            intcmd = IP_NULL;
            i++;
        }
        if (intcmd)
        {
            ipcom_printf("Usage: %s\n", intcmd->usage);
            return 0;
        }

        /* Find shell command */
        cmd = ipcom_shell_find_cmd(argv[1]);
        if (cmd)
        {
            ipcom_printf("Usage: %s\n", cmd->usage);
            return 0;
        }

        /* Command not found */
        ipcom_printf("help: Unknown command '%s'\n", argv[1]);
    }
    else
    {
        /* List all shell internal commands */
        while(shell_intcmd[i].name[0] != 0)
        {
            ipcom_printf("%-32s %s\n", shell_intcmd[i].name, shell_intcmd[i].description);
            i++;
        }

        /* List all shell commands */
        for (cmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); cmd; cmd = IPCOM_LIST_NEXT(&cmd->cmd_list))
        {
            ipcom_printf("%-32s %s\n", cmd->name, cmd->description);
        }
        ipcom_printf("\n");
    }

    return 0;
}
Example #3
0
/*
 *===========================================================================
 *                    ipcom_shell_find_cmd
 *===========================================================================
 * Description:     Search for  a command in the list of available ipcom_shell
 *                  commands
 * Parameters:      name : the command to search for
 * Returns:         pointer to the command or IP_NULL if not found
 *
 */
IP_PUBLIC Ipcom_shell_cmd *
ipcom_shell_find_cmd(const char *name)
{
    Ipcom_shell_cmd *cmd;

    /* First check if present */
    for (cmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); cmd; cmd = IPCOM_LIST_NEXT(&cmd->cmd_list))
        if (ipcom_strcmp(cmd->name, name) == 0)
            break;

    return cmd;
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_dns_find_transaction
 *===========================================================================
 * Description: Find a transaction in the list of transactions.
 * Parameters:  type    - DNS query type.
 *              dns_hdr - pointer to the DNS protocol header.
 *              param   - pointer to NAT proxy parameters.
 * Returns:     A pointer to transaction if found or else IP_NULL.
 */
IP_STATIC Ipnet_nat_dns_transaction *
ipnet_nat_proxy_dns_find_transaction(int type,
                                     Ipnet_nat_dns_hdr *dns_hdr,
                                     Ipnet_nat_proxy_param *param)
{
    Ipnet_nat_dns_transaction *trans;
    Ip_u16 id;

    id = (Ip_u16)IP_GET_NTOHS(&dns_hdr->id);
    for (trans = IPCOM_LIST_FIRST(&ipnet_nat_proxy_dns_list);
         trans != IP_NULL;
         trans = IPCOM_LIST_NEXT(&trans->list))
    {
        if (id == trans->id
            && param->tuple.private_port == trans->srcport
            && param->tuple.public_addr == trans->dstaddr
            && type == trans->type)
        {
            return trans;
        }
    }

    return IP_NULL;
}
/*
 *===========================================================================
 *                    ipl2tps
 *===========================================================================
 * Description: 
 * Parameters:  
 * Returns:     
 *
 */
IP_STATIC
IPCOM_PROCESS(ipl2tps)
{
    Ip_fd                   ipd_fd = IP_INVALID_SOCKET;
    Ip_bool                 ipd_init = 0;
#ifdef IPPPP_USE_PPPL2TP
    Ip_fd                   ipl2tp_ppp_ipc_recv_fd = IP_INVALID_SOCKET;
#endif

    ipcom_proc_init();

#ifdef IPPPP_USE_PPPL2TP
    if ((ipl2tp_ppp_ipc_recv_fd = ipppp_pppl2tp_pkt_que_open()) == IP_INVALID_SOCKET)
    {
        ipcom_printf("Cannot allocate data packet output socket, errno: %d"IP_LF, ipcom_errno);
        goto leave;
    }
#endif

    /* Get socket */
    if ((udp_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP)) < 0)
    {
        ipcom_printf("Cannot allocate socket, errno: %d"IP_LF,
                     ipcom_errno);
        goto leave;
    }
    else
    {
        union Ip_sockaddr_union uaddr;

        /* Bind to L2TP port */
        ipcom_memset(&uaddr, 0, sizeof(uaddr));

        uaddr.sin.sin_family        = IP_AF_INET;
        uaddr.sin.sin_addr.s_addr   = IP_INADDR_ANY;
        uaddr.sin.sin_port          = ip_htons(IPL2TP_PORT_NUMBER);
        uaddr.sin.sin_len           = sizeof(struct Ip_sockaddr_in);
        if (ipcom_bind(udp_fd, &uaddr.sa, sizeof(struct Ip_sockaddr_in)) < 0)
        {
            ipcom_printf("Cannot bind socket, errno: %d"IP_LF,
                         ipcom_errno);
            ipcom_socketclose(udp_fd);
            goto leave;
        }
    }

    /* Get socket */
    if ((ip_fd = ipcom_socket(IP_AF_INET, IP_SOCK_RAW, IP_IPPROTO_L2TP)) < 0)
    {
        ipcom_printf("Cannot allocate socket, errno: %d"IP_LF,
                     ipcom_errno);
        ipcom_socketclose(udp_fd);
        goto leave;
    }


    /* Init IPD */
    if (ipd_init == 0 &&
        ipcom_ipd_init("ipl2tp", IPCOM_SUCCESS, &ipd_fd) != IPCOM_SUCCESS)
    {
        ipcom_printf("Cannot initialize ipd: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto leave;
    }

    ipd_init = 1;

    /* Enter read loop (never return) */
    for (;;)
    {
        Ip_fd_set                   fds;            
        Ipl2tp_example_fd_entry_t   *fd;
        int                         fd_max;
        struct Ip_timeval           tv;
        int                         ret;

        IP_FD_ZERO(&fds);

        IP_FD_SET(udp_fd, &fds);
        IP_FD_SET(ip_fd, &fds);
        IP_FD_SET(ipd_fd, &fds);
        fd_max = IP_MAX(udp_fd, ip_fd);
        fd_max = IP_MAX(fd_max, ipd_fd);

#ifdef IPPPP_USE_PPPL2TP
        IP_FD_SET(ipl2tp_ppp_ipc_recv_fd, &fds); 
        fd_max = IP_MAX(fd_max, ipl2tp_ppp_ipc_recv_fd);
#endif

        fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds);
        while (fd != IP_NULL)
        {
            Ipl2tp_example_fd_entry_t   *nfd = IPCOM_LIST_NEXT(&fd->next);
            if (fd->data != IP_NULL)
            {
                IP_FD_SET(fd->fd, &fds);
                fd_max = IP_MAX(fd_max, fd->fd);
            }
            else
            {
                ipcom_list_remove(&fd->next);
                ipcom_socketclose(fd->fd);
                ipcom_free(fd);
            }

            fd = nfd;
        }

        tv.tv_sec   = 0;
        tv.tv_usec  = 10000;
        if ((ret = ipcom_socketselect(fd_max + 1, &fds, IP_NULL, IP_NULL, &tv)) > 0)
        {
            union Ip_sockaddr_union uaddr;
            int                     length;
            Ip_u8                   *buffer;

            if (IP_FD_ISSET(ipd_fd, &fds))
            {
                int event;

                event = ipcom_ipd_input(ipd_fd);
                if (event == IPCOM_IPD_EVENT_RECONFIGURE)
                    goto leave;
            }


#ifdef IPPPP_USE_PPPL2TP
            if (IP_FD_ISSET(ipl2tp_ppp_ipc_recv_fd, &fds))
            {
                Ipppp_pppl2tp_pkt_que_entry que_entry;
                Ipcom_netif *netif;
                Ipcom_pkt *pkt;
                char addrstr[IP_INET_ADDRSTRLEN];

                /* Read message and feed it to L2TP main input */
                if (ipppp_pppl2tp_pkt_que_recv(&que_entry, &uaddr) == IPCOM_SUCCESS)
                {
                    if ((que_entry.netif == IP_NULL) ||
                        (que_entry.pkt == IP_NULL))
                    {
                        ipcom_printf("ipl2tps: L2TPv2 pkt from %s:%d contains null ptr(s)."IP_LF,
                            ipcom_inet_ntop(IP_AF_INET, &uaddr.sin.sin_addr, addrstr, sizeof(addrstr)),
                            ipcom_ntohs(uaddr.sin.sin_port));
                    }
                    else
                    {
                        pkt = que_entry.pkt;
                        netif = que_entry.netif;
                        ipppp_pppl2tp_output(netif, pkt);
                    }
                }
                else
                    ipcom_printf("ipl2tps: PPP pkt recv failed."IP_LF);
            }
#endif /* IPPPP_USE_PPPL2TP */

            if (IP_FD_ISSET(udp_fd, &fds))
            {
                /* Read message and feed it to L2TP main input */
                if ((length = ipl2tp_l2tp_read(udp_fd, &buffer, &uaddr)) > 0)
                {
                    ipl2tp_api_l2tp_input(buffer, 
                                          buffer + HEADER_SPACE,
                                          (Ip_u16)length, 
                                          &uaddr, 
                                          IPL2TP_ATTR_TRANSPORT_UDP);

                    /* Free buffer if not in PPP output queue */
                    if (ipl2tp_buffer_free)
                    {
                        ipl2tp_cache_free(buffer);
                    }
                }
            }

            if (IP_FD_ISSET(ip_fd, &fds))
            {
                /* Read message and feed it to L2TP main input */
                if ((length = ipl2tp_l2tp_read(ip_fd, &buffer, &uaddr)) > 0)
                {
                    /* Remove the IP header before invoking */
                    ipl2tp_api_l2tp_input(buffer, 
                                          buffer + HEADER_SPACE + 20,
                                          (Ip_u16)(length - 20), 
                                          &uaddr, 
                                          IPL2TP_ATTR_TRANSPORT_IP);

                    /* Free buffer if not in PPP output queue */
                    if (ipl2tp_buffer_free)
                    {
                        ipl2tp_cache_free(buffer);
                    }
                }
            }

            fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds);
            while (fd != IP_NULL)
            {
                Ipl2tp_example_fd_entry_t   *nfd = IPCOM_LIST_NEXT(&fd->next);
                if (fd->data!= IP_NULL && IP_FD_ISSET(fd->fd, &fds))
                {
                    /* Read message and feed it to L2TP main input */
                    if ((length = ipl2tp_l2tp_read(fd->fd, &buffer, &uaddr)) > 0)
                    {
                        if (fd->data != IP_NULL)
                        {
                            (*fd->data) (fd,
                                         buffer, 
                                         buffer + HEADER_SPACE, 
                                         length);
                        }

                        /* Free buffer if not in PPP output queue */
                        if (ipl2tp_buffer_free)
                        {
                            ipl2tp_cache_free(buffer);
                        }
                    }
                }

                fd = nfd;
            }
        }
        else if (ret < 0)
        {
            ipcom_printf("select error"IP_LF);
        }        
    }

leave:
    /* Have to call ipd init if not done yet */
    if (ipd_init == 0 &&
        ipcom_ipd_init("ipl2tp", IPCOM_ERR_FAILED, &ipd_fd) == IPCOM_SUCCESS)
    {
        ipd_init = 1;
    }
    if (ipd_init != 0)
    {
        (void)ipcom_ipd_exit("ipl2tp", ipd_fd);
    }

    ipcom_proc_exit();
}
Example #6
0
/*
 *===========================================================================
 *                    ipcom_shell_run_extcmd
 *===========================================================================
 * Description: Starts a shell command process and delivers the command arguments
 *              and stdio socket to that process.
 * Parameters:  argc, argv - traditional command arguments
 *              stdio_fd - the standard input, output and error sock
 *              ppid - parent pid
 *              cmd_pid - shell command process id
 *
 * Returns:          1 : command process started
 *                   0 : not an external command
 *                  -1 : error
 *
 */
IP_PUBLIC Ip_err
ipcom_shell_run_extcmd(int argc, char **argv, Ip_fd *stdio_fd, Ip_pid_t ppid, Ip_u32 seqno, Ip_pid_t *cmd_pid, int *proc_index)
{
    Ipcom_proc_attr  attr;
    Ipcom_ipc        ipc;
    Ipcom_shellcmd_info  *sinfo;
    Ipcom_shell_cmd   *cmd = IP_NULL;
    Ipcom_shell_cmd   *tcmd;
    Ip_err retval;
    char procname[40];
    Ip_u32    stack = IPCOM_PROC_STACK_DEFAULT;
    Ip_pid_t  pid;

    pid = ipcom_getpid();
    ipcom_sprintf(procname, "ipcom_sc_0x%lx_%d", (Ip_u32)pid, *proc_index);

    /* Find command and max stack size (since we are reusing the process). */
    if (argc > 0)
    {
        for (tcmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); tcmd; tcmd = IPCOM_LIST_NEXT(&tcmd->cmd_list))
        {
            stack = (Ip_u32)IP_MAX(stack, tcmd->stack_size);
            if (cmd == IP_NULL && ipcom_strcmp(tcmd->name, argv[0]) == 0)
            {
                cmd = tcmd;
                if (*cmd_pid != 0)
                    break;
            }
        }
        if (cmd == IP_NULL)
            return 0;

        /* Start the shell_cmd process. */
        if (*cmd_pid == 0)
        {
            ipcom_proc_attr_init(&attr);
            attr.priority  = (Ip_u32)cmd->priority;
            attr.stacksize = stack;
            attr.flags |= IPCOM_PROC_FLAG_FP;
            if (ipcom_proc_acreate(procname, (Ipcom_proc_func)ipcom_shell_cmd, &attr, cmd_pid))
            {
                IPCOM_LOG0(ERR, "ipcom_shell_run_extcmd :: ipcom_proc_acreate() failed");
                goto fail;
            }
            ip_assert(*cmd_pid != 0);
        }
    }
    else
    {
        /* argc == 0 is used to kill the shell_cmd process. */
        ip_assert(*cmd_pid != 0);
    }

    /* Open IPC with ipcom_shell. */
    retval = ipcom_ipc_open(&ipc, procname, -1);
    if (retval != IPCOM_SUCCESS)
    {
        IPCOM_LOG2(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_open(%s) failed, ret = %d", procname, retval);
        goto fail;
    }

    /* Send a message to ipcom_shell. */
    sinfo = ipcom_ipc_malloc(sizeof(Ipcom_shellcmd_info));
    if (sinfo == IP_NULL)
    {
        IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_malloc() failed, ret = %d", retval);
        goto fail;
    }

    /* Fill in IPC info. */
    sinfo->argc = argc;
    if (argc > 0)
    {
        sinfo->hook  = cmd->hook;
        sinfo->argv  = argv;
        sinfo->fd    = *stdio_fd;
        sinfo->pid   = pid;
        sinfo->ppid  = ppid;
        sinfo->seqno = seqno;
#if IPCOM_USE_FILE != IPCOM_FILE_NONE
        if (ipcom_getcwd(sinfo->cwd, sizeof(sinfo->cwd)) == IP_NULL)
            ipcom_memset(sinfo->cwd, 0, sizeof(sinfo->cwd));
        else
            sinfo->cwd[sizeof(sinfo->cwd)-1] = '\0';
#endif
        sinfo->prio = cmd->priority;
    }

    /* Send the IPC info. */
    retval = ipcom_ipc_send(&ipc, sinfo);
    if (retval != IPCOM_SUCCESS)
    {
        IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_send() failed, ret = %d", retval);
        ipcom_ipc_free(sinfo);
        goto fail;
     }

    (void)ipcom_ipc_close(&ipc);

#ifdef IP_PORT_OSE5
    if (argc > 0)
    {
        /* OSE5 has process specific sockets -> donate child fd */
        ip_assert(*cmd_pid != 0);
        retval = (Ip_err)efs_donate_fd(*stdio_fd, *cmd_pid);
        if (retval != 0)
        {
            IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: efs_donate_fd, ret = %d", retval);
            goto fail;
        }
    }
#endif /* IP_PORT_OSE5 */

    /* Wait for exit message from shell_cmd process. */
    retval = ipcom_ipc_receive(IP_NULL, &sinfo, -1);
    if (retval != IPCOM_SUCCESS)
    {
        IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_receive(shell_cmd) failed, ret = %d", retval);
        goto fail;
    }
    ip_assert(argc > 0 || *(Ip_u32 *)sinfo == 1);
    if (*(Ip_u32 *)sinfo == 1)
    {
        *cmd_pid = 0;  /* shell command called ipcom_exit(). */
        (*proc_index)++;
    }
    else
    {
#ifdef IP_PORT_OSE5
        *stdio_fd = efs_receive_fd(0);
        if (*stdio_fd == -1)
        {
            IP_PANIC();
            goto fail;
        }
#endif
#if defined(IP_PORT_OSE) || defined(IP_PORT_OSE5)
        /* Change child socket owner (A must for OSE to work due to poor ipcom_block impl). */
        pid = ipcom_getpid();
        if (ipcom_socketioctl(*stdio_fd, IP_SIOCSPGRP, &pid) < 0)
        {
            IP_PANIC2();
            IPCOM_LOG1(WARNING, "ipcom_shell_run_extcmd :: ipcom_socketioctl(IP_SIOCSPGRP) failed, errno = %d", ipcom_errno);
        }
#endif

    }
    ipcom_ipc_free(sinfo);

    return 1;

 fail:
    if (ipcom_ipc_isopen(&ipc))
        (void)ipcom_ipc_close(&ipc);
    return -1;
}