PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/uClinux-dist/user/samba/source/lib/interface.c

https://bitbucket.org/__wp__/mb-linux-msli
C | 363 lines | 226 code | 62 blank | 75 comment | 58 complexity | b0a76ff56b92a8d7c5787110403109b9 MD5 | raw file
Possible License(s): AGPL-3.0, GPL-2.0, LGPL-2.0, MPL-2.0, ISC, BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception, 0BSD, CC-BY-SA-3.0, GPL-3.0, LGPL-3.0, AGPL-1.0, Unlicense
  1. /*
  2. Unix SMB/CIFS implementation.
  3. multiple interface handling
  4. Copyright (C) Andrew Tridgell 1992-1998
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #include "includes.h"
  18. static struct iface_struct *probed_ifaces;
  19. static int total_probed;
  20. struct in_addr allones_ip;
  21. struct in_addr loopback_ip;
  22. static struct interface *local_interfaces;
  23. #define ALLONES ((uint32)0xFFFFFFFF)
  24. #define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
  25. #define MKNETADDR(_IP, _NM) (_IP & _NM)
  26. /****************************************************************************
  27. Try and find an interface that matches an ip. If we cannot, return NULL
  28. **************************************************************************/
  29. static struct interface *iface_find(struct in_addr ip, BOOL CheckMask)
  30. {
  31. struct interface *i;
  32. if (is_zero_ip(ip)) return local_interfaces;
  33. for (i=local_interfaces;i;i=i->next)
  34. if (CheckMask) {
  35. if (same_net(i->ip,ip,i->nmask)) return i;
  36. } else if ((i->ip).s_addr == ip.s_addr) return i;
  37. return NULL;
  38. }
  39. /****************************************************************************
  40. add an interface to the linked list of interfaces
  41. ****************************************************************************/
  42. static void add_interface(struct in_addr ip, struct in_addr nmask)
  43. {
  44. struct interface *iface;
  45. if (iface_find(ip, False)) {
  46. DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
  47. return;
  48. }
  49. #if !defined(__s390__)
  50. if (ip_equal(nmask, allones_ip)) {
  51. DEBUG(3,("not adding non-broadcast interface %s\n",inet_ntoa(ip)));
  52. return;
  53. }
  54. #endif
  55. iface = SMB_MALLOC_P(struct interface);
  56. if (!iface) return;
  57. ZERO_STRUCTPN(iface);
  58. iface->ip = ip;
  59. iface->nmask = nmask;
  60. iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
  61. DLIST_ADD(local_interfaces, iface);
  62. DEBUG(2,("added interface ip=%s ",inet_ntoa(iface->ip)));
  63. DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
  64. DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
  65. }
  66. /****************************************************************************
  67. interpret a single element from a interfaces= config line
  68. This handles the following different forms:
  69. 1) wildcard interface name
  70. 2) DNS name
  71. 3) IP/masklen
  72. 4) ip/mask
  73. 5) bcast/mask
  74. ****************************************************************************/
  75. static void interpret_interface(char *token)
  76. {
  77. struct in_addr ip, nmask;
  78. char *p;
  79. int i, added=0;
  80. zero_ip(&ip);
  81. zero_ip(&nmask);
  82. /* first check if it is an interface name */
  83. for (i=0;i<total_probed;i++) {
  84. if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
  85. add_interface(probed_ifaces[i].ip,
  86. probed_ifaces[i].netmask);
  87. added = 1;
  88. }
  89. }
  90. if (added) return;
  91. /* maybe it is a DNS name */
  92. p = strchr_m(token,'/');
  93. if (!p) {
  94. ip = *interpret_addr2(token);
  95. for (i=0;i<total_probed;i++) {
  96. if (ip.s_addr == probed_ifaces[i].ip.s_addr &&
  97. !ip_equal(allones_ip, probed_ifaces[i].netmask)) {
  98. add_interface(probed_ifaces[i].ip,
  99. probed_ifaces[i].netmask);
  100. return;
  101. }
  102. }
  103. DEBUG(2,("can't determine netmask for %s\n", token));
  104. return;
  105. }
  106. /* parse it into an IP address/netmasklength pair */
  107. *p = 0;
  108. ip = *interpret_addr2(token);
  109. *p++ = '/';
  110. if (strlen(p) > 2) {
  111. nmask = *interpret_addr2(p);
  112. } else {
  113. nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
  114. }
  115. /* maybe the first component was a broadcast address */
  116. if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
  117. ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
  118. for (i=0;i<total_probed;i++) {
  119. if (same_net(ip, probed_ifaces[i].ip, nmask)) {
  120. add_interface(probed_ifaces[i].ip, nmask);
  121. return;
  122. }
  123. }
  124. DEBUG(2,("Can't determine ip for broadcast address %s\n", token));
  125. return;
  126. }
  127. add_interface(ip, nmask);
  128. }
  129. /****************************************************************************
  130. load the list of network interfaces
  131. ****************************************************************************/
  132. void load_interfaces(void)
  133. {
  134. const char **ptr;
  135. int i;
  136. struct iface_struct ifaces[MAX_INTERFACES];
  137. ptr = lp_interfaces();
  138. allones_ip = *interpret_addr2("255.255.255.255");
  139. loopback_ip = *interpret_addr2("127.0.0.1");
  140. SAFE_FREE(probed_ifaces);
  141. /* dump the current interfaces if any */
  142. while (local_interfaces) {
  143. struct interface *iface = local_interfaces;
  144. DLIST_REMOVE(local_interfaces, local_interfaces);
  145. ZERO_STRUCTPN(iface);
  146. SAFE_FREE(iface);
  147. }
  148. /* probe the kernel for interfaces */
  149. total_probed = get_interfaces(ifaces, MAX_INTERFACES);
  150. if (total_probed > 0) {
  151. probed_ifaces = (struct iface_struct *)memdup(ifaces, sizeof(ifaces[0])*total_probed);
  152. if (!probed_ifaces) {
  153. DEBUG(0,("ERROR: memdup failed\n"));
  154. exit(1);
  155. }
  156. }
  157. /* if we don't have a interfaces line then use all broadcast capable
  158. interfaces except loopback */
  159. if (!ptr || !*ptr || !**ptr) {
  160. if (total_probed <= 0) {
  161. DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
  162. exit(1);
  163. }
  164. for (i=0;i<total_probed;i++) {
  165. if (
  166. #if !defined(__s390__)
  167. probed_ifaces[i].netmask.s_addr != allones_ip.s_addr &&
  168. #endif
  169. probed_ifaces[i].ip.s_addr != loopback_ip.s_addr) {
  170. add_interface(probed_ifaces[i].ip,
  171. probed_ifaces[i].netmask);
  172. }
  173. }
  174. return;
  175. }
  176. if (ptr) {
  177. while (*ptr) {
  178. char *ptr_cpy = SMB_STRDUP(*ptr);
  179. if (ptr_cpy) {
  180. interpret_interface(ptr_cpy);
  181. free(ptr_cpy);
  182. }
  183. ptr++;
  184. }
  185. }
  186. if (!local_interfaces) {
  187. DEBUG(0,("WARNING: no network interfaces found\n"));
  188. }
  189. }
  190. void gfree_interfaces(void)
  191. {
  192. while (local_interfaces) {
  193. struct interface *iface = local_interfaces;
  194. DLIST_REMOVE(local_interfaces, local_interfaces);
  195. ZERO_STRUCTPN(iface);
  196. SAFE_FREE(iface);
  197. }
  198. SAFE_FREE(probed_ifaces);
  199. }
  200. /****************************************************************************
  201. return True if the list of probed interfaces has changed
  202. ****************************************************************************/
  203. BOOL interfaces_changed(void)
  204. {
  205. int n;
  206. struct iface_struct ifaces[MAX_INTERFACES];
  207. n = get_interfaces(ifaces, MAX_INTERFACES);
  208. if ((n > 0 )&& (n != total_probed ||
  209. memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
  210. return True;
  211. }
  212. return False;
  213. }
  214. /****************************************************************************
  215. check if an IP is one of mine
  216. **************************************************************************/
  217. BOOL ismyip(struct in_addr ip)
  218. {
  219. struct interface *i;
  220. for (i=local_interfaces;i;i=i->next)
  221. if (ip_equal(i->ip,ip)) return True;
  222. return False;
  223. }
  224. /****************************************************************************
  225. check if a packet is from a local (known) net
  226. **************************************************************************/
  227. BOOL is_local_net(struct in_addr from)
  228. {
  229. struct interface *i;
  230. for (i=local_interfaces;i;i=i->next) {
  231. if((from.s_addr & i->nmask.s_addr) ==
  232. (i->ip.s_addr & i->nmask.s_addr))
  233. return True;
  234. }
  235. return False;
  236. }
  237. /****************************************************************************
  238. how many interfaces do we have
  239. **************************************************************************/
  240. int iface_count(void)
  241. {
  242. int ret = 0;
  243. struct interface *i;
  244. for (i=local_interfaces;i;i=i->next)
  245. ret++;
  246. return ret;
  247. }
  248. /****************************************************************************
  249. return the Nth interface
  250. **************************************************************************/
  251. struct interface *get_interface(int n)
  252. {
  253. struct interface *i;
  254. for (i=local_interfaces;i && n;i=i->next)
  255. n--;
  256. if (i) return i;
  257. return NULL;
  258. }
  259. /****************************************************************************
  260. return IP of the Nth interface
  261. **************************************************************************/
  262. struct in_addr *iface_n_ip(int n)
  263. {
  264. struct interface *i;
  265. for (i=local_interfaces;i && n;i=i->next)
  266. n--;
  267. if (i) return &i->ip;
  268. return NULL;
  269. }
  270. /****************************************************************************
  271. return bcast of the Nth interface
  272. **************************************************************************/
  273. struct in_addr *iface_n_bcast(int n)
  274. {
  275. struct interface *i;
  276. for (i=local_interfaces;i && n;i=i->next)
  277. n--;
  278. if (i) return &i->bcast;
  279. return NULL;
  280. }
  281. /* these 3 functions return the ip/bcast/nmask for the interface
  282. most appropriate for the given ip address. If they can't find
  283. an appropriate interface they return the requested field of the
  284. first known interface. */
  285. struct in_addr *iface_ip(struct in_addr ip)
  286. {
  287. struct interface *i = iface_find(ip, True);
  288. return(i ? &i->ip : &local_interfaces->ip);
  289. }
  290. /*
  291. return True if a IP is directly reachable on one of our interfaces
  292. */
  293. BOOL iface_local(struct in_addr ip)
  294. {
  295. return iface_find(ip, True) ? True : False;
  296. }