static PyObject* set_primary(PyObject* dummy, PyObject* args) { PyObject* ret = 0; int fd; int l; int assoc_id; char* addr; struct sctp_prim ssp; int port; if (! PyArg_ParseTuple(args, "ii(si)", &fd, &assoc_id, &addr, &port)) { return ret; } bzero(&ssp, sizeof(ssp)); ssp.ssp_assoc_id = assoc_id; if (! to_sockaddr(addr, port, (struct sockaddr*) &(ssp.ssp_addr), &l)) { PyErr_SetString(PyExc_ValueError, "Invalid address"); return ret; } if (setsockopt(fd, SOL_SCTP, SCTP_PRIMARY_ADDR, &ssp, sizeof(ssp))) { PyErr_SetFromErrno(PyExc_IOError); } else { ret = Py_None; Py_INCREF(ret); } return ret; }
static bool session_from_linkaddr(const struct sol_network_link_addr *addr, session_t *session) { memset(session, 0, sizeof(*session)); session->size = sizeof(session->addr); return to_sockaddr(addr, &session->addr.sa, &session->size) >= 0; }
static PyObject* get_paddrparams(PyObject* dummy, PyObject* args) { PyObject* ret = 0; PyObject* dict; PyObject* oassoc_id; PyObject *oaddresstuple; const char* address; int port; int fd; int slen_dummy; struct sctp_paddrparams v; socklen_t lv = sizeof(v); int ok; ok = PyArg_ParseTuple(args, "iO", &fd, &dict) && PyDict_Check(dict); ok = ok && (oassoc_id = PyDict_GetItemString(dict, "assoc_id")); ok = ok && (oaddresstuple = PyDict_GetItemString(dict, "sockaddr")); ok = ok && PyArg_ParseTuple(oaddresstuple, "si", &address, &port); ok = ok && PyInt_Check(oassoc_id); if (! ok) { return ret; } bzero(&v, sizeof(v)); v.spp_assoc_id = PyInt_AsLong(oassoc_id); if (! to_sockaddr(address, port, (struct sockaddr*) &(v.spp_address), &slen_dummy)) { PyErr_SetString(PyExc_ValueError, "address could not be translated"); return ret; } if (getsockopt(fd, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &v, &lv)) { PyErr_SetFromErrno(PyExc_IOError); } else { PyDict_SetItemString(dict, "hbinterval", PyInt_FromLong(v.spp_hbinterval)); PyDict_SetItemString(dict, "pathmaxrxt", PyInt_FromLong(v.spp_pathmaxrxt)); #ifdef SCTP_DRAFT10_LEVEL PyDict_SetItemString(dict, "pathmtu", PyInt_FromLong(v.spp_pathmtu)); PyDict_SetItemString(dict, "sackdelay", PyInt_FromLong(v.spp_sackdelay)); PyDict_SetItemString(dict, "flags", PyInt_FromLong(v.spp_flags)); #endif ret = Py_None; Py_INCREF(ret); } return ret; }
static PyObject* sctp_send_msg(PyObject* dummy, PyObject* args) { int fd, msg_len, size_sent, ppid, flags, stream, ttl, context; const char *msg; char *to; int port; struct sockaddr_storage sto; struct sockaddr_storage *psto = &sto; int sto_len; PyObject *ret = 0; if (! PyArg_ParseTuple(args, "is#(si)iiiii", &fd, &msg, &msg_len, &to, &port, &ppid, &flags, &stream, &ttl, &context)) { return ret; } if (msg_len <= 0 && (! (flags & MSG_EOF))) { PyErr_SetString(PyExc_ValueError, "Empty messages are not allowed, except if coupled with the MSG_EOF flag."); return ret; } // TODO: "to" can contain and assoc_id. For this to be possible, we will need to // use bare sendmsg() instead of sctp_sendmsg(). if (strlen(to) == 0) { // special case: should pass NULL sto_len = 0; psto = 0; } else { if (! to_sockaddr(to, port, (struct sockaddr*) psto, &sto_len)) { PyErr_SetString(PyExc_ValueError, "Invalid Address"); return ret; } } size_sent = sctp_sendmsg(fd, msg, msg_len, (struct sockaddr*) psto, sto_len, ppid, flags, stream, ttl, context); if (size_sent < 0) { PyErr_SetFromErrno(PyExc_IOError); return ret; } ret = PyInt_FromLong(size_sent); return ret; }
static PyObject* get_paddrinfo(PyObject* dummy, PyObject* args) { PyObject* ret = 0; PyObject* dict; PyObject* oassoc_id; PyObject* oaddresstuple; const char* address; int port; int fd; int slen_dummy; struct sctp_paddrinfo v; socklen_t lv = sizeof(v); int ok; ok = PyArg_ParseTuple(args, "iO", &fd, &dict) && PyDict_Check(dict); ok = ok && (oassoc_id = PyDict_GetItemString(dict, "assoc_id")); ok = ok && (oaddresstuple = PyDict_GetItemString(dict, "sockaddr")); ok = ok && PyInt_Check(oassoc_id); ok = ok && PyArg_ParseTuple(oaddresstuple, "si", &address, &port); if (! ok) { return ret; } bzero(&v, sizeof(v)); v.spinfo_assoc_id = PyInt_AsLong(oassoc_id); if (! to_sockaddr(address, port, (struct sockaddr*) &(v.spinfo_address), &slen_dummy)) { PyErr_SetString(PyExc_ValueError, "address could not be translated"); return ret; } if (getsockopt(fd, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO, &v, &lv)) { PyErr_SetFromErrno(PyExc_IOError); } else { PyDict_SetItemString(dict, "state", PyInt_FromLong(v.spinfo_state)); PyDict_SetItemString(dict, "cwnd", PyInt_FromLong(v.spinfo_cwnd)); PyDict_SetItemString(dict, "srtt", PyInt_FromLong(v.spinfo_srtt)); PyDict_SetItemString(dict, "rto", PyInt_FromLong(v.spinfo_rto)); PyDict_SetItemString(dict, "mtu", PyInt_FromLong(v.spinfo_mtu)); ret = Py_None; Py_INCREF(ret); } return ret; }
static PyObject* _sockaddr_test(PyObject* dummy, PyObject* args) { PyObject* ret = 0; PyObject* addrtupleret = 0; char *caddr; int port; struct sockaddr_storage saddr; int slen; int family; char caddr2[256]; if (! PyArg_ParseTuple(args, "(si)", &caddr, &port)) { return ret; } printf("DEBUG: addr=%s, port=%d\n", caddr, port); if (! to_sockaddr(caddr, port, (struct sockaddr*) &saddr, &slen)) { PyErr_SetString(PyExc_ValueError, "address could not be translated"); return ret; } port = 0; caddr = 0; if (! from_sockaddr((struct sockaddr*) &saddr, &family, &slen, &port, caddr2, sizeof(caddr2))) { PyErr_SetString(PyExc_ValueError, "address could not be de-translated"); return ret; } ret = PyTuple_New(4); addrtupleret = PyTuple_New(2); PyTuple_SetItem(ret, 0, PyString_FromFormat("family %d, size %d, address %s.%d", family, slen, caddr2, port)); PyTuple_SetItem(ret, 1, PyInt_FromLong(family)); PyTuple_SetItem(ret, 2, PyInt_FromLong(slen)); PyTuple_SetItem(ret, 3, addrtupleret); PyTuple_SetItem(addrtupleret, 0, PyString_FromString(caddr2)); PyTuple_SetItem(addrtupleret, 1, PyInt_FromLong(port)); return ret; }
static PyObject* bindx(PyObject* dummy, PyObject* args) { PyObject* ret = 0; int fd; PyObject* addrs; struct sockaddr saddr; struct sockaddr* saddrs; int saddr_len, saddrs_len; int addrcount; int flags; int x; if (! PyArg_ParseTuple(args, "iOi", &fd, &addrs, &flags)) { return ret; } if (! PySequence_Check(addrs)) { PyErr_SetString(PyExc_ValueError, "Second parameter must be a sequence of address/port tuples"); return ret; } addrcount = PySequence_Length(addrs); if (addrcount <= 0) { PyErr_SetString(PyExc_ValueError, "Second parameter must be a non-empty sequence"); return ret; } saddrs_len = 0; saddrs = (struct sockaddr*) malloc(saddrs_len); for(x = 0; x < addrcount; ++x) { const char* caddr; int iport; PyObject* otuple = PySequence_GetItem(addrs, x); if (! PyArg_ParseTuple(otuple, "si", &caddr, &iport)) { free(saddrs); return ret; } if (! to_sockaddr(caddr, iport, &saddr, &saddr_len)) { PyErr_Format(PyExc_ValueError, "Invalid address: %s", caddr); free(saddrs); return ret; } if (saddr_len == 0) { PyErr_Format(PyExc_ValueError, "Invalid address family: %s", caddr); free(saddrs); return ret; } saddrs = realloc(saddrs, saddrs_len + saddr_len); memcpy( ((char*) saddrs) + saddrs_len, &saddr, saddr_len); saddrs_len += saddr_len; } if (sctp_bindx(fd, saddrs, addrcount, flags)) { PyErr_SetFromErrno(PyExc_IOError); } else { ret = Py_None; Py_INCREF(ret); } free(saddrs); return ret; }