+int FAST_FUNC setsockopt_SOL_SOCKET_int(int fd, int optname, int optval)
+{
+ return setsockopt_int(fd, SOL_SOCKET, optname, optval);
+}
+int FAST_FUNC setsockopt_SOL_SOCKET_1(int fd, int optname)
+{
+ return setsockopt_SOL_SOCKET_int(fd, optname, 1);
+}
+
+void FAST_FUNC setsockopt_reuseaddr(int fd)
+{
+ setsockopt_SOL_SOCKET_1(fd, SO_REUSEADDR);
+}
+int FAST_FUNC setsockopt_broadcast(int fd)
+{
+ return setsockopt_SOL_SOCKET_1(fd, SO_BROADCAST);
+}
+int FAST_FUNC setsockopt_keepalive(int fd)
+{
+ return setsockopt_SOL_SOCKET_1(fd, SO_KEEPALIVE);
+}
+
+#ifdef SO_BINDTODEVICE
+int FAST_FUNC setsockopt_bindtodevice(int fd, const char *iface)
+{
+ int r;
+ struct ifreq ifr;
+ strncpy_IFNAMSIZ(ifr.ifr_name, iface);
+ /* NB: passing (iface, strlen(iface) + 1) does not work!
+ * (maybe it works on _some_ kernels, but not on 2.6.26)
+ * Actually, ifr_name is at offset 0, and in practice
+ * just giving char[IFNAMSIZ] instead of struct ifreq works too.
+ * But just in case it's not true on some obscure arch... */
+ r = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr));
+ if (r)
+ bb_perror_msg("can't bind to interface %s", iface);
+ return r;
+}
+#else
+int FAST_FUNC setsockopt_bindtodevice(int fd UNUSED_PARAM,
+ const char *iface UNUSED_PARAM)
+{
+ bb_error_msg("SO_BINDTODEVICE is not supported on this system");
+ return -1;
+}
+#endif
+
+static len_and_sockaddr* get_lsa(int fd, int (*get_name)(int fd, struct sockaddr *addr, socklen_t *addrlen))
+{
+ len_and_sockaddr lsa;
+ len_and_sockaddr *lsa_ptr;
+
+ lsa.len = LSA_SIZEOF_SA;
+ if (get_name(fd, &lsa.u.sa, &lsa.len) != 0)
+ return NULL;