예제 #1
0
static void ncSessionFree(ncSessionObject *self)
{
	PyObject *err_type, *err_value, *err_traceback;

	/* save the current exception state */
	PyErr_Fetch(&err_type, &err_value, &err_traceback);

	nc_session_free(self->session);

	/* restore the saved exception state */
	PyErr_Restore(err_type, err_value, err_traceback);

	Py_TYPE(self)->tp_free((PyObject*)self);
}
예제 #2
0
static int
teardown_write(void **state)
{
    struct wr *w = (struct wr *)*state;

    nc_rpc_free(w->rpc);
    w->session->ti.fd.in = -1;
    w->session->ti.fd.out = -1;
    nc_session_free(w->session);
    free(w);
    *state = NULL;

    return 0;
}
예제 #3
0
/* rpc parameter is freed after the function call */
static int op_send_recv(ncSessionObject *self, nc_rpc* rpc, char **data)
{
	nc_reply *reply = NULL;
	int ret = EXIT_SUCCESS;

	/* send the request and get the reply */
	switch (nc_session_send_recv(self->session, rpc, &reply)) {
	case NC_MSG_UNKNOWN:
		if (nc_session_get_status(self->session) != NC_SESSION_STATUS_WORKING) {
			PyErr_SetString(libnetconfError, "Session damaged, closing.");
			/* free the Session */
			nc_session_free(self->session);
			self->session = NULL;
		}
		ret = EXIT_FAILURE;
		break;
	case NC_MSG_NONE:
		/* error occurred, but processed by callback */
		break;
	case NC_MSG_REPLY:
		switch (nc_reply_get_type(reply)) {
		case NC_REPLY_OK:
			break;
		case NC_REPLY_DATA:
			if (data) {
				*data = nc_reply_get_data (reply);
			}
			break;
		case NC_REPLY_ERROR:
			ret = EXIT_FAILURE;
			break;
		default:
			PyErr_SetString(libnetconfError, "Unexpected operation result.");
			ret = EXIT_FAILURE;
			break;
		}
		break;
	default:
		PyErr_SetString(libnetconfError, "Unknown error occurred.");
		ret = EXIT_FAILURE;
		break;
	}
	nc_rpc_free(rpc);
	nc_reply_free(reply);

	return (ret);
}
예제 #4
0
void
__wrap_nc_ps_clear(struct nc_pollsession *ps, int all, void (*data_free)(void *))
{
    int i;

    if (!all) {
        fail();
    }

    for (i = 0; i < ps->session_count; ++i) {
        for (i = 0; i < ps->session_count; i++) {
            nc_session_free(ps->sessions[i], data_free);
        }
        free(ps->sessions);
        ps->sessions = NULL;
        free(ps->pfds);
        ps->pfds = NULL;
        ps->session_count = 0;
    }
}
예제 #5
0
static int ncSessionInit(ncSessionObject *self, PyObject *args, PyObject *keywords)
{
	const char *host = NULL, *user = NULL, *transport_s = NULL;
	unsigned short port = 830;
	PyObject *PyCpblts = NULL;
	PyObject *PyStr;
	struct nc_session *session;
	struct nc_cpblts *cpblts = NULL;
	char cpblts_free_flag = 0;
	char* item = NULL;
	Py_ssize_t l, i;
	int ret;
	int fd_in = -1, fd_out = -1;
	NC_TRANSPORT transport = NC_TRANSPORT_UNKNOWN;

	char *kwlist[] = {"host", "port", "user", "transport", "capabilities", "fd_in", "fd_out", NULL};

	/* Get input parameters */
	if (! PyArg_ParseTupleAndKeywords(args, keywords, "|zHzzOii", kwlist, &host, &port, &user, &transport_s, &PyCpblts, &fd_in, &fd_out)) {
		return -1;
	}

	if ((fd_in >= 0 && fd_out < 0) || (fd_in < 0 && fd_out >= 0)) {
		PyErr_SetString(PyExc_ValueError, "Both or none of fd_in and fd_out arguments must be set.");
		return -1;
	}

	if (host != NULL) {
		/* Client side */
		if (transport_s && strcasecmp(transport_s, NETCONF_TRANSPORT_TLS) == 0) {
			ret = nc_session_transport(NC_TRANSPORT_TLS);
			transport = NC_TRANSPORT_TLS;
		} else {
			ret = nc_session_transport(NC_TRANSPORT_SSH);
			transport = NC_TRANSPORT_SSH;
		}
		if (ret != EXIT_SUCCESS) {
			return -1;
		}
	}

	if (PyCpblts != NULL && PyCpblts != Py_None) {
		cpblts = nc_cpblts_new(NULL);
		cpblts_free_flag = 1;
		if (PyList_Check(PyCpblts)) {
			if ((l = PyList_Size(PyCpblts)) > 0) {
				for (i = 0; i < l; i++) {
					PyObject *PyUni = PyList_GetItem(PyCpblts, i);
					Py_INCREF(PyUni);
					if (!PyUnicode_Check(PyUni)) {
						PyErr_SetString(PyExc_TypeError, "Capabilities list must contain strings.");
						nc_cpblts_free(cpblts);
						Py_DECREF(PyUni);
						return -1;
					}
					PyStr = PyUnicode_AsEncodedString(PyUni, "UTF-8", NULL);
					Py_DECREF(PyUni);
					if (PyStr == NULL) {
						nc_cpblts_free(cpblts);
						return -1;
					}
					item = PyBytes_AsString(PyStr);
					if (item == NULL) {
						nc_cpblts_free(cpblts);
						Py_DECREF(PyStr);
						return -1;
					}
					ret = nc_cpblts_add(cpblts, item);
					Py_DECREF(PyStr);
					if (ret != EXIT_SUCCESS) {
						nc_cpblts_free(cpblts);
						return -1;
					}
				}
			}
		} else {
			PyErr_SetString(PyExc_TypeError, "Capabilities argument is expected to be a list of strings.");
			return -1;
		}
	}

	if (cpblts == NULL) {
		/* use global capabilities, that are, by default, same as libnetconf's
		 * default capabilities
		 */
		cpblts = global_cpblts;
	}

	if (host != NULL) {
		/* Client side */
		if (fd_in != -1 && fd_out != -1) {
			session = nc_session_connect_inout(fd_in, fd_out, cpblts,
					host, NULL, user, transport);
		} else {
			session = nc_session_connect(host, port, user, cpblts);
		}
	} else {
		/* Server side */
		session = nc_session_accept_inout(cpblts, user,
				fd_in != -1 ? fd_in : STDIN_FILENO,
				fd_out != -1 ? fd_out : STDOUT_FILENO);

		/* add to the list of monitored sessions */
		nc_session_monitor(session);
	}

	if (cpblts_free_flag) {
		nc_cpblts_free(cpblts);
	}

	if (session == NULL) {
		return -1;
	}

	nc_session_free(self->session);
	self->session = session;

	return 0;
}
예제 #6
0
static PyObject *ncProcessRPC(ncSessionObject *self)
{
	NC_MSG_TYPE ret;
	NC_RPC_TYPE req_type;
	NC_OP req_op;
	nc_rpc *rpc = NULL;
	nc_reply *reply = NULL;
	struct nc_err* e = NULL;

	SESSION_CHECK(self);

	/* receive incoming message */
	ret = nc_session_recv_rpc(self->session, -1, &rpc);
	if (ret != NC_MSG_RPC) {
		if (nc_session_get_status(self->session) != NC_SESSION_STATUS_WORKING) {
			/* something really bad happend, and communication is not possible anymore */
			nc_session_free(self->session);
			self->session = NULL;
		}
		Py_RETURN_NONE;
	}

	/* process it */
	req_type = nc_rpc_get_type(rpc);
	req_op = nc_rpc_get_op(rpc);
	if (req_type == NC_RPC_SESSION) {
		/* process operations affectinf session */
		switch(req_op) {
		case NC_OP_CLOSESESSION:
			/* exit the event loop immediately without processing any following request */
			reply = nc_reply_ok();
			break;
		case NC_OP_KILLSESSION:
			/* todo: kill the requested session */
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		default:
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		}
	} else if (req_type == NC_RPC_DATASTORE_READ) {
		/* process operations reading datastore */
		switch (req_op) {
		case NC_OP_GET:
		case NC_OP_GETCONFIG:
			reply = ncds_apply_rpc2all(self->session, rpc,  NULL);
			break;
		default:
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		}
	} else if (req_type == NC_RPC_DATASTORE_WRITE) {
		/* process operations affecting datastore */
		switch (req_op) {
		case NC_OP_LOCK:
		case NC_OP_UNLOCK:
		case NC_OP_COPYCONFIG:
		case NC_OP_DELETECONFIG:
		case NC_OP_EDITCONFIG:
			reply = ncds_apply_rpc2all(self->session, rpc, NULL);
			break;
		default:
			reply = nc_reply_error(nc_err_new(NC_ERR_OP_NOT_SUPPORTED));
			break;
		}
	} else {
		/* process other operations */
		reply = ncds_apply_rpc2all(self->session, rpc, NULL);
	}

	/* create reply */
	if (reply == NULL) {
		reply = nc_reply_error(nc_err_new(NC_ERR_OP_FAILED));
	} else if (reply == NCDS_RPC_NOT_APPLICABLE) {
		e = nc_err_new(NC_ERR_OP_FAILED);
		nc_err_set(e, NC_ERR_PARAM_MSG, "Requested operation cannot be performed on the managed datastore.");
		reply = nc_reply_error(e);
	}

	/* and send the reply to the client */
	nc_session_send_reply(self->session, rpc, reply);
	nc_rpc_free(rpc);
	nc_reply_free(reply);

	if (req_op == NC_OP_CLOSESESSION) {
		/* free the Session */
		nc_session_free(self->session);
		self->session = NULL;
	}

	Py_RETURN_NONE;
}
예제 #7
0
int main(int argc, char** argv)
{
	struct nc_session* dummy_session;
	struct nc_cpblts* capabs;
	struct ncds_ds* ds;
	nc_rpc* rpc;
	nc_reply* reply;
	char* new_startup_config;
	xmlDocPtr startup_doc = NULL;
	int ret = 0, i, j;

	if (argc < 2 || argv[1][0] == '-') {
		help(argv[0]);
		return 1;
	}

	/* set message printing callback */
	nc_callback_print(my_print);

	/* init libnetconf for messages  from transAPI function */
	if (nc_init(NC_INIT_ALL | NC_INIT_MULTILAYER) == -1) {
		my_print(NC_VERB_ERROR, "Could not initialize libnetconf.");
		return 1;
	}

	/* register the datastore */
	if ((ds = ncds_new(NCDS_TYPE_FILE, "./model/ietf-interfaces.yin", NULL)) == NULL) {
		nc_close();
		return 1;
	}

	/* add imports and augments */
	if (ncds_add_model("./model/ietf-yang-types.yin") != 0 || ncds_add_model("./model/ietf-inet-types.yin") != 0 ||
			ncds_add_model("./model/ietf-ip.yin") != 0) {
		nc_verb_error("Could not add import and augment models.");
		nc_close();
		return 1;
	}

	/* enable features */
	for (i = 2; i < argc; ++i) {
		if (strcmp(argv[i], "ipv4-non-contiguous-netmasks") == 0 || strcmp(argv[i], "ipv6-privacy-autoconf") == 0) {
			j = ncds_feature_enable("ietf-ip", argv[i]);
		} else {
			j = ncds_feature_enable("ietf-interfaces", argv[i]);
		}

		if (j != 0) {
			nc_verb_error("Could not enable feature \"%s\".", argv[i]);
			nc_close();
			return 1;
		}
	}

	/* set the path to the target file */
	if (ncds_file_set_path(ds, argv[1]) != 0) {
		nc_verb_error("Could not set \"%s\" to the datastore.", argv[1]);
		nc_close();
		return 1;
	}
	if (ncds_init(ds) < 0) {
		nc_verb_error("Failed to nitialize datastore.");
		nc_close();
		return 1;
	}
	if (ncds_consolidate() != 0) {
		nc_verb_error("Could not consolidate the datastore.");
		nc_close();
		return 1;
	}

	if (transapi_init(&startup_doc) != EXIT_SUCCESS) {
		nc_close();
		return 1;
	}

	if (startup_doc == NULL || startup_doc->children == NULL) {
		/* nothing to do */
		nc_close();
		return 0;
	}

	/* create the dummy session */
	capabs = nc_cpblts_new(capabilities);
	if ((dummy_session = nc_session_dummy("session0", "root", NULL, capabs)) == NULL) {
		nc_verb_error("Could not create a dummy session.");
		nc_close();
		return 1;
	}

	/* dump the new config */
	xmlDocDumpMemory(startup_doc, (xmlChar**)&new_startup_config, NULL);
	xmlFreeDoc(startup_doc);

	/* apply edit-config rpc on the datastore */
	if ((rpc = nc_rpc_editconfig(NC_DATASTORE_STARTUP, NC_DATASTORE_CONFIG, 0, 0, 0, new_startup_config)) == NULL) {
		nc_verb_error("Could not create edit-config RPC.");
		nc_close();
		return 1;
	}
	free(new_startup_config);
	reply = ncds_apply_rpc2all(dummy_session, rpc, NULL);
	if (nc_reply_get_type(reply) != NC_REPLY_OK) {
		nc_verb_error("Edit-config RPC failed.");
		nc_close();
		return 1;
	}

	nc_reply_free(reply);
	nc_rpc_free(rpc);
	nc_cpblts_free(capabs);
	nc_session_free(dummy_session);
	nc_close();
	return ret;
}