示例#1
0
/*
 * \brief open a unix-domain socket and bind it to a file.
 *
 * The socket is accessed via CLICON_SOCK option, has 770 permissions
 * and group according to CLICON_SOCK_GROUP option.
 */
int
config_socket_init(clicon_handle h)
{
    int s;
    struct sockaddr_un addr;
    mode_t             old_mask;
    char              *config_sock;
    char              *config_group;
    gid_t              gid;
    struct stat        st;

    /* first find sockpath and remove it if it exists (it shouldn't) */
    if ((config_sock = clicon_sock(h)) == NULL)
	return -1;
    if (lstat(config_sock, &st) == 0 && unlink(config_sock) < 0){
	clicon_err(OE_UNIX, errno, "%s: unlink(%s)", __FUNCTION__, config_sock);
	return -1;
    }
    /* then find configuration group (for clients) and find its groupid */
    if ((config_group = clicon_sock_group(h)) == NULL)
	return -1;
    if (group_name2gid(config_group, &gid) < 0)
	return -1;
#if 0
    if (gid == 0) 
	clicon_log(LOG_WARNING, "%s: No such group: %s\n", __FUNCTION__, config_group);
#endif
    /* create unix socket */
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
	clicon_err(OE_UNIX, errno, "%s: socket", __FUNCTION__);
	return -1;
    }

//    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&one, sizeof(one));
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, config_sock, sizeof(addr.sun_path)-1);
    old_mask = umask(S_IRWXO | S_IXGRP | S_IXUSR);
    if (bind(s, (struct sockaddr *)&addr, SUN_LEN(&addr)) < 0){
	clicon_err(OE_UNIX, errno, "%s: bind", __FUNCTION__);
	umask(old_mask); 
	goto err;
    }
    umask(old_mask); 
    /* change socket path file group */
    if (lchown(config_sock, -1, gid) < 0){
	clicon_err(OE_UNIX, errno, "%s: lchown(%s, %s)", __FUNCTION__, 
		config_sock, config_group);
	goto err;
    }
    clicon_debug(1, "Listen on server socket at %s", addr.sun_path);
    if (listen(s, 5) < 0){
	clicon_err(OE_UNIX, errno, "%s: listen", __FUNCTION__);
	goto err;
    }
    return s;
  err:
    close(s);
    return -1;
}
示例#2
0
struct rost_etstats *
ethtool_client_gstats(clicon_handle h, char *ifname, const char *label)
{
    uint16_t            etslen;
    struct clicon_msg  *msg;
    struct rost_etstats *tmp, *ets = NULL;
    char                *s;
    int                 i;
    
    msg = clicon_msg_call_encode(0, "ethtool", "ethtool_gstats", 
				strlen(ifname), ifname, __FUNCTION__);
    if (msg == NULL)
	goto done;
    
    if ((s = clicon_sock(h)) == NULL)
	goto done;
    if (clicon_rpc_connect(msg, s, (char **)&tmp, &etslen, label) < 0)
	goto done;

    ets = tmp;
    for (i = 0; i < ets->ets_nstats; i++)
	ets->ets_stat[i].etse_value = htonll(tmp->ets_stat[i].etse_value);

done:
    unchunk_group(__FUNCTION__);
    return ets;
}
示例#3
0
struct ethtool_cmd *
ethtool_client_gset(clicon_handle h, char *ifname, const char *label)
{
    uint16_t            eclen;
    struct ethtool_cmd *tmp, *ec = NULL;
    struct clicon_msg  *msg;
    char                *s;

    msg = clicon_msg_call_encode(0, "ethtool", "ethtool_gset", 
			      strlen(ifname), ifname, __FUNCTION__);
    if (msg == NULL)
	goto done;
    if ((s = clicon_sock(h)) == NULL)
	goto done;
    if (clicon_rpc_connect(msg, s, (char **)&tmp, &eclen, label) < 0)
	goto done;

    ec = tmp;
    ec->cmd = ntohl(tmp->cmd);
    ec->supported = ntohl(tmp->supported);
    ec->advertising = ntohl(tmp->advertising);
    ec->speed = ntohs(tmp->speed);
    ec->maxtxpkt = ntohl(tmp->maxtxpkt);
    ec->maxrxpkt = ntohl(tmp->maxrxpkt);
    ec->speed_hi = ntohs(tmp->speed_hi);
    ec->eth_tp_mdix = ntohs(tmp->eth_tp_mdix);
   
done:
    unchunk_group(__FUNCTION__);
    return ec;
}
示例#4
0
int
ethtool_client_getlink(clicon_handle h, char *ifname, uint8_t *link)
{
    int               retval = -1;
    char             *ret;
    uint16_t          len;
    struct clicon_msg *msg;
    char              *s;

    msg = clicon_msg_call_encode(0, "ethtool", "ethtool_getlink", 
				strlen(ifname), ifname, __FUNCTION__);
    if (msg == NULL)
	goto done;
    if ((s = clicon_sock(h)) == NULL)
	goto done;
    if (clicon_rpc_connect(msg, s, (char **)&ret, &len, __FUNCTION__) < 0)
	goto done;

    *link = (uint8_t)*ret;
    retval = 0;
done:
    unchunk_group(__FUNCTION__);
    return retval;
}
示例#5
0
/*! Send internal netconf rpc from client to backend
 * @param[in]    h      CLICON handle
 * @param[in]    msg    Encoded message. Deallocate woth free
 * @param[out]   xret   Return value from backend as xml tree. Free w xml_free
 * @param[inout] sock0  If pointer exists, do not close socket to backend on success 
 *                      and return it here. For keeping a notify socket open
 * @note sock0 is if connection should be persistent, like a notification/subscribe api
 * @note xret is populated with yangspec according to standard handle yangspec
 */
