3 * Python bindings for TIPC
4 * Alberto Bertogli (albertito@gmail.com)
6 * This is the low-level module, used by the python one to construct
12 #include <sys/types.h> /* socket defines */
13 #include <sys/socket.h> /* socket functions */
14 #include <stdlib.h> /* malloc() */
15 #include <stdint.h> /* uint32_t and friends */
16 #include <arpa/inet.h> /* htonls() and friends */
17 #include <string.h> /* memcpy() */
19 #include <linux/tipc.h> /* TIPC stuff */
23 * Internal useful functions
26 static int fill_sockaddr(struct sockaddr_tipc
*sa
, PyObject
*addr
)
28 unsigned int atype
, v1
, v2
, v3
;
29 unsigned int scope
= TIPC_CLUSTER_SCOPE
;
31 if (!PyArg_ParseTuple(addr
, "IIII|I;Invalid TIPC address format",
32 &atype
, &v1
, &v2
, &v3
, &scope
))
35 memset(sa
, 0, sizeof(struct sockaddr_tipc
));
41 if (atype
== TIPC_ADDR_NAMESEQ
) {
42 sa
->addr
.nameseq
.type
= v1
;
43 sa
->addr
.nameseq
.lower
= v2
;
44 sa
->addr
.nameseq
.upper
= v3
;
45 } else if (atype
== TIPC_ADDR_NAME
) {
46 sa
->addr
.name
.name
.type
= v1
;
47 sa
->addr
.name
.name
.instance
= v2
;
48 } else if (atype
== TIPC_ADDR_ID
) {
49 sa
->addr
.id
.node
= v1
;
52 /* Shouldn't happen */
53 PyErr_SetString(PyExc_TypeError
, "Invalid address type");
60 static PyObject
*sa_to_tuple(const struct sockaddr_tipc
*sa
)
62 if (sa
->addrtype
== TIPC_ADDR_NAMESEQ
) {
63 return Py_BuildValue("IIIII",
65 sa
->addr
.nameseq
.type
,
66 sa
->addr
.nameseq
.lower
,
67 sa
->addr
.nameseq
.upper
,
69 } else if (sa
->addrtype
== TIPC_ADDR_NAME
) {
70 return Py_BuildValue("IIIII",
72 sa
->addr
.name
.name
.type
,
73 sa
->addr
.name
.name
.instance
,
74 sa
->addr
.name
.name
.instance
,
76 } else if (sa
->addrtype
== TIPC_ADDR_ID
) {
77 return Py_BuildValue("IIIII",
84 /* Shouldn't happen */
85 PyErr_SetString(PyExc_TypeError
, "Invalid address type");
95 static PyObject
*tipc_socket(PyObject
*self
, PyObject
*args
)
99 if (!PyArg_ParseTuple(args
, "i:tipc_socket", &stype
)) {
103 Py_BEGIN_ALLOW_THREADS
104 fd
= socket(AF_TIPC
, stype
, 0);
107 return PyErr_SetFromErrno(PyExc_IOError
);
109 return PyLong_FromLong(fd
);
113 static PyObject
*tipc_bind(PyObject
*self
, PyObject
*args
)
116 struct sockaddr_tipc sa
;
119 if (!PyArg_ParseTuple(args
, "iO:tipc_bind", &fd
, &addr
))
122 if (!fill_sockaddr(&sa
, addr
))
125 Py_BEGIN_ALLOW_THREADS
126 rv
= bind(fd
, (struct sockaddr
*) &sa
, sizeof(sa
));
130 return PyErr_SetFromErrno(PyExc_IOError
);
132 return PyLong_FromLong(rv
);
136 static PyObject
*tipc_connect(PyObject
*self
, PyObject
*args
)
139 struct sockaddr_tipc sa
;
142 if (!PyArg_ParseTuple(args
, "iO:tipc_connect", &fd
, &addr
))
145 if (!fill_sockaddr(&sa
, addr
))
148 Py_BEGIN_ALLOW_THREADS
149 rv
= connect(fd
, (struct sockaddr
*) &sa
, sizeof(sa
));
153 return PyErr_SetFromErrno(PyExc_IOError
);
155 return PyLong_FromLong(rv
);
159 static PyObject
*tipc_accept(PyObject
*self
, PyObject
*args
)
162 struct sockaddr_tipc sa
;
163 socklen_t salen
= sizeof(sa
);
165 if (!PyArg_ParseTuple(args
, "i:tipc_accept", &fd
)) {
169 Py_BEGIN_ALLOW_THREADS
170 newfd
= accept(fd
, (struct sockaddr
*) &sa
, &salen
);
174 return PyErr_SetFromErrno(PyExc_IOError
);
175 return Py_BuildValue("iN", newfd
, sa_to_tuple(&sa
));
179 static PyObject
*tipc_sendto(PyObject
*self
, PyObject
*args
)
184 struct sockaddr_tipc sa
;
187 if (!PyArg_ParseTuple(args
, "is#O:tipc_sendto", &fd
, &buf
, &len
, &addr
))
190 if (!fill_sockaddr(&sa
, addr
))
193 Py_BEGIN_ALLOW_THREADS
194 rv
= sendto(fd
, buf
, len
, 0, (struct sockaddr
*) &sa
, sizeof(sa
));
198 return PyErr_SetFromErrno(PyExc_IOError
);
200 return PyLong_FromLong(rv
);
203 static PyObject
*tipc_recvfrom(PyObject
*self
, PyObject
*args
)
208 struct sockaddr_tipc sa
;
209 socklen_t salen
= sizeof(sa
);
213 if (!PyArg_ParseTuple(args
, "iI:tipc_recvfrom", &fd
, &maxlen
)) {
217 buf
= malloc(maxlen
);
219 return PyErr_NoMemory();
221 Py_BEGIN_ALLOW_THREADS
222 rv
= recvfrom(fd
, buf
, maxlen
, 0,
223 (struct sockaddr
*) &sa
, &salen
);
228 return PyErr_SetFromErrno(PyExc_IOError
);
231 str
= PyString_FromStringAndSize(buf
, rv
);
234 return Py_BuildValue("NN", str
, sa_to_tuple(&sa
));
237 static PyObject
*tipc_build_subscr(PyObject
*self
, PyObject
*args
)
239 int stype
, lower
, upper
;
240 uint32_t timeout
, filter
;
241 struct tipc_subscr subs
;
243 if (!PyArg_ParseTuple(args
, "IIIII:tipc_build_subscr",
244 &stype
, &lower
, &upper
, &timeout
, &filter
)) {
248 subs
.seq
.type
= stype
;
249 subs
.seq
.lower
= lower
;
250 subs
.seq
.upper
= upper
;
251 subs
.timeout
= timeout
;
252 subs
.filter
= filter
;
254 return PyString_FromStringAndSize((char *) &subs
,
258 static PyObject
*tipc_parse_event(PyObject
*self
, PyObject
*args
)
262 struct tipc_event
*event
;
264 if (!PyArg_ParseTuple(args
, "s#:tipc_parse_event",
269 /* Return None if the buffer looks strange */
270 if (len
< sizeof(event
))
271 return Py_BuildValue("");
273 event
= (struct tipc_event
*) buf
;
275 return Py_BuildValue("III(IIIII)",
289 static PyMethodDef pytipc_functions
[] = {
290 { "socket", (PyCFunction
) tipc_socket
, METH_VARARGS
, NULL
},
291 { "bind", (PyCFunction
) tipc_bind
, METH_VARARGS
, NULL
},
292 { "connect", (PyCFunction
) tipc_connect
, METH_VARARGS
, NULL
},
293 { "accept", (PyCFunction
) tipc_accept
, METH_VARARGS
, NULL
},
294 { "sendto", (PyCFunction
) tipc_sendto
, METH_VARARGS
, NULL
},
295 { "recvfrom", (PyCFunction
) tipc_recvfrom
, METH_VARARGS
, NULL
},
296 { "build_subscr", (PyCFunction
) tipc_build_subscr
, METH_VARARGS
, NULL
},
297 { "parse_event", (PyCFunction
) tipc_parse_event
, METH_VARARGS
, NULL
},
301 PyMODINIT_FUNC
inittipc_ll(void)
305 m
= Py_InitModule("tipc_ll", pytipc_functions
);
306 PyModule_AddIntConstant(m
, "AF_TIPC", AF_TIPC
);
309 PyModule_AddIntConstant(m
, "TIPC_ADDR_NAMESEQ", TIPC_ADDR_NAMESEQ
);
310 PyModule_AddIntConstant(m
, "TIPC_ADDR_NAME", TIPC_ADDR_NAME
);
311 PyModule_AddIntConstant(m
, "TIPC_ADDR_ID", TIPC_ADDR_ID
);
313 PyModule_AddIntConstant(m
, "TIPC_ZONE_SCOPE", TIPC_ZONE_SCOPE
);
314 PyModule_AddIntConstant(m
, "TIPC_CLUSTER_SCOPE", TIPC_CLUSTER_SCOPE
);
315 PyModule_AddIntConstant(m
, "TIPC_NODE_SCOPE", TIPC_NODE_SCOPE
);
318 /* for setsockopt() */
319 PyModule_AddIntConstant(m
, "SOL_TIPC", SOL_TIPC
);
320 PyModule_AddIntConstant(m
, "TIPC_IMPORTANCE", TIPC_IMPORTANCE
);
321 PyModule_AddIntConstant(m
, "TIPC_SRC_DROPPABLE", TIPC_SRC_DROPPABLE
);
322 PyModule_AddIntConstant(m
, "TIPC_DEST_DROPPABLE",
323 TIPC_DEST_DROPPABLE
);
324 PyModule_AddIntConstant(m
, "TIPC_CONN_TIMEOUT", TIPC_CONN_TIMEOUT
);
326 PyModule_AddIntConstant(m
, "TIPC_LOW_IMPORTANCE",
327 TIPC_LOW_IMPORTANCE
);
328 PyModule_AddIntConstant(m
, "TIPC_MEDIUM_IMPORTANCE",
329 TIPC_MEDIUM_IMPORTANCE
);
330 PyModule_AddIntConstant(m
, "TIPC_HIGH_IMPORTANCE",
331 TIPC_HIGH_IMPORTANCE
);
332 PyModule_AddIntConstant(m
, "TIPC_CRITICAL_IMPORTANCE",
333 TIPC_CRITICAL_IMPORTANCE
);
335 /* for subscriptions */
336 PyModule_AddIntConstant(m
, "TIPC_SUB_PORTS", TIPC_SUB_PORTS
);
337 PyModule_AddIntConstant(m
, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE
);
338 PyModule_AddIntConstant(m
, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL
);
339 PyModule_AddIntConstant(m
, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER
);
340 PyModule_AddIntConstant(m
, "TIPC_PUBLISHED", TIPC_PUBLISHED
);
341 PyModule_AddIntConstant(m
, "TIPC_WITHDRAWN", TIPC_WITHDRAWN
);
342 PyModule_AddIntConstant(m
, "TIPC_SUBSCR_TIMEOUT", TIPC_SUBSCR_TIMEOUT
);
343 PyModule_AddIntConstant(m
, "TIPC_CFG_SRV", TIPC_CFG_SRV
);
344 PyModule_AddIntConstant(m
, "TIPC_TOP_SRV", TIPC_TOP_SRV
);