kernel_netlink.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667
  1. /*
  2. Copyright 2007-2010 by Grégoire Henry, Julien Cristau and Juliusz Chroboczek
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <errno.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include <fcntl.h>
  25. #include <time.h>
  26. #include <sys/ioctl.h>
  27. #include <sys/socket.h>
  28. #include <netinet/in.h>
  29. #include <net/route.h>
  30. #include <net/if.h>
  31. #include <arpa/inet.h>
  32. #include <asm/types.h>
  33. #include <sys/socket.h>
  34. #include <linux/netlink.h>
  35. #include <linux/rtnetlink.h>
  36. #include <linux/fib_rules.h>
  37. #include <net/if_arp.h>
  38. /* From <linux/if_bridge.h> */
  39. #ifndef BRCTL_GET_BRIDGES
  40. #define BRCTL_GET_BRIDGES 1
  41. #endif
  42. #if(__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 5)
  43. #define RTA_TABLE 15
  44. #endif
  45. #include "babeld.h"
  46. #include "kernel.h"
  47. #include "util.h"
  48. #include "interface.h"
  49. #include "configuration.h"
  50. #ifndef MAX_INTERFACES
  51. #define MAX_INTERFACES 20
  52. #endif
  53. #define GET_PLEN(p, v4) (v4) ? (p) + 96 : (p)
  54. #define COPY_ADDR(d, rta, v4) \
  55. do { \
  56. if(UNLIKELY(RTA_PAYLOAD(rta) < (v4 ? 4 : 16))) { \
  57. fprintf(stderr, "truncated message."); \
  58. return -1; \
  59. } \
  60. if(v4) \
  61. v4tov6(d, RTA_DATA(rta)); \
  62. else \
  63. memcpy(d, RTA_DATA(rta), 16); \
  64. } while(0)
  65. int export_table = -1, import_tables[MAX_IMPORT_TABLES], import_table_count = 0;
  66. struct sysctl_setting {
  67. char *name;
  68. int want;
  69. int was;
  70. };
  71. #define NUM_SYSCTLS 4
  72. static struct sysctl_setting sysctl_settings[NUM_SYSCTLS] = {
  73. {"/proc/sys/net/ipv6/conf/all/forwarding", 1, -1},
  74. {"/proc/sys/net/ipv4/conf/all/forwarding", 1, -1},
  75. {"/proc/sys/net/ipv6/conf/all/accept_redirects", 0, -1},
  76. {"/proc/sys/net/ipv4/conf/all/rp_filter", 0, -1},
  77. };
  78. struct old_if {
  79. char *ifname;
  80. int rp_filter;
  81. };
  82. struct old_if old_if[MAX_INTERFACES];
  83. int num_old_if = 0;
  84. static int dgram_socket = -1;
  85. #ifndef ARPHRD_ETHER
  86. #warning ARPHRD_ETHER not defined, we might not support exotic link layers
  87. #define ARPHRD_ETHER 1
  88. #define NO_ARPHRD
  89. #endif
  90. static int filter_netlink(struct nlmsghdr *nh, struct kernel_filter *filter);
  91. /* Determine an interface's hardware address, in modified EUI-64 format */
  92. int
  93. if_eui64(char *ifname, int ifindex, unsigned char *eui)
  94. {
  95. int s, rc;
  96. struct ifreq ifr;
  97. s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
  98. if(s < 0) return -1;
  99. memset(&ifr, 0, sizeof(ifr));
  100. strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
  101. rc = ioctl(s, SIOCGIFHWADDR, &ifr);
  102. if(rc < 0) {
  103. int saved_errno = errno;
  104. close(s);
  105. errno = saved_errno;
  106. return -1;
  107. }
  108. close(s);
  109. switch(ifr.ifr_hwaddr.sa_family) {
  110. case ARPHRD_ETHER:
  111. #ifndef NO_ARPHRD
  112. case ARPHRD_FDDI:
  113. case ARPHRD_IEEE802_TR:
  114. case ARPHRD_IEEE802:
  115. #endif
  116. {
  117. unsigned char *mac;
  118. mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
  119. /* Check for null address and group and global bits */
  120. if(memcmp(mac, zeroes, 6) == 0 ||
  121. (mac[0] & 1) != 0 || (mac[0] & 2) != 0) {
  122. errno = ENOENT;
  123. return -1;
  124. }
  125. memcpy(eui, mac, 3);
  126. eui[3] = 0xFF;
  127. eui[4] = 0xFE;
  128. memcpy(eui + 5, mac + 3, 3);
  129. eui[0] ^= 2;
  130. return 1;
  131. }
  132. #ifndef NO_ARPHRD
  133. case ARPHRD_EUI64:
  134. case ARPHRD_IEEE1394:
  135. case ARPHRD_INFINIBAND: {
  136. unsigned char *mac;
  137. mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
  138. if(memcmp(mac, zeroes, 8) == 0 ||
  139. (mac[0] & 1) != 0 || (mac[0] & 2) != 0) {
  140. errno = ENOENT;
  141. return -1;
  142. }
  143. memcpy(eui, mac, 8);
  144. eui[0] ^= 2;
  145. return 1;
  146. }
  147. #endif
  148. default:
  149. errno = ENOENT;
  150. return -1;
  151. }
  152. }
  153. static int
  154. read_proc(char *filename)
  155. {
  156. char buf[100];
  157. int fd, rc;
  158. fd = open(filename, O_RDONLY);
  159. if(fd < 0)
  160. return -1;
  161. rc = read(fd, buf, 99);
  162. if(rc < 0) {
  163. int saved_errno = errno;
  164. close(fd);
  165. errno = saved_errno;
  166. return -1;
  167. }
  168. close(fd);
  169. if(rc == 0)
  170. return -1;
  171. buf[rc] = '\0';
  172. return atoi(buf);
  173. }
  174. static int
  175. write_proc(char *filename, int value)
  176. {
  177. char buf[100];
  178. int fd, rc, n;
  179. n = snprintf(buf, 100, "%d", value);
  180. fd = open(filename, O_WRONLY);
  181. if(fd < 0)
  182. return -1;
  183. rc = write(fd, buf, n);
  184. if(rc < n) {
  185. int saved_errno = errno;
  186. close(fd);
  187. errno = saved_errno;
  188. return -1;
  189. }
  190. close(fd);
  191. return 1;
  192. }
  193. struct netlink {
  194. unsigned short seqno;
  195. int sock;
  196. struct sockaddr_nl sockaddr;
  197. socklen_t socklen;
  198. };
  199. static struct netlink nl_command = { 0, -1, {0}, 0 };
  200. static struct netlink nl_listen = { 0, -1, {0}, 0 };
  201. static int nl_setup = 0;
  202. static int
  203. netlink_socket(struct netlink *nl, uint32_t groups)
  204. {
  205. int rc;
  206. int rcvsize = 512 * 1024;
  207. nl->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  208. if(nl->sock < 0)
  209. return -1;
  210. memset(&nl->sockaddr, 0, sizeof(nl->sockaddr));
  211. nl->sockaddr.nl_family = AF_NETLINK;
  212. nl->sockaddr.nl_groups = groups;
  213. nl->socklen = sizeof(nl->sockaddr);
  214. nl->seqno = time(NULL);
  215. rc = fcntl(nl->sock, F_GETFL, 0);
  216. if(rc < 0)
  217. goto fail;
  218. rc = fcntl(nl->sock, F_SETFL, (rc | O_NONBLOCK));
  219. if(rc < 0)
  220. goto fail;
  221. #ifdef SO_RCVBUFFORCE
  222. rc = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE,
  223. &rcvsize, sizeof(rcvsize));
  224. #else
  225. rc = -1;
  226. #endif
  227. if(rc < 0) {
  228. rc = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF,
  229. &rcvsize, sizeof(rcvsize));
  230. if(rc < 0) {
  231. perror("setsockopt(SO_RCVBUF)");
  232. }
  233. }
  234. rc = bind(nl->sock, (struct sockaddr *)&nl->sockaddr, nl->socklen);
  235. if(rc < 0)
  236. goto fail;
  237. rc = getsockname(nl->sock, (struct sockaddr *)&nl->sockaddr, &nl->socklen);
  238. if(rc < 0)
  239. goto fail;
  240. return 0;
  241. fail:
  242. {
  243. int saved_errno = errno;
  244. close(nl->sock);
  245. nl->sock = -1;
  246. errno = saved_errno;
  247. return -1;
  248. }
  249. }
  250. static int
  251. netlink_read(struct netlink *nl, struct netlink *nl_ignore, int answer,
  252. struct kernel_filter *filter)
  253. {
  254. /* 'answer' must be true when we just have send a request on 'nl_socket' */
  255. /* 'nl_ignore' is used in kernel_callback to ignore message originating */
  256. /* from 'nl_command' while reading 'nl_listen' */
  257. /* Return code : */
  258. /* -1 : error */
  259. /* 0 : success */
  260. int err;
  261. struct msghdr msg;
  262. struct sockaddr_nl nladdr;
  263. struct iovec iov;
  264. struct nlmsghdr *nh;
  265. int len;
  266. int done = 0;
  267. int skip = 0;
  268. char buf[8192];
  269. memset(&nladdr, 0, sizeof(nladdr));
  270. nladdr.nl_family = AF_NETLINK;
  271. memset(&msg, 0, sizeof(msg));
  272. msg.msg_name = &nladdr;
  273. msg.msg_namelen = sizeof(nladdr);
  274. msg.msg_iov = &iov;
  275. msg.msg_iovlen = 1;
  276. iov.iov_base = &buf;
  277. do {
  278. iov.iov_len = sizeof(buf);
  279. len = recvmsg(nl->sock, &msg, 0);
  280. if(len < 0 && (errno == EAGAIN || errno == EINTR)) {
  281. int rc;
  282. rc = wait_for_fd(0, nl->sock, 100);
  283. if(rc <= 0) {
  284. if(rc == 0)
  285. errno = EAGAIN;
  286. } else {
  287. len = recvmsg(nl->sock, &msg, 0);
  288. }
  289. }
  290. if(len < 0) {
  291. perror("netlink_read: recvmsg()");
  292. return -1;
  293. } else if(len == 0) {
  294. fprintf(stderr, "netlink_read: EOF\n");
  295. goto socket_error;
  296. } else if(msg.msg_namelen != nl->socklen) {
  297. fprintf(stderr,
  298. "netlink_read: unexpected sender address length (%d)\n",
  299. msg.msg_namelen);
  300. goto socket_error;
  301. } else if(nladdr.nl_pid != 0) {
  302. kdebugf("netlink_read: message not sent by kernel.\n");
  303. return -1;
  304. }
  305. kdebugf("Netlink message: ");
  306. for(nh = (struct nlmsghdr *)buf;
  307. NLMSG_OK(nh, len);
  308. nh = NLMSG_NEXT(nh, len)) {
  309. kdebugf("%s{seq:%d}", (nh->nlmsg_flags & NLM_F_MULTI) ? "[multi] " : "",
  310. nh->nlmsg_seq);
  311. if(!answer)
  312. done = 1;
  313. if(nl_ignore && nh->nlmsg_pid == nl_ignore->sockaddr.nl_pid) {
  314. kdebugf("(ignore), ");
  315. continue;
  316. } else if(answer && (nh->nlmsg_pid != nl->sockaddr.nl_pid ||
  317. nh->nlmsg_seq != nl->seqno)) {
  318. kdebugf("(wrong seqno %d %d /pid %d %d), ",
  319. nh->nlmsg_seq, nl->seqno,
  320. nh->nlmsg_pid, nl->sockaddr.nl_pid);
  321. continue;
  322. } else if(nh->nlmsg_type == NLMSG_DONE) {
  323. kdebugf("(done)\n");
  324. done = 1;
  325. break;
  326. } else if(nh->nlmsg_type == NLMSG_ERROR) {
  327. struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nh);
  328. if(err->error == 0) {
  329. kdebugf("(ACK)\n");
  330. return 0;
  331. } else {
  332. kdebugf("netlink_read: %s\n", strerror(-err->error));
  333. errno = -err->error;
  334. return -1;
  335. }
  336. } else if(skip) {
  337. kdebugf("(skip)");
  338. } if(filter) {
  339. kdebugf("(msg -> \"");
  340. err = filter_netlink(nh, filter);
  341. kdebugf("\" %d), ", err);
  342. if(err < 0) skip = 1;
  343. continue;
  344. }
  345. kdebugf(", ");
  346. }
  347. kdebugf("\n");
  348. if(msg.msg_flags & MSG_TRUNC)
  349. fprintf(stderr, "netlink_read: message truncated\n");
  350. } while(!done);
  351. return 0;
  352. socket_error:
  353. close(nl->sock);
  354. nl->sock = -1;
  355. errno = EIO;
  356. return -1;
  357. }
  358. static int
  359. netlink_talk(struct nlmsghdr *nh)
  360. {
  361. int rc;
  362. struct sockaddr_nl nladdr;
  363. struct msghdr msg;
  364. struct iovec iov;
  365. memset(&nladdr, 0, sizeof(nladdr));
  366. nladdr.nl_family = AF_NETLINK;
  367. nladdr.nl_pid = 0;
  368. memset(&msg, 0, sizeof(msg));
  369. msg.msg_name = &nladdr;
  370. msg.msg_namelen = sizeof(nladdr);
  371. msg.msg_iov = &iov;
  372. msg.msg_iovlen = 1;
  373. iov.iov_base = nh;
  374. iov.iov_len = nh->nlmsg_len;
  375. nh->nlmsg_flags |= NLM_F_ACK;
  376. nh->nlmsg_seq = ++nl_command.seqno;
  377. kdebugf("Sending seqno %d from address %p (talk)\n",
  378. nl_command.seqno, &nl_command.seqno);
  379. rc = sendmsg(nl_command.sock, &msg, 0);
  380. if(rc < 0 && (errno == EAGAIN || errno == EINTR)) {
  381. rc = wait_for_fd(1, nl_command.sock, 100);
  382. if(rc <= 0) {
  383. if(rc == 0)
  384. errno = EAGAIN;
  385. } else {
  386. rc = sendmsg(nl_command.sock, &msg, 0);
  387. }
  388. }
  389. if(rc < nh->nlmsg_len) {
  390. int saved_errno = errno;
  391. perror("sendmsg");
  392. errno = saved_errno;
  393. return -1;
  394. }
  395. rc = netlink_read(&nl_command, NULL, 1, NULL); /* ACK */
  396. return rc;
  397. }
  398. static int
  399. netlink_send_dump(int type, void *data, int len) {
  400. struct sockaddr_nl nladdr;
  401. struct msghdr msg;
  402. struct iovec iov[2];
  403. union {
  404. char raw[NLMSG_ALIGN(sizeof(struct nlmsghdr))];
  405. struct nlmsghdr nh;
  406. } buf;
  407. int rc;
  408. /* At least we should send an 'struct rtgenmsg' */
  409. if(data == NULL || len == 0) {
  410. errno = EIO;
  411. return -1;
  412. }
  413. /* And more : using anything else that 'struct rtgenmsg' is currently */
  414. /* ignored by the linux kernel (today: 2.6.21) because NLM_F_MATCH is */
  415. /* not yet implemented */
  416. memset(&nladdr, 0, sizeof(nladdr));
  417. nladdr.nl_family = AF_NETLINK;
  418. memset(&msg, 0, sizeof(msg));
  419. msg.msg_name = &nladdr;
  420. msg.msg_namelen = sizeof(nladdr);
  421. msg.msg_iov = iov;
  422. msg.msg_iovlen = 2;
  423. iov[0].iov_base = buf.raw;
  424. iov[0].iov_len = sizeof(buf.raw);
  425. iov[1].iov_base = data;
  426. iov[1].iov_len = len;
  427. memset(buf.raw, 0, sizeof(buf.raw));
  428. buf.nh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
  429. buf.nh.nlmsg_type = type;
  430. buf.nh.nlmsg_seq = ++nl_command.seqno;
  431. buf.nh.nlmsg_len = NLMSG_LENGTH(len);
  432. kdebugf("Sending seqno %d from address %p (dump)\n",
  433. nl_command.seqno, &nl_command.seqno);
  434. rc = sendmsg(nl_command.sock, &msg, 0);
  435. if(rc < buf.nh.nlmsg_len) {
  436. int saved_errno = errno;
  437. perror("sendmsg");
  438. errno = saved_errno;
  439. return -1;
  440. }
  441. return 0;
  442. }
  443. int
  444. kernel_setup(int setup)
  445. {
  446. struct sysctl_setting *s;
  447. int i, rc;
  448. if(setup) {
  449. if(export_table < 0)
  450. export_table = RT_TABLE_MAIN;
  451. if(import_table_count < 1)
  452. import_tables[import_table_count++] = RT_TABLE_MAIN;
  453. dgram_socket = socket(PF_INET, SOCK_DGRAM, 0);
  454. if(dgram_socket < 0)
  455. return -1;
  456. rc = netlink_socket(&nl_command, 0);
  457. if(rc < 0) {
  458. perror("netlink_socket(0)");
  459. return -1;
  460. }
  461. nl_setup = 1;
  462. if(skip_kernel_setup) return 1;
  463. for(i=0; i<NUM_SYSCTLS; i++) {
  464. s = &sysctl_settings[i];
  465. s->was = read_proc(s->name);
  466. if(s->was < 0) {
  467. perror("Couldn't read sysctl");
  468. return -1;
  469. }
  470. if(s->was != s->want) {
  471. rc = write_proc(s->name, s->want);
  472. if(rc < 0) {
  473. perror("Couldn't write sysctl");
  474. return -1;
  475. }
  476. }
  477. }
  478. return 1;
  479. } else {
  480. close(dgram_socket);
  481. dgram_socket = -1;
  482. close(nl_command.sock);
  483. nl_command.sock = -1;
  484. nl_setup = 0;
  485. if(skip_kernel_setup) return 1;
  486. for(i=0; i<NUM_SYSCTLS; i++) {
  487. s = &sysctl_settings[i];
  488. if(s->was >= 0 && s->was != s->want) {
  489. rc = write_proc(s->name,s->was);
  490. if(rc < 0) {
  491. perror("Couldn't write sysctl");
  492. return -1;
  493. }
  494. }
  495. }
  496. return 1;
  497. }
  498. }
  499. static inline unsigned int
  500. rtnlgrp_to_mask(unsigned int grp)
  501. {
  502. return grp ? 1 << (grp - 1) : 0;
  503. }
  504. int
  505. kernel_setup_socket(int setup)
  506. {
  507. int rc;
  508. if(setup) {
  509. rc = netlink_socket(&nl_listen,
  510. rtnlgrp_to_mask(RTNLGRP_IPV6_ROUTE)
  511. | rtnlgrp_to_mask(RTNLGRP_IPV4_ROUTE)
  512. | rtnlgrp_to_mask(RTNLGRP_LINK)
  513. | rtnlgrp_to_mask(RTNLGRP_IPV4_IFADDR)
  514. | rtnlgrp_to_mask(RTNLGRP_IPV6_IFADDR)
  515. /* We monitor rules, because it can be change by third parties. For example
  516. a /etc/init.d/network restart on OpenWRT flush the rules. */
  517. | rtnlgrp_to_mask(RTNLGRP_IPV4_RULE)
  518. | rtnlgrp_to_mask(RTNLGRP_IPV6_RULE));
  519. if(rc < 0) {
  520. perror("netlink_socket(_ROUTE | _LINK | _IFADDR | _RULE)");
  521. kernel_socket = -1;
  522. return -1;
  523. }
  524. kernel_socket = nl_listen.sock;
  525. return 1;
  526. } else {
  527. close(nl_listen.sock);
  528. nl_listen.sock = -1;
  529. kernel_socket = -1;
  530. return 1;
  531. }
  532. }
  533. static int
  534. get_old_if(const char *ifname)
  535. {
  536. int i;
  537. for(i = 0; i < num_old_if; i++)
  538. if(strcmp(old_if[i].ifname, ifname) == 0)
  539. return i;
  540. if(num_old_if >= MAX_INTERFACES)
  541. return -1;
  542. old_if[num_old_if].ifname = strdup(ifname);
  543. if(old_if[num_old_if].ifname == NULL)
  544. return -1;
  545. old_if[num_old_if].rp_filter = -1;
  546. return num_old_if++;
  547. }
  548. int
  549. kernel_setup_interface(int setup, const char *ifname, int ifindex)
  550. {
  551. char buf[100];
  552. int i, rc;
  553. /* rp_filter has weird semantics: both all/rp_filter and ifname/rp_filter
  554. must be set to 0 for the rp_filter to be disabled. Deal with it. */
  555. rc = snprintf(buf, 100, "/proc/sys/net/ipv4/conf/%s/rp_filter", ifname);
  556. if(rc < 0 || rc >= 100)
  557. return -1;
  558. i = get_old_if(ifname);
  559. if(setup) {
  560. if(i >= 0)
  561. old_if[i].rp_filter = read_proc(buf);
  562. if(i < 0 || old_if[i].rp_filter < 0)
  563. fprintf(stderr,
  564. "Warning: cannot save old configuration for %s.\n",
  565. ifname);
  566. rc = write_proc(buf, 0);
  567. if(rc < 0)
  568. return -1;
  569. } else {
  570. if(i >= 0 && old_if[i].rp_filter >= 0)
  571. rc = write_proc(buf, old_if[i].rp_filter);
  572. else
  573. rc = -1;
  574. if(rc < 0)
  575. fprintf(stderr,
  576. "Warning: cannot restore old configuration for %s.\n",
  577. ifname);
  578. }
  579. return 1;
  580. }
  581. int
  582. kernel_interface_operational(const char *ifname, int ifindex)
  583. {
  584. struct ifreq req;
  585. int rc;
  586. int flags = link_detect ? (IFF_UP | IFF_RUNNING) : IFF_UP;
  587. memset(&req, 0, sizeof(req));
  588. strncpy(req.ifr_name, ifname, sizeof(req.ifr_name));
  589. rc = ioctl(dgram_socket, SIOCGIFFLAGS, &req);
  590. if(rc < 0)
  591. return -1;
  592. return ((req.ifr_flags & flags) == flags);
  593. }
  594. int
  595. kernel_interface_ipv4(const char *ifname, int ifindex, unsigned char *addr_r)
  596. {
  597. struct ifreq req;
  598. int rc;
  599. memset(&req, 0, sizeof(req));
  600. strncpy(req.ifr_name, ifname, sizeof(req.ifr_name));
  601. req.ifr_addr.sa_family = AF_INET;
  602. rc = ioctl(dgram_socket, SIOCGIFADDR, &req);
  603. if(rc < 0)
  604. return -1;
  605. memcpy(addr_r, &((struct sockaddr_in*)&req.ifr_addr)->sin_addr, 4);
  606. return 1;
  607. }
  608. int
  609. kernel_interface_mtu(const char *ifname, int ifindex)
  610. {
  611. struct ifreq req;
  612. int rc;
  613. memset(&req, 0, sizeof(req));
  614. strncpy(req.ifr_name, ifname, sizeof(req.ifr_name));
  615. rc = ioctl(dgram_socket, SIOCGIFMTU, &req);
  616. if(rc < 0)
  617. return -1;
  618. return req.ifr_mtu;
  619. }
  620. static int
  621. isbridge(const char *ifname, int ifindex)
  622. {
  623. char buf[256];
  624. int rc, i;
  625. unsigned long args[3];
  626. int indices[256];
  627. rc = snprintf(buf, 256, "/sys/class/net/%s", ifname);
  628. if(rc < 0 || rc >= 256)
  629. goto fallback;
  630. if(access(buf, R_OK) < 0)
  631. goto fallback;
  632. rc = snprintf(buf, 256, "/sys/class/net/%s/bridge", ifname);
  633. if(rc < 0 || rc >= 256)
  634. goto fallback;
  635. if(access(buf, F_OK) >= 0)
  636. return 1;
  637. else if(errno == ENOENT)
  638. return 0;
  639. fallback:
  640. args[0] = BRCTL_GET_BRIDGES;
  641. args[1] = (unsigned long)indices;
  642. args[2] = 256;
  643. rc = ioctl(dgram_socket, SIOCGIFBR, args);
  644. if(rc < 0) {
  645. if(errno == ENOPKG)
  646. return 0;
  647. else
  648. return -1;
  649. }
  650. for(i = 0; i < rc; i++) {
  651. if(indices[i] == ifindex)
  652. return 1;
  653. }
  654. return 0;
  655. }
  656. static int
  657. isbatman(const char *ifname, int ifindex)
  658. {
  659. char buf[256];
  660. int rc;
  661. rc = snprintf(buf, 256, "/sys/devices/virtual/net/%s/mesh", ifname);
  662. if(rc < 0 || rc >= 256)
  663. return -1;
  664. if(access(buf, F_OK) >= 0)
  665. return 1;
  666. if(errno != ENOENT)
  667. return -1;
  668. return 0;
  669. }
  670. int
  671. kernel_interface_wireless(const char *ifname, int ifindex)
  672. {
  673. #ifndef SIOCGIWNAME
  674. #define SIOCGIWNAME 0x8B01
  675. #endif
  676. struct ifreq req;
  677. int rc;
  678. if(isbridge(ifname, ifindex) != 0 || isbatman(ifname, ifindex) != 0)
  679. return -1;
  680. memset(&req, 0, sizeof(req));
  681. strncpy(req.ifr_name, ifname, sizeof(req.ifr_name));
  682. rc = ioctl(dgram_socket, SIOCGIWNAME, &req);
  683. if(rc < 0) {
  684. if(errno == EOPNOTSUPP || errno == EINVAL)
  685. rc = 0;
  686. else {
  687. perror("ioctl(SIOCGIWNAME)");
  688. rc = -1;
  689. }
  690. } else {
  691. rc = 1;
  692. }
  693. return rc;
  694. }
  695. /* Sorry for that, but I haven't managed to get <linux/wireless.h>
  696. to include cleanly. */
  697. #define SIOCGIWFREQ 0x8B05
  698. struct iw_freq {
  699. int m;
  700. short e;
  701. unsigned char i;
  702. unsigned char flags;
  703. };
  704. struct iwreq_subset {
  705. union {
  706. char ifrn_name[IFNAMSIZ];
  707. } ifr_ifrn;
  708. union {
  709. struct iw_freq freq;
  710. } u;
  711. };
  712. static int
  713. freq_to_chan(struct iw_freq *freq)
  714. {
  715. int m = freq->m, e = freq->e;
  716. /* If exponent is 0, assume the channel is encoded directly in m. */
  717. if(e == 0 && m > 0 && m < 254)
  718. return m;
  719. if(e <= 6) {
  720. int mega, step, c, i;
  721. /* This encodes 1 MHz */
  722. mega = 1000000;
  723. for(i = 0; i < e; i++)
  724. mega /= 10;
  725. /* Channels 1 through 13 are 5 MHz apart, with channel 1 at 2412. */
  726. step = 5 * mega;
  727. c = 1 + (m - 2412 * mega + step / 2) / step;
  728. if(c >= 1 && c <= 13)
  729. return c;
  730. /* Channel 14 is at 2484 MHz */
  731. if(c >= 14 && m < 2484 * mega + step / 2)
  732. return 14;
  733. /* 802.11a channel 36 is at 5180 MHz */
  734. c = 36 + (m - 5180 * mega + step / 2) / step;
  735. if(c >= 34 && c <= 165)
  736. return c;
  737. }
  738. errno = ENOENT;
  739. return -1;
  740. }
  741. int
  742. kernel_interface_channel(const char *ifname, int ifindex)
  743. {
  744. struct iwreq_subset iwreq;
  745. int rc;
  746. memset(&iwreq, 0, sizeof(iwreq));
  747. strncpy(iwreq.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ);
  748. rc = ioctl(dgram_socket, SIOCGIWFREQ, &iwreq);
  749. if(rc >= 0)
  750. return freq_to_chan(&iwreq.u.freq);
  751. else
  752. return -1;
  753. }
  754. /* Return true if we cannot handle disambiguation ourselves. */
  755. int
  756. kernel_disambiguate(int v4)
  757. {
  758. return !v4 && has_ipv6_subtrees;
  759. }
  760. int
  761. kernel_has_ipv6_subtrees(void)
  762. {
  763. return (kernel_older_than("Linux", 3, 11) == 0);
  764. }
  765. int
  766. kernel_route(int operation, int table,
  767. const unsigned char *dest, unsigned short plen,
  768. const unsigned char *src, unsigned short src_plen,
  769. const unsigned char *gate, int ifindex, unsigned int metric,
  770. const unsigned char *newgate, int newifindex,
  771. unsigned int newmetric, int newtable)
  772. {
  773. union { char raw[1024]; struct nlmsghdr nh; } buf;
  774. struct rtmsg *rtm;
  775. struct rtattr *rta;
  776. int len = sizeof(buf.raw);
  777. int rc, ipv4, use_src = 0;
  778. if(!nl_setup) {
  779. fprintf(stderr,"kernel_route: netlink not initialized.\n");
  780. errno = EIO;
  781. return -1;
  782. }
  783. /* if the socket has been closed after an IO error, */
  784. /* we try to re-open it. */
  785. if(nl_command.sock < 0) {
  786. rc = netlink_socket(&nl_command, 0);
  787. if(rc < 0) {
  788. int olderrno = errno;
  789. perror("kernel_route: netlink_socket()");
  790. errno = olderrno;
  791. return -1;
  792. }
  793. }
  794. /* Check that the protocol family is consistent. */
  795. if(plen >= 96 && v4mapped(dest)) {
  796. if(!v4mapped(gate) ||
  797. (src_plen > 0 && (!v4mapped(src) || src_plen < 96))) {
  798. errno = EINVAL;
  799. return -1;
  800. }
  801. } else {
  802. if(v4mapped(gate)|| (src_plen > 0 && v4mapped(src))) {
  803. errno = EINVAL;
  804. return -1;
  805. }
  806. }
  807. if(operation == ROUTE_MODIFY) {
  808. if(newmetric == metric && memcmp(newgate, gate, 16) == 0 &&
  809. newifindex == ifindex)
  810. return 0;
  811. /* It would be better to add the new route before removing the
  812. old one, to avoid losing packets. However, this causes
  813. problems with non-multipath kernels, which sometimes
  814. silently fail the request, causing "stuck" routes. Let's
  815. stick with the naive approach, and hope that the window is
  816. small enough to be negligible. */
  817. kernel_route(ROUTE_FLUSH, table, dest, plen,
  818. src, src_plen,
  819. gate, ifindex, metric,
  820. NULL, 0, 0, 0);
  821. rc = kernel_route(ROUTE_ADD, newtable, dest, plen,
  822. src, src_plen,
  823. newgate, newifindex, newmetric,
  824. NULL, 0, 0, 0);
  825. if(rc < 0) {
  826. if(errno == EEXIST)
  827. rc = 1;
  828. /* Should we try to re-install the flushed route on failure?
  829. Error handling is hard. */
  830. }
  831. return rc;
  832. }
  833. ipv4 = v4mapped(gate);
  834. use_src = (src_plen != 0 && kernel_disambiguate(ipv4));
  835. kdebugf("kernel_route: %s %s from %s "
  836. "table %d metric %d dev %d nexthop %s\n",
  837. operation == ROUTE_ADD ? "add" :
  838. operation == ROUTE_FLUSH ? "flush" : "???",
  839. format_prefix(dest, plen), format_prefix(src, src_plen),
  840. table, metric, ifindex, format_address(gate));
  841. /* Unreachable default routes cause all sort of weird interactions;
  842. ignore them. */
  843. if(metric >= KERNEL_INFINITY && (plen == 0 || (ipv4 && plen == 96)))
  844. return 0;
  845. memset(buf.raw, 0, sizeof(buf.raw));
  846. if(operation == ROUTE_ADD) {
  847. buf.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
  848. buf.nh.nlmsg_type = RTM_NEWROUTE;
  849. } else {
  850. buf.nh.nlmsg_flags = NLM_F_REQUEST;
  851. buf.nh.nlmsg_type = RTM_DELROUTE;
  852. }
  853. rtm = NLMSG_DATA(&buf.nh);
  854. rtm->rtm_family = ipv4 ? AF_INET : AF_INET6;
  855. rtm->rtm_dst_len = ipv4 ? plen - 96 : plen;
  856. if(use_src)
  857. rtm->rtm_src_len = src_plen;
  858. rtm->rtm_table = table;
  859. rtm->rtm_scope = RT_SCOPE_UNIVERSE;
  860. if(metric < KERNEL_INFINITY)
  861. rtm->rtm_type = RTN_UNICAST;
  862. else
  863. rtm->rtm_type = RTN_UNREACHABLE;
  864. rtm->rtm_protocol = RTPROT_BABEL;
  865. rtm->rtm_flags |= RTNH_F_ONLINK;
  866. rta = RTM_RTA(rtm);
  867. if(ipv4) {
  868. rta = RTA_NEXT(rta, len);
  869. rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
  870. rta->rta_type = RTA_DST;
  871. memcpy(RTA_DATA(rta), dest + 12, sizeof(struct in_addr));
  872. } else {
  873. rta = RTA_NEXT(rta, len);
  874. rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
  875. rta->rta_type = RTA_DST;
  876. memcpy(RTA_DATA(rta), dest, sizeof(struct in6_addr));
  877. if(use_src) {
  878. rta = RTA_NEXT(rta, len);
  879. rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
  880. rta->rta_type = RTA_SRC;
  881. memcpy(RTA_DATA(rta), src, sizeof(struct in6_addr));
  882. }
  883. }
  884. rta = RTA_NEXT(rta, len);
  885. rta->rta_len = RTA_LENGTH(sizeof(int));
  886. rta->rta_type = RTA_PRIORITY;
  887. if(metric < KERNEL_INFINITY) {
  888. *(int*)RTA_DATA(rta) = metric;
  889. rta = RTA_NEXT(rta, len);
  890. rta->rta_len = RTA_LENGTH(sizeof(int));
  891. rta->rta_type = RTA_OIF;
  892. *(int*)RTA_DATA(rta) = ifindex;
  893. if(ipv4) {
  894. rta = RTA_NEXT(rta, len);
  895. rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
  896. rta->rta_type = RTA_GATEWAY;
  897. memcpy(RTA_DATA(rta), gate + 12, sizeof(struct in_addr));
  898. } else {
  899. rta = RTA_NEXT(rta, len);
  900. rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr));
  901. rta->rta_type = RTA_GATEWAY;
  902. memcpy(RTA_DATA(rta), gate, sizeof(struct in6_addr));
  903. }
  904. } else {
  905. *(int*)RTA_DATA(rta) = -1;
  906. }
  907. buf.nh.nlmsg_len = (char*)rta + rta->rta_len - buf.raw;
  908. return netlink_talk(&buf.nh);
  909. }
  910. static int
  911. parse_kernel_route_rta(struct rtmsg *rtm, int len, struct kernel_route *route)
  912. {
  913. int table = rtm->rtm_table;
  914. struct rtattr *rta= RTM_RTA(rtm);;
  915. int i, is_v4;
  916. len -= NLMSG_ALIGN(sizeof(*rtm));
  917. memset(route, 0, sizeof(struct kernel_route));
  918. if(rtm->rtm_family == AF_INET) {
  919. /* if RTA_DST is not a TLV, that's a default destination */
  920. const unsigned char zeroes[4] = {0, 0, 0, 0};
  921. v4tov6(route->prefix, zeroes);
  922. route->plen = 96;
  923. }
  924. route->proto = rtm->rtm_protocol;
  925. is_v4 = rtm->rtm_family == AF_INET;
  926. while(RTA_OK(rta, len)) {
  927. switch(rta->rta_type) {
  928. case RTA_DST:
  929. route->plen = GET_PLEN(rtm->rtm_dst_len, is_v4);
  930. COPY_ADDR(route->prefix, rta, is_v4);
  931. break;
  932. case RTA_SRC:
  933. route->src_plen = GET_PLEN(rtm->rtm_src_len, is_v4);
  934. COPY_ADDR(route->src_prefix, rta, is_v4);
  935. break;
  936. case RTA_GATEWAY:
  937. COPY_ADDR(route->gw, rta, is_v4);
  938. break;
  939. case RTA_OIF:
  940. route->ifindex = *(int*)RTA_DATA(rta);
  941. break;
  942. case RTA_PRIORITY:
  943. route->metric = *(int*)RTA_DATA(rta);
  944. if(route->metric < 0 || route->metric > KERNEL_INFINITY)
  945. route->metric = KERNEL_INFINITY;
  946. break;
  947. case RTA_TABLE:
  948. table = *(int*)RTA_DATA(rta);
  949. break;
  950. default:
  951. break;
  952. }
  953. rta = RTA_NEXT(rta, len);
  954. }
  955. for(i = 0; i < import_table_count; i++)
  956. if(table == import_tables[i])
  957. return 0;
  958. return -1;
  959. }
  960. static void
  961. print_kernel_route(int add, int protocol, int type,
  962. struct kernel_route *route)
  963. {
  964. char ifname[IFNAMSIZ];
  965. char addr_prefix[INET6_ADDRSTRLEN];
  966. char src_addr_prefix[INET6_ADDRSTRLEN];
  967. char addr_gw[INET6_ADDRSTRLEN];
  968. if(!inet_ntop(AF_INET6, route->prefix,
  969. addr_prefix, sizeof(addr_prefix)) ||
  970. !inet_ntop(AF_INET6,route->gw, addr_gw, sizeof(addr_gw)) ||
  971. !if_indextoname(route->ifindex, ifname)) {
  972. kdebugf("Couldn't format kernel route for printing.");
  973. return;
  974. }
  975. if(route->src_plen >= 0) {
  976. if(!inet_ntop(AF_INET6, route->src_prefix,
  977. src_addr_prefix, sizeof(src_addr_prefix))) {
  978. kdebugf("Couldn't format kernel route for printing.");
  979. return;
  980. }
  981. kdebugf("%s kernel route: dest: %s/%d gw: %s metric: %d if: %s "
  982. "(proto: %d, type: %d, from: %s/%d)",
  983. add == RTM_NEWROUTE ? "Add" : "Delete",
  984. addr_prefix, route->plen, addr_gw, route->metric, ifname,
  985. protocol, type, src_addr_prefix, route->src_plen);
  986. return;
  987. }
  988. kdebugf("%s kernel route: dest: %s/%d gw: %s metric: %d if: %s "
  989. "(proto: %d, type: %d)",
  990. add == RTM_NEWROUTE ? "Add" : "Delete",
  991. addr_prefix, route->plen, addr_gw, route->metric, ifname,
  992. protocol, type);
  993. }
  994. static int
  995. filter_kernel_routes(struct nlmsghdr *nh, struct kernel_route *route)
  996. {
  997. int rc, len;
  998. struct rtmsg *rtm;
  999. len = nh->nlmsg_len;
  1000. if(nh->nlmsg_type != RTM_NEWROUTE &&
  1001. nh->nlmsg_type != RTM_DELROUTE)
  1002. return 0;
  1003. rtm = (struct rtmsg*)NLMSG_DATA(nh);
  1004. len -= NLMSG_LENGTH(0);
  1005. if(rtm->rtm_protocol == RTPROT_BABEL)
  1006. return 0;
  1007. /* Ignore cached routes, advertised by some kernels (linux 3.x). */
  1008. if(rtm->rtm_flags & RTM_F_CLONED)
  1009. return 0;
  1010. rc = parse_kernel_route_rta(rtm, len, route);
  1011. if(rc < 0)
  1012. return 0;
  1013. /* Ignore default unreachable routes; no idea where they come from. */
  1014. if(route->plen == 0 && route->metric >= KERNEL_INFINITY)
  1015. return 0;
  1016. if(debug >= 2) {
  1017. if(rc >= 0) {
  1018. print_kernel_route(nh->nlmsg_type, rtm->rtm_protocol,
  1019. rtm->rtm_type, route);
  1020. }
  1021. }
  1022. return 1;
  1023. }
  1024. /* This function should not return routes installed by us. */
  1025. int
  1026. kernel_dump(int operation, struct kernel_filter *filter)
  1027. {
  1028. int i, rc;
  1029. int families[2] = { AF_INET6, AF_INET };
  1030. struct rtgenmsg g;
  1031. if(!nl_setup) {
  1032. fprintf(stderr,"kernel_dump: netlink not initialized.\n");
  1033. errno = EIO;
  1034. return -1;
  1035. }
  1036. if(nl_command.sock < 0) {
  1037. rc = netlink_socket(&nl_command, 0);
  1038. if(rc < 0) {
  1039. int save = errno;
  1040. perror("kernel_dump: netlink_socket()");
  1041. errno = save;
  1042. return -1;
  1043. }
  1044. }
  1045. for(i = 0; i < 2; i++) {
  1046. memset(&g, 0, sizeof(g));
  1047. g.rtgen_family = families[i];
  1048. if(operation & CHANGE_ROUTE) {
  1049. rc = netlink_send_dump(RTM_GETROUTE, &g, sizeof(g));
  1050. if(rc < 0)
  1051. return -1;
  1052. rc = netlink_read(&nl_command, NULL, 1, filter);
  1053. if(rc < 0)
  1054. return -1;
  1055. }
  1056. memset(&g, 0, sizeof(g));
  1057. g.rtgen_family = families[i];
  1058. if(operation & CHANGE_RULE) {
  1059. rc = netlink_send_dump(RTM_GETRULE, &g, sizeof(g));
  1060. if(rc < 0)
  1061. return -1;
  1062. rc = netlink_read(&nl_command, NULL, 1, filter);
  1063. if(rc < 0)
  1064. return -1;
  1065. }
  1066. }
  1067. if(operation & CHANGE_ADDR) {
  1068. memset(&g, 0, sizeof(g));
  1069. g.rtgen_family = AF_UNSPEC;
  1070. rc = netlink_send_dump(RTM_GETADDR, &g, sizeof(g));
  1071. if(rc < 0)
  1072. return -1;
  1073. rc = netlink_read(&nl_command, NULL, 1, filter);
  1074. if(rc < 0)
  1075. return -1;
  1076. }
  1077. return 0;
  1078. }
  1079. static char *
  1080. parse_ifname_rta(struct ifinfomsg *info, int len)
  1081. {
  1082. struct rtattr *rta = IFLA_RTA(info);
  1083. char *ifname = NULL;
  1084. len -= NLMSG_ALIGN(sizeof(*info));
  1085. while(RTA_OK(rta, len)) {
  1086. switch(rta->rta_type) {
  1087. case IFLA_IFNAME:
  1088. ifname = RTA_DATA(rta);
  1089. break;
  1090. default:
  1091. break;
  1092. }
  1093. rta = RTA_NEXT(rta, len);
  1094. }
  1095. return ifname;
  1096. }
  1097. static int
  1098. parse_addr_rta(struct ifaddrmsg *addr, int len, struct in6_addr *res)
  1099. {
  1100. struct rtattr *rta;
  1101. len -= NLMSG_ALIGN(sizeof(*addr));
  1102. rta = IFA_RTA(addr);
  1103. while(RTA_OK(rta, len)) {
  1104. switch(rta->rta_type) {
  1105. case IFA_LOCAL:
  1106. case IFA_ADDRESS:
  1107. switch(addr->ifa_family) {
  1108. case AF_INET:
  1109. if(res)
  1110. v4tov6(res->s6_addr, RTA_DATA(rta));
  1111. break;
  1112. case AF_INET6:
  1113. if(res)
  1114. memcpy(res->s6_addr, RTA_DATA(rta), 16);
  1115. break;
  1116. default:
  1117. kdebugf("ifaddr: unexpected address family %d\n",
  1118. addr->ifa_family);
  1119. return -1;
  1120. break;
  1121. }
  1122. break;
  1123. default:
  1124. break;
  1125. }
  1126. rta = RTA_NEXT(rta, len);
  1127. }
  1128. return 0;
  1129. }
  1130. static int
  1131. filter_link(struct nlmsghdr *nh, struct kernel_link *link)
  1132. {
  1133. struct ifinfomsg *info;
  1134. int len;
  1135. int ifindex;
  1136. unsigned int ifflags;
  1137. len = nh->nlmsg_len;
  1138. if(nh->nlmsg_type != RTM_NEWLINK && nh->nlmsg_type != RTM_DELLINK)
  1139. return 0;
  1140. info = (struct ifinfomsg*)NLMSG_DATA(nh);
  1141. len -= NLMSG_LENGTH(0);
  1142. ifindex = info->ifi_index;
  1143. ifflags = info->ifi_flags;
  1144. link->ifname = parse_ifname_rta(info, len);
  1145. if(link->ifname == NULL)
  1146. return 0;
  1147. kdebugf("filter_interfaces: link change on if %s(%d): 0x%x\n",
  1148. link->ifname, ifindex, (unsigned)ifflags);
  1149. return 1;
  1150. }
  1151. /* If data is null, takes all addresses. If data is not null, takes
  1152. either link-local or global addresses depending of the value of
  1153. data[4]. */
  1154. static int
  1155. filter_addresses(struct nlmsghdr *nh, struct kernel_addr *addr)
  1156. {
  1157. int rc;
  1158. int len;
  1159. struct ifaddrmsg *ifa;
  1160. char ifname[IFNAMSIZ];
  1161. len = nh->nlmsg_len;
  1162. if(nh->nlmsg_type != RTM_NEWADDR &&
  1163. nh->nlmsg_type != RTM_DELADDR)
  1164. return 0;
  1165. ifa = (struct ifaddrmsg *)NLMSG_DATA(nh);
  1166. len -= NLMSG_LENGTH(0);
  1167. rc = parse_addr_rta(ifa, len, &addr->addr);
  1168. if(rc < 0)
  1169. return 0;
  1170. addr->ifindex = ifa->ifa_index;
  1171. kdebugf("found address on interface %s(%d): %s\n",
  1172. if_indextoname(ifa->ifa_index, ifname), ifa->ifa_index,
  1173. format_address(addr->addr.s6_addr));
  1174. return 1;
  1175. }
  1176. static int
  1177. filter_kernel_rules(struct nlmsghdr *nh, struct kernel_rule *rule)
  1178. {
  1179. int len, has_priority = 0, has_table = 0;
  1180. struct rtmsg *rtm = NULL;
  1181. struct rtattr *rta = NULL;
  1182. int is_v4 = 0;
  1183. len = nh->nlmsg_len;
  1184. rtm = (struct rtmsg*)NLMSG_DATA(nh);
  1185. len -= NLMSG_LENGTH(0);
  1186. rule->src_plen = rtm->rtm_src_len;
  1187. memset(rule->src, 0, sizeof(rule->src));
  1188. rule->table = rtm->rtm_table;
  1189. if(rtm->rtm_family != AF_INET && rtm->rtm_family != AF_INET6) {
  1190. kdebugf("filter_rules: Unknown family: %d\n", rtm->rtm_family);
  1191. return -1;
  1192. }
  1193. is_v4 = rtm->rtm_family == AF_INET;
  1194. rta = RTM_RTA(rtm);
  1195. len -= NLMSG_ALIGN(sizeof(*rtm));
  1196. for(; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
  1197. switch(rta->rta_type) {
  1198. case FRA_UNSPEC: break;
  1199. case FRA_SRC:
  1200. rule->src_plen = GET_PLEN(rtm->rtm_src_len, is_v4);
  1201. COPY_ADDR(rule->src, rta, is_v4);
  1202. break;
  1203. case FRA_PRIORITY:
  1204. rule->priority = *(unsigned int*)RTA_DATA(rta);
  1205. has_priority = 1;
  1206. break;
  1207. case FRA_TABLE:
  1208. rule->table = *(int*)RTA_DATA(rta);
  1209. has_table = 1;
  1210. break;
  1211. default:
  1212. kdebugf("filter_rules: Unknown rule attribute: %d.\n",
  1213. rta->rta_type);
  1214. break;
  1215. }
  1216. }
  1217. kdebugf("filter_rules: from %s prio %d table %d\n",
  1218. format_prefix(rule->src, rule->src_plen),
  1219. has_priority ? rule->priority : -1, rule->table);
  1220. if(!has_priority || !has_table)
  1221. return 0;
  1222. return 1;
  1223. }
  1224. static int
  1225. filter_netlink(struct nlmsghdr *nh, struct kernel_filter *filter)
  1226. {
  1227. int rc;
  1228. union {
  1229. struct kernel_route route;
  1230. struct kernel_addr addr;
  1231. struct kernel_link link;
  1232. struct kernel_rule rule;
  1233. } u;
  1234. switch(nh->nlmsg_type) {
  1235. case RTM_NEWROUTE:
  1236. case RTM_DELROUTE:
  1237. if(!filter->route) break;
  1238. rc = filter_kernel_routes(nh, &u.route);
  1239. if(rc <= 0) break;
  1240. return filter->route(&u.route, filter->route_closure);
  1241. case RTM_NEWLINK:
  1242. case RTM_DELLINK:
  1243. if(!filter->link) break;
  1244. rc = filter_link(nh, &u.link);
  1245. if(rc <= 0) break;
  1246. return filter->link(&u.link, filter->link_closure);
  1247. case RTM_NEWADDR:
  1248. case RTM_DELADDR:
  1249. if(!filter->addr) break;
  1250. rc = filter_addresses(nh, &u.addr);
  1251. if(rc <= 0) break;
  1252. return filter->addr(&u.addr, filter->addr_closure);
  1253. case RTM_NEWRULE:
  1254. case RTM_DELRULE:
  1255. if(!filter->rule) break;
  1256. rc = filter_kernel_rules(nh, &u.rule);
  1257. if(rc <= 0) break;
  1258. return filter->rule(&u.rule, filter->rule_closure);
  1259. default:
  1260. kdebugf("filter_netlink: unexpected message type %d\n",
  1261. nh->nlmsg_type);
  1262. break;
  1263. }
  1264. return 0;
  1265. }
  1266. int
  1267. kernel_callback(struct kernel_filter *filter)
  1268. {
  1269. int rc;
  1270. kdebugf("\nReceived changes in kernel tables.\n");
  1271. if(nl_listen.sock < 0) {
  1272. rc = kernel_setup_socket(1);
  1273. if(rc < 0) {
  1274. perror("kernel_callback: kernel_setup_socket(1)");
  1275. return -1;
  1276. }
  1277. }
  1278. rc = netlink_read(&nl_listen, &nl_command, 0, filter);
  1279. if(rc < 0 && nl_listen.sock < 0)
  1280. kernel_setup_socket(1);
  1281. return 0;
  1282. }
  1283. /* Routing table's rules */
  1284. int
  1285. add_rule(int prio, const unsigned char *src_prefix, int src_plen, int table)
  1286. {
  1287. char buffer[64] = {0}; /* 56 needed */
  1288. struct nlmsghdr *message_header = (void*)buffer;
  1289. struct rtmsg *message = NULL;
  1290. struct rtattr *current_attribute = NULL;
  1291. int is_v4 = v4mapped(src_prefix);
  1292. int addr_size = is_v4 ? sizeof(struct in_addr) : sizeof(struct in6_addr);
  1293. kdebugf("Add rule v%c prio %d from %s\n", is_v4 ? '4' : '6', prio,
  1294. format_prefix(src_prefix, src_plen));
  1295. if(is_v4) {
  1296. src_prefix += 12;
  1297. src_plen -= 96;
  1298. if(src_plen < 0) {
  1299. errno = EINVAL;
  1300. return -1;
  1301. }
  1302. }
  1303. #if RTA_ALIGNTO != NLMSG_ALIGNTO
  1304. #error "RTA_ALIGNTO != NLMSG_ALIGNTO"
  1305. #endif
  1306. /* Set the header */
  1307. message_header->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
  1308. message_header->nlmsg_type = RTM_NEWRULE;
  1309. message_header->nlmsg_len = NLMSG_ALIGN(sizeof(struct nlmsghdr));
  1310. /* Append the message */
  1311. message = NLMSG_DATA(message_header);
  1312. message->rtm_family = is_v4 ? AF_INET : AF_INET6;
  1313. message->rtm_dst_len = 0;
  1314. message->rtm_src_len = src_plen;
  1315. message->rtm_tos = 0;
  1316. message->rtm_table = table;
  1317. message->rtm_protocol = RTPROT_BABEL;
  1318. message->rtm_scope = RT_SCOPE_UNIVERSE;
  1319. message->rtm_type = RTN_UNICAST;
  1320. message->rtm_flags = 0;
  1321. message_header->nlmsg_len += NLMSG_ALIGN(sizeof(struct rtmsg));
  1322. /* Append each attribute */
  1323. current_attribute = RTM_RTA(message);
  1324. /* prio */
  1325. current_attribute->rta_len = RTA_LENGTH(sizeof(int));
  1326. current_attribute->rta_type = FRA_PRIORITY;
  1327. *(int*)RTA_DATA(current_attribute) = prio;
  1328. message_header->nlmsg_len += current_attribute->rta_len;
  1329. current_attribute = (void*)
  1330. ((char*)current_attribute) + current_attribute->rta_len;
  1331. /* src */
  1332. current_attribute->rta_len = RTA_LENGTH(addr_size);
  1333. current_attribute->rta_type = FRA_SRC;
  1334. memcpy(RTA_DATA(current_attribute), src_prefix, addr_size);
  1335. message_header->nlmsg_len += current_attribute->rta_len;
  1336. current_attribute = (void*)
  1337. ((char*)current_attribute) + current_attribute->rta_len;
  1338. /* send message */
  1339. if(message_header->nlmsg_len > 64) {
  1340. errno = EINVAL;
  1341. return -1;
  1342. }
  1343. return netlink_talk(message_header);
  1344. }
  1345. int
  1346. flush_rule(int prio, int family)
  1347. {
  1348. char buffer[64] = {0}; /* 36 needed */
  1349. struct nlmsghdr *message_header = (void*)buffer;
  1350. struct rtmsg *message = NULL;
  1351. struct rtattr *current_attribute = NULL;
  1352. memset(buffer, 0, sizeof(buffer));
  1353. kdebugf("Flush rule v%c prio %d\n", family == AF_INET ? '4' : '6', prio);
  1354. #if RTA_ALIGNTO != NLMSG_ALIGNTO
  1355. #error "RTA_ALIGNTO != NLMSG_ALIGNTO"
  1356. #endif
  1357. /* Set the header */
  1358. message_header->nlmsg_flags = NLM_F_REQUEST;
  1359. message_header->nlmsg_type = RTM_DELRULE;
  1360. message_header->nlmsg_len = NLMSG_ALIGN(sizeof(struct nlmsghdr));
  1361. /* Append the message */
  1362. message = NLMSG_DATA(message_header);
  1363. message->rtm_family = family;
  1364. message->rtm_dst_len = 0;
  1365. message->rtm_src_len = 0;
  1366. message->rtm_tos = 0;
  1367. message->rtm_table = 0;
  1368. message->rtm_protocol = RTPROT_BABEL;
  1369. message->rtm_scope = RT_SCOPE_UNIVERSE;
  1370. message->rtm_type = RTN_UNSPEC;
  1371. message->rtm_flags = 0;
  1372. message_header->nlmsg_len += NLMSG_ALIGN(sizeof(struct rtmsg));
  1373. /* Append each attribute */
  1374. current_attribute = RTM_RTA(message);
  1375. /* prio */
  1376. current_attribute->rta_len = RTA_LENGTH(sizeof(int));
  1377. current_attribute->rta_type = FRA_PRIORITY;
  1378. *(int*)RTA_DATA(current_attribute) = prio;
  1379. message_header->nlmsg_len += current_attribute->rta_len;
  1380. current_attribute = (void*)
  1381. ((char*)current_attribute) + current_attribute->rta_len;
  1382. /* send message */
  1383. if(message_header->nlmsg_len > 64) {
  1384. errno = EINVAL;
  1385. return -1;
  1386. }
  1387. return netlink_talk(message_header);
  1388. }
  1389. int
  1390. change_rule(int new_prio, int old_prio,
  1391. const unsigned char *src, int plen, int table)
  1392. {
  1393. int rc;
  1394. kdebugf("/Swap: ");
  1395. rc = add_rule(new_prio, src, plen, table);
  1396. if(rc < 0)
  1397. return rc;
  1398. kdebugf("\\Swap: ");
  1399. return flush_rule(old_prio, v4mapped(src) ? AF_INET : AF_INET6);
  1400. }