capi.i 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. %module capi
  2. %{
  3. #include <netlink/netlink.h>
  4. #include <netlink/types.h>
  5. #include <netlink/socket.h>
  6. #include <netlink/msg.h>
  7. #include <netlink/object.h>
  8. #include <netlink/cache.h>
  9. #include <netlink/attr.h>
  10. #include <net/if.h>
  11. #define DEBUG
  12. #include "utils.h"
  13. %}
  14. %include <stdint.i>
  15. %include <cstring.i>
  16. %include <cpointer.i>
  17. %inline %{
  18. struct nl_dump_params *alloc_dump_params(void)
  19. {
  20. struct nl_dump_params *dp;
  21. if (!(dp = calloc(1, sizeof(*dp))))
  22. return NULL;
  23. dp->dp_fd = stdout;
  24. return dp;
  25. }
  26. void free_dump_params(struct nl_dump_params *dp)
  27. {
  28. free(dp);
  29. }
  30. %};
  31. /* <netlink/types.h> */
  32. enum nl_dump_type {
  33. NL_DUMP_LINE, /**< Dump object briefly on one line */
  34. NL_DUMP_DETAILS, /**< Dump all attributes but no statistics */
  35. NL_DUMP_STATS, /**< Dump all attributes including statistics */
  36. __NL_DUMP_MAX,
  37. };
  38. struct nl_dump_params
  39. {
  40. /**
  41. * Specifies the type of dump that is requested.
  42. */
  43. enum nl_dump_type dp_type;
  44. /**
  45. * Specifies the number of whitespaces to be put in front
  46. * of every new line (indentation).
  47. */
  48. int dp_prefix;
  49. /**
  50. * Causes the cache index to be printed for each element.
  51. */
  52. int dp_print_index;
  53. /**
  54. * Causes each element to be prefixed with the message type.
  55. */
  56. int dp_dump_msgtype;
  57. /**
  58. * A callback invoked for output
  59. *
  60. * Passed arguments are:
  61. * - dumping parameters
  62. * - string to append to the output
  63. */
  64. void (*dp_cb)(struct nl_dump_params *, char *);
  65. /**
  66. * A callback invoked for every new line, can be used to
  67. * customize the indentation.
  68. *
  69. * Passed arguments are:
  70. * - dumping parameters
  71. * - line number starting from 0
  72. */
  73. void (*dp_nl_cb)(struct nl_dump_params *, int);
  74. /**
  75. * User data pointer, can be used to pass data to callbacks.
  76. */
  77. void *dp_data;
  78. /**
  79. * File descriptor the dumping output should go to
  80. */
  81. FILE * dp_fd;
  82. /**
  83. * Alternatively the output may be redirected into a buffer
  84. */
  85. char * dp_buf;
  86. /**
  87. * Length of the buffer dp_buf
  88. */
  89. size_t dp_buflen;
  90. /**
  91. * PRIVATE
  92. * Set if a dump was performed prior to the actual dump handler.
  93. */
  94. int dp_pre_dump;
  95. /**
  96. * PRIVATE
  97. * Owned by the current caller
  98. */
  99. int dp_ivar;
  100. unsigned int dp_line;
  101. };
  102. /* <net/if.h> */
  103. extern unsigned int if_nametoindex(const char *ifname);
  104. /* <netlink/errno.h> */
  105. extern const char *nl_geterror(int);
  106. /* <netlink/utils.h> */
  107. extern double nl_cancel_down_bytes(unsigned long long, char **);
  108. extern double nl_cancel_down_bits(unsigned long long, char **);
  109. %cstring_output_maxsize(char *buf, size_t len)
  110. extern int nl_rate2str(unsigned long long rate, int type, char *buf, size_t len);
  111. extern double nl_cancel_down_us(uint32_t, char **);
  112. extern long nl_size2int(const char *);
  113. %cstring_output_maxsize(char *buf, const size_t len)
  114. extern char *nl_size2str(const size_t, char *buf, const size_t len);
  115. extern long nl_prob2int(const char *);
  116. extern int nl_get_user_hz(void);
  117. extern uint32_t nl_us2ticks(uint32_t);
  118. extern uint32_t nl_ticks2us(uint32_t);
  119. extern int nl_str2msec(const char *, uint64_t *);
  120. %cstring_output_maxsize(char *buf, size_t len)
  121. extern char *nl_msec2str(uint64_t, char *buf, size_t len);
  122. %cstring_output_maxsize(char *buf, size_t len)
  123. extern char *nl_llproto2str(int, char *buf, size_t len);
  124. extern int nl_str2llproto(const char *);
  125. %cstring_output_maxsize(char *buf, size_t len)
  126. extern char *nl_ether_proto2str(int, char *buf, size_t len);
  127. extern int nl_str2ether_proto(const char *);
  128. %cstring_output_maxsize(char *buf, size_t len)
  129. extern char *nl_ip_proto2str(int, char *buf, size_t len);
  130. extern int nl_str2ip_proto(const char *);
  131. extern void nl_new_line(struct nl_dump_params *);
  132. extern void nl_dump(struct nl_dump_params *, const char *, ...);
  133. extern void nl_dump_line(struct nl_dump_params *, const char *, ...);
  134. /* <netlink/netlink.h> */
  135. extern struct nl_dump_params *alloc_dump_params(void);
  136. extern void free_dump_params(struct nl_dump_params *);
  137. extern int nl_connect(struct nl_sock *, int);
  138. extern void nl_close(struct nl_sock *);
  139. /* <netlink/socket.h> */
  140. extern struct nl_sock *nl_socket_alloc(void);
  141. extern struct nl_sock *nl_socket_alloc_cb(struct nl_cb *);
  142. extern void nl_socket_free(struct nl_sock *);
  143. extern uint32_t nl_socket_get_local_port(const struct nl_sock *);
  144. extern void nl_socket_set_local_port(struct nl_sock *, uint32_t);
  145. extern uint32_t nl_socket_get_peer_port(const struct nl_sock *);
  146. extern void nl_socket_set_peer_port(struct nl_sock *, uint32_t);
  147. extern uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk);
  148. extern void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups);
  149. extern int nl_socket_set_buffer_size(struct nl_sock *, int, int);
  150. extern void nl_socket_set_cb(struct nl_sock *, struct nl_cb *);
  151. extern int nl_send_auto_complete(struct nl_sock *, struct nl_msg *);
  152. extern int nl_recvmsgs(struct nl_sock *, struct nl_cb *);
  153. /* <netlink/msg.h> */
  154. extern int nlmsg_size(int);
  155. extern int nlmsg_total_size(int);
  156. extern int nlmsg_padlen(int);
  157. extern void * nlmsg_data(const struct nlmsghdr *);
  158. extern int nlmsg_datalen(const struct nlmsghdr *);
  159. extern void * nlmsg_tail(const struct nlmsghdr *);
  160. /* attribute access */
  161. extern struct nlattr * nlmsg_attrdata(const struct nlmsghdr *, int);
  162. extern int nlmsg_attrlen(const struct nlmsghdr *, int);
  163. /* message parsing */
  164. extern int nlmsg_valid_hdr(const struct nlmsghdr *, int);
  165. extern int nlmsg_ok(const struct nlmsghdr *, int);
  166. extern struct nlmsghdr * nlmsg_next(struct nlmsghdr *, int *);
  167. extern int nlmsg_parse(struct nlmsghdr *, int, struct nlattr **,
  168. int, struct nla_policy *);
  169. extern struct nlattr * nlmsg_find_attr(struct nlmsghdr *, int, int);
  170. extern int nlmsg_validate(struct nlmsghdr *, int, int,
  171. struct nla_policy *);
  172. extern struct nl_msg * nlmsg_alloc(void);
  173. extern struct nl_msg * nlmsg_alloc_size(size_t);
  174. extern struct nl_msg * nlmsg_alloc_simple(int, int);
  175. extern void nlmsg_set_default_size(size_t);
  176. extern struct nl_msg * nlmsg_inherit(struct nlmsghdr *);
  177. extern struct nl_msg * nlmsg_convert(struct nlmsghdr *);
  178. extern void * nlmsg_reserve(struct nl_msg *, size_t, int);
  179. extern int nlmsg_append(struct nl_msg *, void *, size_t, int);
  180. extern int nlmsg_expand(struct nl_msg *, size_t);
  181. extern struct nlmsghdr * nlmsg_put(struct nl_msg *, uint32_t, uint32_t,
  182. int, int, int);
  183. extern struct nlmsghdr * nlmsg_hdr(struct nl_msg *);
  184. extern void nlmsg_get(struct nl_msg *);
  185. extern void nlmsg_free(struct nl_msg *);
  186. /* attribute modification */
  187. extern void nlmsg_set_proto(struct nl_msg *, int);
  188. extern int nlmsg_get_proto(struct nl_msg *);
  189. extern size_t nlmsg_get_max_size(struct nl_msg *);
  190. extern void nlmsg_set_src(struct nl_msg *, struct sockaddr_nl *);
  191. extern struct sockaddr_nl *nlmsg_get_src(struct nl_msg *);
  192. extern void nlmsg_set_dst(struct nl_msg *, struct sockaddr_nl *);
  193. extern struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *);
  194. extern void nlmsg_set_creds(struct nl_msg *, struct ucred *);
  195. extern struct ucred * nlmsg_get_creds(struct nl_msg *);
  196. extern char * nl_nlmsgtype2str(int, char *, size_t);
  197. extern int nl_str2nlmsgtype(const char *);
  198. extern char * nl_nlmsg_flags2str(int, char *, size_t);
  199. extern int nl_msg_parse(struct nl_msg *,
  200. void (*cb)(struct nl_object *, void *),
  201. void *);
  202. extern void nl_msg_dump(struct nl_msg *, FILE *);
  203. %inline %{
  204. struct nl_object *cast_obj(void *obj)
  205. {
  206. return (struct nl_object *) obj;
  207. }
  208. struct nl_object *object_alloc_name(const char *name)
  209. {
  210. struct nl_object *obj;
  211. if (nl_object_alloc_name(name, &obj) < 0)
  212. return NULL;
  213. return obj;
  214. }
  215. %};
  216. extern struct nl_object *nl_object_alloc(struct nl_object_ops *);
  217. extern void nl_object_free(struct nl_object *);
  218. extern struct nl_object *nl_object_clone(struct nl_object *);
  219. extern void nl_object_get(struct nl_object *);
  220. extern void nl_object_put(struct nl_object *);
  221. extern int nl_object_shared(struct nl_object *);
  222. %cstring_output_maxsize(char *buf, size_t len)
  223. extern void nl_object_dump_buf(struct nl_object *, char *buf, size_t len);
  224. extern void nl_object_dump(struct nl_object *, struct nl_dump_params *);
  225. extern int nl_object_identical(struct nl_object *, struct nl_object *);
  226. extern uint32_t nl_object_diff(struct nl_object *, struct nl_object *);
  227. extern int nl_object_match_filter(struct nl_object *, struct nl_object *);
  228. %cstring_output_maxsize(char *buf, size_t len)
  229. extern char *nl_object_attrs2str(struct nl_object *, uint32_t, char *buf, size_t len);
  230. %cstring_output_maxsize(char *buf, size_t len)
  231. extern char *nl_object_attr_list(struct nl_object *, char *buf, size_t len);
  232. extern void nl_object_mark(struct nl_object *);
  233. extern void nl_object_unmark(struct nl_object *);
  234. extern int nl_object_is_marked(struct nl_object *);
  235. extern int nl_object_get_refcnt(struct nl_object *);
  236. /* <netlink/cache.h> */
  237. typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *);
  238. %inline %{
  239. struct nl_cache *alloc_cache_name(const char *name)
  240. {
  241. struct nl_cache *c;
  242. if (nl_cache_alloc_name(name, &c) < 0)
  243. return NULL;
  244. return c;
  245. }
  246. struct nl_cache_mngr *alloc_cache_mngr(struct nl_sock *sock,
  247. int protocol, int flags)
  248. {
  249. struct nl_cache_mngr *mngr;
  250. if (nl_cache_mngr_alloc(sock, protocol, flags, &mngr) < 0)
  251. return NULL;
  252. return mngr;
  253. }
  254. struct nl_cache *cache_mngr_add(struct nl_cache_mngr *mngr,
  255. const char *name, change_func_t func,
  256. void *arg)
  257. {
  258. struct nl_cache *cache;
  259. if (nl_cache_mngr_add(mngr, name, func, arg, &cache) < 0)
  260. return NULL;
  261. return cache;
  262. }
  263. %}
  264. /* Access Functions */
  265. extern int nl_cache_nitems(struct nl_cache *);
  266. extern int nl_cache_nitems_filter(struct nl_cache *,
  267. struct nl_object *);
  268. extern struct nl_cache_ops * nl_cache_get_ops(struct nl_cache *);
  269. extern struct nl_object * nl_cache_get_first(struct nl_cache *);
  270. extern struct nl_object * nl_cache_get_last(struct nl_cache *);
  271. extern struct nl_object * nl_cache_get_next(struct nl_object *);
  272. extern struct nl_object * nl_cache_get_prev(struct nl_object *);
  273. extern struct nl_cache * nl_cache_alloc(struct nl_cache_ops *);
  274. extern struct nl_cache * nl_cache_subset(struct nl_cache *,
  275. struct nl_object *);
  276. extern void nl_cache_clear(struct nl_cache *);
  277. extern void nl_cache_free(struct nl_cache *);
  278. /* Cache modification */
  279. extern int nl_cache_add(struct nl_cache *,
  280. struct nl_object *);
  281. extern int nl_cache_parse_and_add(struct nl_cache *,
  282. struct nl_msg *);
  283. extern void nl_cache_remove(struct nl_object *);
  284. extern int nl_cache_refill(struct nl_sock *,
  285. struct nl_cache *);
  286. extern int nl_cache_pickup(struct nl_sock *,
  287. struct nl_cache *);
  288. extern int nl_cache_resync(struct nl_sock *,
  289. struct nl_cache *,
  290. change_func_t,
  291. void *);
  292. extern int nl_cache_include(struct nl_cache *,
  293. struct nl_object *,
  294. change_func_t,
  295. void *);
  296. extern void nl_cache_set_arg1(struct nl_cache *, int);
  297. extern void nl_cache_set_arg2(struct nl_cache *, int);
  298. /* General */
  299. extern int nl_cache_is_empty(struct nl_cache *);
  300. extern struct nl_object * nl_cache_search(struct nl_cache *,
  301. struct nl_object *);
  302. extern void nl_cache_mark_all(struct nl_cache *);
  303. /* Dumping */
  304. extern void nl_cache_dump(struct nl_cache *,
  305. struct nl_dump_params *);
  306. extern void nl_cache_dump_filter(struct nl_cache *,
  307. struct nl_dump_params *,
  308. struct nl_object *);
  309. /* Iterators */
  310. extern void nl_cache_foreach(struct nl_cache *,
  311. void (*cb)(struct nl_object *,
  312. void *),
  313. void *arg);
  314. extern void nl_cache_foreach_filter(struct nl_cache *,
  315. struct nl_object *,
  316. void (*cb)(struct
  317. nl_object *,
  318. void *),
  319. void *arg);
  320. /* --- cache management --- */
  321. /* Cache type management */
  322. extern struct nl_cache_ops * nl_cache_ops_lookup(const char *);
  323. extern struct nl_cache_ops * nl_cache_ops_associate(int, int);
  324. extern struct nl_msgtype * nl_msgtype_lookup(struct nl_cache_ops *, int);
  325. extern void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *);
  326. extern int nl_cache_mngt_register(struct nl_cache_ops *);
  327. extern int nl_cache_mngt_unregister(struct nl_cache_ops *);
  328. /* Global cache provisioning/requiring */
  329. extern void nl_cache_mngt_provide(struct nl_cache *);
  330. extern void nl_cache_mngt_unprovide(struct nl_cache *);
  331. extern struct nl_cache * nl_cache_mngt_require(const char *);
  332. struct nl_cache_mngr;
  333. #define NL_AUTO_PROVIDE 1
  334. extern int nl_cache_mngr_get_fd(struct nl_cache_mngr *);
  335. extern int nl_cache_mngr_poll(struct nl_cache_mngr *,
  336. int);
  337. extern int nl_cache_mngr_data_ready(struct nl_cache_mngr *);
  338. extern void nl_cache_mngr_free(struct nl_cache_mngr *);
  339. /* <netlink/addr.h> */
  340. %inline %{
  341. struct nl_addr *addr_parse(const char *addr, int guess)
  342. {
  343. struct nl_addr *result;
  344. if (nl_addr_parse(addr, guess, &result) < 0)
  345. return NULL;
  346. return result;
  347. }
  348. %};
  349. extern struct nl_addr *nl_addr_alloc(size_t);
  350. extern struct nl_addr *nl_addr_alloc_attr(struct nlattr *, int);
  351. extern struct nl_addr *nl_addr_build(int, void *, size_t);
  352. extern struct nl_addr *nl_addr_clone(struct nl_addr *);
  353. extern struct nl_addr *nl_addr_get(struct nl_addr *);
  354. extern void nl_addr_put(struct nl_addr *);
  355. extern int nl_addr_shared(struct nl_addr *);
  356. extern int nl_addr_cmp(struct nl_addr *, struct nl_addr *);
  357. extern int nl_addr_cmp_prefix(struct nl_addr *, struct nl_addr *);
  358. extern int nl_addr_iszero(struct nl_addr *);
  359. extern int nl_addr_valid(char *, int);
  360. extern int nl_addr_guess_family(struct nl_addr *);
  361. extern int nl_addr_fill_sockaddr(struct nl_addr *, struct sockaddr *, socklen_t *);
  362. extern int nl_addr_info(struct nl_addr *, struct addrinfo **);
  363. extern int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen);
  364. extern void nl_addr_set_family(struct nl_addr *, int);
  365. extern int nl_addr_get_family(struct nl_addr *);
  366. extern int nl_addr_set_binary_addr(struct nl_addr *, void *, size_t);
  367. extern void *nl_addr_get_binary_addr(struct nl_addr *);
  368. extern unsigned int nl_addr_get_len(struct nl_addr *);
  369. extern void nl_addr_set_prefixlen(struct nl_addr *, int);
  370. extern unsigned int nl_addr_get_prefixlen(struct nl_addr *);
  371. %cstring_output_maxsize(char *buf, size_t len)
  372. extern char *nl_af2str(int, char *buf, size_t len);
  373. extern int nl_str2af(const char *);
  374. %cstring_output_maxsize(char *buf, size_t len)
  375. extern char *nl_addr2str(struct nl_addr *, char *buf, size_t len);
  376. /* Message Handlers <netlink/handlers.h> */
  377. /**
  378. * Callback actions
  379. * @ingroup cb
  380. */
  381. enum nl_cb_action {
  382. /** Proceed with wathever would come next */
  383. NL_OK,
  384. /** Skip this message */
  385. NL_SKIP,
  386. /** Stop parsing altogether and discard remaining messages */
  387. NL_STOP,
  388. };
  389. /**
  390. * Callback kinds
  391. * @ingroup cb
  392. */
  393. enum nl_cb_kind {
  394. /** Default handlers (quiet) */
  395. NL_CB_DEFAULT,
  396. /** Verbose default handlers (error messages printed) */
  397. NL_CB_VERBOSE,
  398. /** Debug handlers for debugging */
  399. NL_CB_DEBUG,
  400. /** Customized handler specified by the user */
  401. NL_CB_CUSTOM,
  402. __NL_CB_KIND_MAX,
  403. };
  404. #define NL_CB_KIND_MAX (__NL_CB_KIND_MAX - 1)
  405. /**
  406. * Callback types
  407. * @ingroup cb
  408. */
  409. enum nl_cb_type {
  410. /** Message is valid */
  411. NL_CB_VALID,
  412. /** Last message in a series of multi part messages received */
  413. NL_CB_FINISH,
  414. /** Report received that data was lost */
  415. NL_CB_OVERRUN,
  416. /** Message wants to be skipped */
  417. NL_CB_SKIPPED,
  418. /** Message is an acknowledge */
  419. NL_CB_ACK,
  420. /** Called for every message received */
  421. NL_CB_MSG_IN,
  422. /** Called for every message sent out except for nl_sendto() */
  423. NL_CB_MSG_OUT,
  424. /** Message is malformed and invalid */
  425. NL_CB_INVALID,
  426. /** Called instead of internal sequence number checking */
  427. NL_CB_SEQ_CHECK,
  428. /** Sending of an acknowledge message has been requested */
  429. NL_CB_SEND_ACK,
  430. /** Flag NLM_F_DUMP_INTR is set in message */
  431. NL_CB_DUMP_INTR,
  432. __NL_CB_TYPE_MAX,
  433. };
  434. #define NL_CB_TYPE_MAX (__NL_CB_TYPE_MAX - 1)
  435. extern struct nl_cb *nl_cb_alloc(enum nl_cb_kind);
  436. extern struct nl_cb *nl_cb_clone(struct nl_cb *);
  437. struct nlmsgerr {
  438. int error;
  439. };
  440. %{
  441. struct pynl_callback {
  442. PyObject *cbf;
  443. PyObject *cba;
  444. };
  445. struct pynl_cbinfo {
  446. struct nl_cb *cb;
  447. struct pynl_callback cbtype[NL_CB_TYPE_MAX+1];
  448. struct pynl_callback cberr;
  449. struct list_head list;
  450. };
  451. LIST_HEAD(callback_list);
  452. static struct pynl_cbinfo *pynl_find_cbinfo(struct nl_cb *cb, int unlink)
  453. {
  454. struct list_head *pos, *prev;
  455. struct pynl_cbinfo *info;
  456. list_for_each_safe(pos, prev, &callback_list) {
  457. info = container_of(pos, struct pynl_cbinfo, list);
  458. if (info->cb == cb) {
  459. if (unlink)
  460. list_del(pos, prev);
  461. pynl_dbg("cb=%p: found=%p\n", cb, info);
  462. return info;
  463. }
  464. }
  465. pynl_dbg("cb=%p: not found\n", cb);
  466. return NULL;
  467. }
  468. static struct pynl_cbinfo *pynl_get_cbinfo(struct nl_cb *cb, int unlink)
  469. {
  470. struct pynl_cbinfo *info;
  471. info = pynl_find_cbinfo(cb, unlink);
  472. if (info || unlink) {
  473. /* found or no need to allocate a new one */
  474. pynl_dbg("cb=%p: done\n", cb);
  475. return info;
  476. }
  477. info = calloc(1, sizeof(*info));
  478. info->cb = cb;
  479. list_add(&info->list, &callback_list);
  480. pynl_dbg("cb=%p: added %p\n", cb, info);
  481. return info;
  482. }
  483. static int nl_recv_msg_handler(struct nl_msg *msg, void *arg)
  484. {
  485. struct pynl_callback *cbd = arg;
  486. PyObject *msgobj;
  487. PyObject *cbparobj;
  488. PyObject *resobj;
  489. PyObject *funcobj;
  490. int result;
  491. if (!cbd) {
  492. result = NL_STOP;
  493. goto done;
  494. }
  495. msgobj = SWIG_NewPointerObj(SWIG_as_voidptr(msg),
  496. SWIGTYPE_p_nl_msg, 0 | 0 );
  497. /* add selfobj if callback is a method */
  498. if (cbd->cbf && PyMethod_Check(cbd->cbf)) {
  499. PyObject *selfobj = PyMethod_Self(cbd->cbf);
  500. cbparobj = Py_BuildValue("(OOO)", selfobj ? selfobj : cbd->cba,
  501. msgobj, cbd->cba);
  502. funcobj = PyMethod_Function(cbd->cbf);
  503. pynl_dbg("callback %sbounded instance method %p\n",
  504. selfobj ? "" : "un", funcobj);
  505. } else {
  506. cbparobj = Py_BuildValue("(OO)", msgobj, cbd->cba);
  507. funcobj = cbd->cbf;
  508. pynl_dbg("callback function %p\n", funcobj);
  509. }
  510. resobj = PyObject_CallObject(funcobj, cbparobj);
  511. Py_DECREF(cbparobj);
  512. if (resobj && PyInt_Check(resobj))
  513. result = (int)PyInt_AsLong(resobj);
  514. else
  515. result = NL_STOP;
  516. Py_XDECREF(resobj);
  517. done:
  518. pynl_dbg("result=%d\n", result);
  519. return result;
  520. }
  521. static int nl_recv_err_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
  522. void *arg)
  523. {
  524. struct pynl_callback *cbd = arg;
  525. PyObject *errobj;
  526. PyObject *cbparobj;
  527. PyObject *resobj;
  528. PyObject *funcobj;
  529. int result;
  530. if (!cbd)
  531. return NL_STOP;
  532. errobj = SWIG_NewPointerObj(SWIG_as_voidptr(err),
  533. SWIGTYPE_p_nlmsgerr, 0 | 0 );
  534. /* add selfobj if callback is a method */
  535. if (cbd->cbf && PyMethod_Check(cbd->cbf)) {
  536. PyObject *selfobj = PyMethod_Self(cbd->cbf);
  537. cbparobj = Py_BuildValue("(OOO)", selfobj ? selfobj : cbd->cba,
  538. errobj, cbd->cba);
  539. funcobj = PyMethod_Function(cbd->cbf);
  540. } else {
  541. cbparobj = Py_BuildValue("(OO)", errobj, cbd->cba);
  542. funcobj = cbd->cbf;
  543. }
  544. resobj = PyObject_CallObject(funcobj, cbparobj);
  545. Py_DECREF(cbparobj);
  546. if (resobj && PyInt_Check(resobj))
  547. result = (int)PyInt_AsLong(resobj);
  548. else
  549. result = NL_STOP;
  550. Py_XDECREF(resobj);
  551. pynl_dbg("error: err=%d ret=%d\n", err->error, result);
  552. return result;
  553. }
  554. %}
  555. %inline %{
  556. struct nl_cb *py_nl_cb_clone(struct nl_cb *cb)
  557. {
  558. struct pynl_cbinfo *info, *clone_info;
  559. struct nl_cb *clone;
  560. int i;
  561. clone = nl_cb_clone(cb);
  562. info = pynl_find_cbinfo(cb, 0);
  563. if (info) {
  564. clone_info = pynl_get_cbinfo(clone, 0);
  565. /* increase refcnt to callback parameters and copy them */
  566. for (i = 0; info && i <= NL_CB_TYPE_MAX; i++) {
  567. Py_XINCREF(info->cbtype[i].cbf);
  568. Py_XINCREF(info->cbtype[i].cba);
  569. clone_info->cbtype[i].cbf = info->cbtype[i].cbf;
  570. clone_info->cbtype[i].cba = info->cbtype[i].cba;
  571. }
  572. Py_XINCREF(info->cberr.cbf);
  573. Py_XINCREF(info->cberr.cba);
  574. clone_info->cberr.cbf = info->cberr.cbf;
  575. clone_info->cberr.cba = info->cberr.cba;
  576. }
  577. return clone;
  578. }
  579. void py_nl_cb_put(struct nl_cb *cb)
  580. {
  581. struct pynl_cbinfo *info;
  582. int i;
  583. /* obtain callback info (and unlink) */
  584. info = pynl_get_cbinfo(cb, 1);
  585. pynl_dbg("cb=%p, info=%p\n", cb, info);
  586. /* decrease refcnt for callback type handlers */
  587. for (i = 0; info && i <= NL_CB_TYPE_MAX; i++) {
  588. Py_XDECREF(info->cbtype[i].cbf);
  589. Py_XDECREF(info->cbtype[i].cba);
  590. }
  591. /* decrease refcnt for error handler and free callback info */
  592. if (info) {
  593. Py_XDECREF(info->cberr.cbf);
  594. Py_XDECREF(info->cberr.cba);
  595. free(info);
  596. }
  597. nl_cb_put(cb);
  598. }
  599. int py_nl_cb_set(struct nl_cb *cb, enum nl_cb_type t, enum nl_cb_kind k,
  600. PyObject *func, PyObject *a)
  601. {
  602. struct pynl_cbinfo *info;
  603. /* obtain callback info */
  604. info = pynl_get_cbinfo(cb, 0);
  605. /* clear existing handlers (if any) */
  606. Py_XDECREF(info->cbtype[t].cbf);
  607. Py_XDECREF(info->cbtype[t].cba);
  608. info->cbtype[t].cbf = NULL;
  609. info->cbtype[t].cba = NULL;
  610. pynl_dbg("cb=%p, info=%p, type=%d, kind=%d\n", cb, info, t, k);
  611. /* handle custom callback */
  612. if (k == NL_CB_CUSTOM) {
  613. Py_XINCREF(func);
  614. Py_XINCREF(a);
  615. info->cbtype[t].cbf = func;
  616. info->cbtype[t].cba = a;
  617. return nl_cb_set(cb, t, k,
  618. nl_recv_msg_handler, &info->cbtype[t]);
  619. }
  620. return nl_cb_set(cb, t, k, NULL, NULL);
  621. }
  622. int py_nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind k,
  623. PyObject *func , PyObject *a)
  624. {
  625. struct pynl_cbinfo *info;
  626. int t;
  627. info = pynl_get_cbinfo(cb, 0);
  628. pynl_dbg("cb=%p, info=%p, kind=%d\n", cb, info, k);
  629. for (t = 0; t <= NL_CB_TYPE_MAX; t++) {
  630. /* (possibly) free existing handler */
  631. Py_XDECREF(info->cbtype[t].cbf);
  632. Py_XDECREF(info->cbtype[t].cba);
  633. info->cbtype[t].cbf = NULL;
  634. info->cbtype[t].cba = NULL;
  635. if (k == NL_CB_CUSTOM) {
  636. Py_XINCREF(func);
  637. Py_XINCREF(a);
  638. info->cbtype[t].cbf = func;
  639. info->cbtype[t].cba = a;
  640. }
  641. }
  642. if (k == NL_CB_CUSTOM)
  643. /* callback argument is same for all so using idx 0 here */
  644. return nl_cb_set_all(cb, k, nl_recv_msg_handler,
  645. &info->cbtype[0]);
  646. else
  647. return nl_cb_set_all(cb, k, NULL, NULL);
  648. }
  649. int py_nl_cb_err(struct nl_cb *cb, enum nl_cb_kind k,
  650. PyObject *func, PyObject *a)
  651. {
  652. struct pynl_cbinfo *info;
  653. /* obtain callback info */
  654. info = pynl_get_cbinfo(cb, 0);
  655. pynl_dbg("cb=%p, info=%p, kind=%d\n", cb, info, k);
  656. /* clear existing handlers (if any) */
  657. Py_XDECREF(info->cberr.cbf);
  658. Py_XDECREF(info->cberr.cba);
  659. info->cberr.cbf = NULL;
  660. info->cberr.cba = NULL;
  661. /* handle custom callback */
  662. if (k == NL_CB_CUSTOM) {
  663. Py_XINCREF(func);
  664. Py_XINCREF(a);
  665. info->cberr.cbf = func;
  666. info->cberr.cba = a;
  667. return nl_cb_err(cb, k,
  668. nl_recv_err_handler, &info->cberr);
  669. }
  670. return nl_cb_err(cb, k, NULL, NULL);
  671. }
  672. %}
  673. /* Attributes <netlink/attr.h> */
  674. /*
  675. * This typemap is a bit tricky as it uses arg1, which is knowledge about
  676. * the SWIGged wrapper output.
  677. */
  678. %typemap(out) void * {
  679. $result = PyByteArray_FromStringAndSize($1, nla_len(arg1));
  680. }
  681. extern void *nla_data(struct nlattr *);
  682. %typemap(out) void *;
  683. extern int nla_type(const struct nlattr *);
  684. /* Integer attribute */
  685. extern uint8_t nla_get_u8(struct nlattr *);
  686. extern int nla_put_u8(struct nl_msg *, int, uint8_t);
  687. extern uint16_t nla_get_u16(struct nlattr *);
  688. extern int nla_put_u16(struct nl_msg *, int, uint16_t);
  689. extern uint32_t nla_get_u32(struct nlattr *);
  690. extern int nla_put_u32(struct nl_msg *, int, uint32_t);
  691. extern uint64_t nla_get_u64(struct nlattr *);
  692. extern int nla_put_u64(struct nl_msg *, int, uint64_t);
  693. /* String attribute */
  694. extern char * nla_get_string(struct nlattr *);
  695. extern char * nla_strdup(struct nlattr *);
  696. extern int nla_put_string(struct nl_msg *, int, const char *);
  697. /* Flag attribute */
  698. extern int nla_get_flag(struct nlattr *);
  699. extern int nla_put_flag(struct nl_msg *, int);
  700. /* Msec attribute */
  701. extern unsigned long nla_get_msecs(struct nlattr *);
  702. extern int nla_put_msecs(struct nl_msg *, int, unsigned long);
  703. /* Attribute nesting */
  704. extern int nla_put_nested(struct nl_msg *, int, struct nl_msg *);
  705. extern struct nlattr * nla_nest_start(struct nl_msg *, int);
  706. extern int nla_nest_end(struct nl_msg *, struct nlattr *);
  707. %inline %{
  708. PyObject *py_nla_parse_nested(int max, struct nlattr *nest_attr, PyObject *p)
  709. {
  710. struct nlattr *tb_msg[max + 1];
  711. struct nla_policy *policy = NULL;
  712. void *pol;
  713. PyObject *attrs = Py_None;
  714. PyObject *k;
  715. PyObject *v;
  716. PyObject *resobj;
  717. int err;
  718. int i;
  719. if (p != Py_None) {
  720. PyObject *pobj;
  721. if (!PyList_Check(p)) {
  722. fprintf(stderr, "expected list object\n");
  723. err = -1;
  724. goto fail;
  725. }
  726. pobj = PyList_GetItem(p, 0);
  727. err = SWIG_ConvertPtr(pobj, &pol, SWIGTYPE_p_nla_policy, 0 | 0 );
  728. if (!SWIG_IsOK(err))
  729. goto fail;
  730. policy = pol;
  731. }
  732. err = nla_parse_nested(tb_msg, max, nest_attr, policy);
  733. if (err < 0) {
  734. fprintf(stderr, "Failed to parse response message\n");
  735. } else {
  736. attrs = PyDict_New();
  737. for (i = 0; i <= max; i++)
  738. if (tb_msg[i]) {
  739. k = PyInt_FromLong((long)i);
  740. v = SWIG_NewPointerObj(SWIG_as_voidptr(tb_msg[i]), SWIGTYPE_p_nlattr, 0 | 0 );
  741. PyDict_SetItem(attrs, k, v);
  742. }
  743. }
  744. fail:
  745. if (attrs == Py_None)
  746. Py_INCREF(attrs);
  747. resobj = Py_BuildValue("(iO)", err, attrs);
  748. return resobj;
  749. }
  750. /*
  751. * nla_get_nested() - get list of nested attributes.
  752. *
  753. * nla_for_each_<nested|attr>() is a macro construct that needs another approach
  754. * for Python. Create and return list of nested attributes.
  755. */
  756. PyObject *nla_get_nested(struct nlattr *nest_attr)
  757. {
  758. PyObject *listobj;
  759. PyObject *nestattrobj;
  760. struct nlattr *pos;
  761. int rem;
  762. listobj = PyList_New(0);
  763. nla_for_each_nested(pos, nest_attr, rem) {
  764. nestattrobj = SWIG_NewPointerObj(SWIG_as_voidptr(pos),
  765. SWIGTYPE_p_nlattr, 0 | 0 );
  766. PyList_Append(listobj, nestattrobj);
  767. }
  768. return listobj;
  769. }
  770. %}
  771. /**
  772. * @ingroup attr
  773. * Basic attribute data types
  774. *
  775. * See \ref attr_datatypes for more details.
  776. */
  777. enum {
  778. NLA_UNSPEC, /**< Unspecified type, binary data chunk */
  779. NLA_U8, /**< 8 bit integer */
  780. NLA_U16, /**< 16 bit integer */
  781. NLA_U32, /**< 32 bit integer */
  782. NLA_U64, /**< 64 bit integer */
  783. NLA_STRING, /**< NUL terminated character string */
  784. NLA_FLAG, /**< Flag */
  785. NLA_MSECS, /**< Micro seconds (64bit) */
  786. NLA_NESTED, /**< Nested attributes */
  787. __NLA_TYPE_MAX,
  788. };
  789. #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
  790. /** @} */
  791. /**
  792. * @ingroup attr
  793. * Attribute validation policy.
  794. *
  795. * See \ref attr_datatypes for more details.
  796. */
  797. struct nla_policy {
  798. /** Type of attribute or NLA_UNSPEC */
  799. uint16_t type;
  800. /** Minimal length of payload required */
  801. uint16_t minlen;
  802. /** Maximal length of payload allowed */
  803. uint16_t maxlen;
  804. };
  805. %inline %{
  806. PyObject *nla_policy_array(int n_items)
  807. {
  808. struct nla_policy *policies;
  809. PyObject *listobj;
  810. PyObject *polobj;
  811. int i;
  812. policies = calloc(n_items, sizeof(*policies));
  813. listobj = PyList_New(n_items);
  814. for (i = 0; i < n_items; i++) {
  815. polobj = SWIG_NewPointerObj(SWIG_as_voidptr(&policies[i]),
  816. SWIGTYPE_p_nla_policy, 0 | 0 );
  817. PyList_SetItem(listobj, i, polobj);
  818. }
  819. return listobj;
  820. }
  821. %}