socket.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * DHCP server client/server socket creation
  4. *
  5. * udhcp client/server
  6. * Copyright (C) 1999 Matthew Ramsay <matthewr@moreton.com.au>
  7. * Chris Trew <ctrew@moreton.com.au>
  8. *
  9. * Rewrite by Russ Dill <Russ.Dill@asu.edu> July 2001
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. */
  25. #include <net/if.h>
  26. #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION
  27. # include <netpacket/packet.h>
  28. # include <net/ethernet.h>
  29. #else
  30. # include <asm/types.h>
  31. # include <linux/if_packet.h>
  32. # include <linux/if_ether.h>
  33. #endif
  34. #include "common.h"
  35. int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac)
  36. {
  37. int fd;
  38. struct ifreq ifr;
  39. struct sockaddr_in *our_ip;
  40. memset(&ifr, 0, sizeof(ifr));
  41. fd = xsocket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  42. ifr.ifr_addr.sa_family = AF_INET;
  43. strncpy_IFNAMSIZ(ifr.ifr_name, interface);
  44. if (nip) {
  45. if (ioctl_or_perror(fd, SIOCGIFADDR, &ifr,
  46. "is interface %s up and configured?", interface)
  47. ) {
  48. close(fd);
  49. return -1;
  50. }
  51. our_ip = (struct sockaddr_in *) &ifr.ifr_addr;
  52. *nip = our_ip->sin_addr.s_addr;
  53. log1("IP %s", inet_ntoa(our_ip->sin_addr));
  54. }
  55. if (ifindex) {
  56. if (ioctl_or_warn(fd, SIOCGIFINDEX, &ifr) != 0) {
  57. close(fd);
  58. return -1;
  59. }
  60. log1("Adapter index %d", ifr.ifr_ifindex);
  61. *ifindex = ifr.ifr_ifindex;
  62. }
  63. if (mac) {
  64. if (ioctl_or_warn(fd, SIOCGIFHWADDR, &ifr) != 0) {
  65. close(fd);
  66. return -1;
  67. }
  68. memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
  69. log1("MAC %02x:%02x:%02x:%02x:%02x:%02x",
  70. mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  71. }
  72. close(fd);
  73. return 0;
  74. }
  75. /* 1. None of the callers expects it to ever fail */
  76. /* 2. ip was always INADDR_ANY */
  77. int FAST_FUNC udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf)
  78. {
  79. int fd;
  80. struct sockaddr_in addr;
  81. log1("Opening listen socket on *:%d %s", port, inf);
  82. fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  83. setsockopt_reuseaddr(fd);
  84. if (setsockopt_broadcast(fd) == -1)
  85. bb_perror_msg_and_die("SO_BROADCAST");
  86. /* NB: bug 1032 says this doesn't work on ethernet aliases (ethN:M) */
  87. if (setsockopt_bindtodevice(fd, inf))
  88. xfunc_die(); /* warning is already printed */
  89. memset(&addr, 0, sizeof(addr));
  90. addr.sin_family = AF_INET;
  91. addr.sin_port = htons(port);
  92. /* addr.sin_addr.s_addr = ip; - all-zeros is INADDR_ANY */
  93. xbind(fd, (struct sockaddr *)&addr, sizeof(addr));
  94. return fd;
  95. }