int
clicon_rpc_msg(clicon_handle      h, 
	       struct clicon_msg *msg, 
	       cxobj            **xret0,
	       int               *sock0)
{
    int                retval = -1;
    char              *sock;
    int                port;
    char              *retdata = NULL;
    cxobj             *xret = NULL;
    yang_stmt         *yspec;

#ifdef RPC_USERNAME_ASSERT
    assert(strstr(msg->op_body, "username")!=NULL); /* XXX */
#endif
    clicon_debug(1, "%s request:%s", __FUNCTION__, msg->op_body);
    if ((sock = clicon_sock(h)) == NULL){
	clicon_err(OE_FATAL, 0, "CLICON_SOCK option not set");
	goto done;
    }
    /* What to do if inet socket? */
    switch (clicon_sock_family(h)){
    case AF_UNIX:
	if (clicon_rpc_connect_unix(msg, sock, &retdata, sock0) < 0){
#if 0
	    if (errno == ESHUTDOWN)
		/* Maybe could reconnect on a higher layer, but lets fail
		   loud and proud */
		cligen_exiting_set(cli_cligen(h), 1);
#endif
	    goto done;
	}
	break;
    case AF_INET:
	if ((port = clicon_sock_port(h)) < 0){
	    clicon_err(OE_FATAL, 0, "CLICON_SOCK option not set");
	    goto done;
	}
	if (port < 0){
	    clicon_err(OE_FATAL, 0, "CLICON_SOCK_PORT not set");
	    goto done;
	}
	if (clicon_rpc_connect_inet(msg, sock, port, &retdata, sock0) < 0)
	    goto done;
	break;
    }
    clicon_debug(1, "%s retdata:%s", __FUNCTION__, retdata);

    if (retdata){
 	yspec = clicon_dbspec_yang(h);
	if (xml_parse_string(retdata, yspec, &xret) < 0)
	    goto done;
    }
    if (xret0){
	*xret0 = xret;
	xret = NULL;
    }
    retval = 0;
 done:
    if (retdata)
	free(retdata);
    if (xret)
	xml_free(xret);
    return retval;
}