Changeset 745 for trunk/server/source3/nmbd/nmbd_packets.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/nmbd/nmbd_packets.c
r620 r745 5 5 Copyright (C) Luke Kenneth Casson Leighton 1994-1998 6 6 Copyright (C) Jeremy Allison 1994-2003 7 7 8 8 This program is free software; you can redistribute it and/or modify 9 9 it under the terms of the GNU General Public License as published by 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 20 */ 22 21 23 22 #include "includes.h" 23 #include "nmbd/nmbd.h" 24 #include "../lib/util/select.h" 25 #include "system/select.h" 26 #include "libsmb/libsmb.h" 24 27 25 28 extern int ClientNMB; … … 30 33 31 34 bool rescan_listen_set = False; 35 36 static struct nb_packet_server *packet_server; 37 38 bool nmbd_init_packet_server(void) 39 { 40 NTSTATUS status; 41 42 status = nb_packet_server_create( 43 NULL, nmbd_event_context(), 44 lp_parm_int(-1, "nmbd", "unexpected_clients", 200), 45 &packet_server); 46 if (!NT_STATUS_IS_OK(status)) { 47 DEBUG(0, ("ERROR: nb_packet_server_create failed: %s\n", 48 nt_errstr(status))); 49 return false; 50 } 51 return true; 52 } 32 53 33 54 … … 89 110 **************************************************************************/ 90 111 91 static void debug_browse_data(c har *outbuf, int len)112 static void debug_browse_data(const char *outbuf, int len) 92 113 { 93 114 int i,j; … … 105 126 if (x < 32 || x > 127) 106 127 x = '.'; 107 128 108 129 DEBUGADD( 4, ( "%c", x ) ); 109 130 } … … 159 180 return False; 160 181 } 161 182 162 183 return True; 163 184 } … … 184 205 return NULL; 185 206 } 186 207 187 208 memset((char *)packet,'\0',sizeof(*packet)); 188 209 … … 196 217 nmb->header.nm_flags.authoritative = False; 197 218 nmb->header.nm_flags.bcast = bcast; 198 219 199 220 nmb->header.rcode = 0; 200 221 nmb->header.qdcount = 1; … … 213 234 packet->packet_type = NMB_PACKET; 214 235 packet->locked = False; 215 236 216 237 return packet; /* Caller must free. */ 217 238 } … … 237 258 nmb->additional->rr_type = RR_TYPE_NB; 238 259 nmb->additional->rr_class = RR_CLASS_IN; 239 260 240 261 /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */ 241 262 if (nmb->header.nm_flags.bcast) … … 243 264 else 244 265 nmb->additional->ttl = lp_max_ttl(); 245 266 246 267 nmb->additional->rdlength = 6; 247 268 248 269 set_nb_flags(nmb->additional->rdata,nb_flags); 249 270 250 271 /* Set the address for the name we are registering. */ 251 272 putip(&nmb->additional->rdata[2], register_ip); 252 273 253 274 /* 254 275 it turns out that Jeremys code was correct, we are supposed … … 295 316 { 296 317 struct nmb_packet *nmb = NULL; 297 318 298 319 nmb = &packet->packet.nmb; 299 320 300 321 nmb->header.opcode = NMB_NAME_QUERY_OPCODE; 301 322 nmb->header.arcount = 0; 302 323 303 324 nmb->header.nm_flags.recursion_desired = False; 304 325 305 326 DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n", 306 327 nmb_namestr(&nmb->question.question_name), 307 328 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip))); 308 329 309 330 return send_netbios_packet( packet ); 310 331 } … … 350 371 351 372 nmb->header.nm_flags.recursion_desired = True; 352 373 353 374 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False) 354 375 return False; 355 376 356 377 DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \ 357 378 for name %s IP %s (bcast=%s) to IP %s\n", … … 479 500 480 501 in_addr_to_sockaddr_storage(&ss, subrec->bcast_ip); 481 pss = iface_ip((struct sockaddr *) &ss);502 pss = iface_ip((struct sockaddr *)(void *)&ss); 482 503 if (!pss || pss->ss_family != AF_INET) { 483 504 p->locked = False; … … 589 610 struct response_record *rrec; 590 611 bool ret; 591 612 592 613 /* Sanity check. */ 593 614 if(subrec != unicast_subnet) { … … 599 620 if(assert_check_subnet(subrec)) 600 621 return NULL; 601 622 602 623 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL) 603 624 return NULL; … … 613 634 return NULL; 614 635 } 615 636 616 637 if ((rrec = make_response_record(subrec, /* subnet record. */ 617 638 p, /* packet we sent. */ … … 625 646 return NULL; 626 647 } 627 648 628 649 return rrec; 629 650 } … … 687 708 Queue a query name packet to the broadcast address of a subnet. 688 709 ****************************************************************************/ 689 710 690 711 struct response_record *queue_query_name( struct subnet_record *subrec, 691 712 response_function resp_fn, … … 704 725 705 726 to_ip = subrec->bcast_ip; 706 727 707 728 /* queries to the WINS server turn up here as queries to IP 0.0.0.0 708 729 These need to be handled a bit differently */ … … 1012 1033 void queue_packet(struct packet_struct *packet) 1013 1034 { 1014 struct packet_struct *p; 1015 1016 if (!packet_queue) { 1017 packet->prev = NULL; 1018 packet->next = NULL; 1019 packet_queue = packet; 1020 return; 1021 } 1022 1023 /* find the bottom */ 1024 for (p=packet_queue;p->next;p=p->next) 1025 ; 1026 1027 p->next = packet; 1028 packet->next = NULL; 1029 packet->prev = p; 1035 DLIST_ADD_END(packet_queue, packet, struct packet_struct *); 1030 1036 } 1031 1037 … … 1058 1064 ****************************************************************************/ 1059 1065 1060 static void process_browse_packet(struct packet_struct *p, c har *buf,int len)1066 static void process_browse_packet(struct packet_struct *p, const char *buf,int len) 1061 1067 { 1062 1068 struct dgram_packet *dgram = &p->packet.dgram; … … 1145 1151 ****************************************************************************/ 1146 1152 1147 static void process_lanman_packet(struct packet_struct *p, c har *buf,int len)1153 static void process_lanman_packet(struct packet_struct *p, const char *buf,int len) 1148 1154 { 1149 1155 struct dgram_packet *dgram = &p->packet.dgram; … … 1212 1218 static void process_dgram(struct packet_struct *p) 1213 1219 { 1214 c har *buf;1215 c har *buf2;1220 const char *buf; 1221 const char *buf2; 1216 1222 int len; 1217 1223 struct dgram_packet *dgram = &p->packet.dgram; … … 1219 1225 /* If we aren't listening to the destination name then ignore the packet */ 1220 1226 if (!listening(p,&dgram->dest_name)) { 1221 unexpected_packet(p);1227 nb_packet_dispatch(packet_server, p); 1222 1228 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n", 1223 1229 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip))); … … 1226 1232 1227 1233 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) { 1228 unexpected_packet(p);1234 nb_packet_dispatch(packet_server, p); 1229 1235 /* Don't process error packets etc yet */ 1230 1236 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \ … … 1312 1318 } 1313 1319 1314 unexpected_packet(p);1320 nb_packet_dispatch(packet_server, p); 1315 1321 } 1316 1322 … … 1432 1438 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n", 1433 1439 nmb->header.name_trn_id)); 1434 unexpected_packet(p);1440 nb_packet_dispatch(packet_server, p); 1435 1441 return NULL; 1436 1442 } … … 1583 1589 1584 1590 while ((p = packet_queue)) { 1585 packet_queue = p->next; 1586 if (packet_queue) 1587 packet_queue->prev = NULL; 1588 p->next = p->prev = NULL; 1591 DLIST_REMOVE(packet_queue, p); 1589 1592 1590 1593 switch (p->packet_type) { … … 1674 1677 ***************************************************************************/ 1675 1678 1676 static bool create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd) 1677 { 1678 int *sock_array = NULL; 1679 struct socket_attributes { 1680 enum packet_type type; 1681 bool broadcast; 1682 }; 1683 1684 static bool create_listen_pollfds(struct pollfd **pfds, 1685 struct socket_attributes **pattrs, 1686 int *pnum_sockets) 1687 { 1679 1688 struct subnet_record *subrec = NULL; 1680 1689 int count = 0; 1681 1690 int num = 0; 1682 fd_set *pset = SMB_MALLOC_P(fd_set); 1683 1684 if(pset == NULL) { 1685 DEBUG(0,("create_listen_fdset: malloc fail !\n")); 1686 return True; 1687 } 1688 1689 /* The Client* sockets */ 1690 count++; 1691 struct pollfd *fds; 1692 struct socket_attributes *attrs; 1693 1694 /* The ClientNMB and ClientDGRAM sockets */ 1695 count = 2; 1691 1696 1692 1697 /* Check that we can add all the fd's we need. */ 1693 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) 1694 count++; 1695 1696 /* each interface gets 4 sockets */ 1697 count *= 4; 1698 1699 if(count >= FD_SETSIZE) { 1700 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \ 1701 only use %d.\n", count, FD_SETSIZE)); 1702 SAFE_FREE(pset); 1703 return True; 1704 } 1705 1706 if((sock_array = SMB_MALLOC_ARRAY(int, count)) == NULL) { 1707 DEBUG(0,("create_listen_fdset: malloc fail for socket array. size %d\n", count)); 1708 SAFE_FREE(pset); 1709 return True; 1710 } 1711 1712 FD_ZERO(pset); 1713 1714 /* Add in the lp_socket_address() interface on 137. */ 1715 if (ClientNMB < 0 || ClientNMB >= FD_SETSIZE) { 1716 errno = EBADF; 1717 SAFE_FREE(pset); 1718 return True; 1719 } 1720 1721 FD_SET(ClientNMB,pset); 1722 sock_array[num++] = ClientNMB; 1723 *maxfd = MAX( *maxfd, ClientNMB); 1724 1725 /* the lp_socket_address() interface has only one socket */ 1726 sock_array[num++] = -1; 1727 1728 /* Add in the 137 sockets on all the interfaces. */ 1698 for (subrec = FIRST_SUBNET; 1699 subrec != NULL; 1700 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { 1701 count += 2; /* nmb_sock and dgram_sock */ 1702 if (subrec->nmb_bcast != -1) { 1703 count += 1; 1704 } 1705 if (subrec->dgram_bcast != -1) { 1706 count += 1; 1707 } 1708 } 1709 1710 fds = TALLOC_ZERO_ARRAY(NULL, struct pollfd, count); 1711 if (fds == NULL) { 1712 DEBUG(1, ("create_listen_pollfds: malloc fail for fds. " 1713 "size %d\n", count)); 1714 return true; 1715 } 1716 1717 attrs = TALLOC_ARRAY(NULL, struct socket_attributes, count); 1718 if (fds == NULL) { 1719 DEBUG(1, ("create_listen_pollfds: malloc fail for attrs. " 1720 "size %d\n", count)); 1721 SAFE_FREE(fds); 1722 return true; 1723 } 1724 1725 num = 0; 1726 1727 fds[num].fd = ClientNMB; 1728 attrs[num].type = NMB_PACKET; 1729 attrs[num].broadcast = false; 1730 num += 1; 1731 1732 fds[num].fd = ClientDGRAM; 1733 attrs[num].type = DGRAM_PACKET; 1734 attrs[num].broadcast = false; 1735 num += 1; 1736 1729 1737 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { 1730 if (subrec->nmb_sock < 0 || subrec->nmb_sock >= FD_SETSIZE) { 1731 /* We have to ignore sockets outside FD_SETSIZE. */ 1732 sock_array[num++] = -1; 1733 } else { 1734 FD_SET(subrec->nmb_sock,pset); 1735 sock_array[num++] = subrec->nmb_sock; 1736 *maxfd = MAX( *maxfd, subrec->nmb_sock); 1737 } 1738 1739 if (subrec->nmb_bcast < 0 || subrec->nmb_bcast >= FD_SETSIZE) { 1740 /* We have to ignore sockets outside FD_SETSIZE. */ 1741 sock_array[num++] = -1; 1742 } else { 1743 sock_array[num++] = subrec->nmb_bcast; 1744 if (subrec->nmb_bcast != -1) { 1745 FD_SET(subrec->nmb_bcast,pset); 1746 *maxfd = MAX( *maxfd, subrec->nmb_bcast); 1747 } 1748 } 1749 } 1750 1751 /* Add in the lp_socket_address() interface on 138. */ 1752 if (ClientDGRAM < 0 || ClientDGRAM >= FD_SETSIZE) { 1753 errno = EBADF; 1754 SAFE_FREE(pset); 1755 return True; 1756 } 1757 FD_SET(ClientDGRAM,pset); 1758 sock_array[num++] = ClientDGRAM; 1759 *maxfd = MAX( *maxfd, ClientDGRAM); 1760 1761 /* the lp_socket_address() interface has only one socket */ 1762 sock_array[num++] = -1; 1763 1764 /* Add in the 138 sockets on all the interfaces. */ 1765 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { 1766 if (subrec->dgram_sock < 0 || subrec->dgram_sock >= FD_SETSIZE) { 1767 /* We have to ignore sockets outside FD_SETSIZE. */ 1768 sock_array[num++] = -1; 1769 } else { 1770 FD_SET(subrec->dgram_sock,pset); 1771 sock_array[num++] = subrec->dgram_sock; 1772 *maxfd = MAX( *maxfd, subrec->dgram_sock); 1773 } 1774 1775 if (subrec->dgram_bcast < 0 || subrec->dgram_bcast >= FD_SETSIZE) { 1776 /* We have to ignore sockets outside FD_SETSIZE. */ 1777 sock_array[num++] = -1; 1778 } else { 1779 sock_array[num++] = subrec->dgram_bcast; 1780 if (subrec->dgram_bcast != -1) { 1781 FD_SET(subrec->dgram_bcast,pset); 1782 *maxfd = MAX( *maxfd, subrec->dgram_bcast); 1783 } 1784 } 1785 } 1786 1787 SMB_ASSERT(count == num); 1788 1789 *listen_number = count; 1790 1791 SAFE_FREE(*ppset); 1792 SAFE_FREE(*psock_array); 1793 1794 *ppset = pset; 1795 *psock_array = sock_array; 1738 1739 fds[num].fd = subrec->nmb_sock; 1740 attrs[num].type = NMB_PACKET; 1741 attrs[num].broadcast = false; 1742 num += 1; 1743 1744 if (subrec->nmb_bcast != -1) { 1745 fds[num].fd = subrec->nmb_bcast; 1746 attrs[num].type = NMB_PACKET; 1747 attrs[num].broadcast = true; 1748 num += 1; 1749 } 1750 1751 fds[num].fd = subrec->dgram_sock; 1752 attrs[num].type = DGRAM_PACKET; 1753 attrs[num].broadcast = false; 1754 num += 1; 1755 1756 if (subrec->dgram_bcast != -1) { 1757 fds[num].fd = subrec->dgram_bcast; 1758 attrs[num].type = DGRAM_PACKET; 1759 attrs[num].broadcast = true; 1760 num += 1; 1761 } 1762 } 1763 1764 TALLOC_FREE(*pfds); 1765 *pfds = fds; 1766 1767 TALLOC_FREE(*pattrs); 1768 *pattrs = attrs; 1769 1770 *pnum_sockets = count; 1796 1771 1797 1772 return False; … … 1853 1828 p->packet_id = packet->packet.dgram.header.dgm_id; 1854 1829 } else { 1830 SAFE_FREE(p); 1855 1831 return false; 1856 1832 } … … 1882 1858 bool listen_for_packets(bool run_election) 1883 1859 { 1884 static fd_set *listen_set = NULL; 1860 static struct pollfd *fds = NULL; 1861 static struct socket_attributes *attrs = NULL; 1885 1862 static int listen_number = 0; 1886 static int *sock_array = NULL;1863 int num_sockets; 1887 1864 int i; 1888 static int maxfd = 0; 1889 1890 fd_set r_fds; 1891 fd_set w_fds; 1892 int selrtn; 1893 struct timeval timeout; 1865 1866 int pollrtn; 1867 int timeout; 1894 1868 #ifndef SYNC_DNS 1895 1869 int dns_fd; 1870 int dns_pollidx = -1; 1896 1871 #endif 1897 1872 struct processed_packet *processed_packet_list = NULL; 1898 1873 1899 if (listen_set == NULL|| rescan_listen_set) {1900 if (create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {1874 if ((fds == NULL) || rescan_listen_set) { 1875 if (create_listen_pollfds(&fds, &attrs, &listen_number)) { 1901 1876 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n")); 1902 1877 return True; … … 1905 1880 } 1906 1881 1907 memcpy((char *)&r_fds, (char *)listen_set, sizeof(fd_set)); 1908 FD_ZERO(&w_fds); 1882 /* 1883 * "fds" can be enlarged by event_add_to_poll_args 1884 * below. Shrink it again to what was given to us by 1885 * create_listen_pollfds. 1886 */ 1887 1888 fds = TALLOC_REALLOC_ARRAY(NULL, fds, struct pollfd, listen_number); 1889 if (fds == NULL) { 1890 return true; 1891 } 1892 num_sockets = listen_number; 1909 1893 1910 1894 #ifndef SYNC_DNS 1911 1895 dns_fd = asyncdns_fd(); 1912 if (dns_fd >= 0 && dns_fd < FD_SETSIZE) { 1913 FD_SET(dns_fd, &r_fds); 1914 maxfd = MAX( maxfd, dns_fd); 1896 if (dns_fd != -1) { 1897 fds = TALLOC_REALLOC_ARRAY(NULL, fds, struct pollfd, num_sockets+1); 1898 if (fds == NULL) { 1899 return true; 1900 } 1901 dns_pollidx = num_sockets; 1902 fds[num_sockets].fd = dns_fd; 1903 num_sockets += 1; 1915 1904 } 1916 1905 #endif 1917 1906 1907 for (i=0; i<num_sockets; i++) { 1908 fds[i].events = POLLIN|POLLHUP; 1909 } 1910 1918 1911 /* Process a signal and timer events now... */ 1919 if (run_events (nmbd_event_context(), 0, NULL, NULL)) {1912 if (run_events_poll(nmbd_event_context(), 0, NULL, 0)) { 1920 1913 return False; 1921 1914 } … … 1928 1921 */ 1929 1922 1930 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP; 1931 timeout.tv_usec = 0; 1932 1933 { 1934 struct timeval now = timeval_current(); 1935 event_add_to_select_args(nmbd_event_context(), &now, 1936 &r_fds, &w_fds, &timeout, &maxfd); 1937 } 1938 1939 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout); 1940 1941 if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) { 1923 timeout = ((run_election||num_response_packets) 1924 ? 1 : NMBD_SELECT_LOOP) * 1000; 1925 1926 event_add_to_poll_args(nmbd_event_context(), NULL, 1927 &fds, &num_sockets, &timeout); 1928 1929 pollrtn = sys_poll(fds, num_sockets, timeout); 1930 1931 if (run_events_poll(nmbd_event_context(), pollrtn, fds, num_sockets)) { 1942 1932 return False; 1943 1933 } 1944 1934 1945 if ( selrtn == -1) {1935 if (pollrtn == -1) { 1946 1936 return False; 1947 1937 } 1948 1938 1949 1939 #ifndef SYNC_DNS 1950 if (dns_fd != -1 && FD_ISSET(dns_fd,&r_fds)) { 1940 if ((dns_fd != -1) && (dns_pollidx != -1) && 1941 (fds[dns_pollidx].revents & (POLLIN|POLLHUP|POLLERR))) { 1951 1942 run_dns_queue(); 1952 1943 } … … 1960 1951 int client_port; 1961 1952 1962 if ( sock_array[i] == -1) {1953 if ((fds[i].revents & (POLLIN|POLLHUP|POLLERR)) == 0) { 1963 1954 continue; 1964 1955 } 1965 1956 1966 if (!FD_ISSET(sock_array[i],&r_fds)) { 1967 continue; 1968 } 1969 1970 if (i < (listen_number/2)) { 1957 if (attrs[i].type == NMB_PACKET) { 1971 1958 /* Port 137 */ 1972 1959 packet_type = NMB_PACKET; … … 1982 1969 } 1983 1970 1984 packet = read_packet( sock_array[i], packet_type);1971 packet = read_packet(fds[i].fd, packet_type); 1985 1972 if (!packet) { 1986 1973 continue; … … 1992 1979 */ 1993 1980 if (lp_bind_interfaces_only() && 1994 ( sock_array[i]== client_fd) &&1981 (fds[i].fd == client_fd) && 1995 1982 (!is_local_net_v4(packet->ip))) { 1996 1983 DEBUG(7,("discarding %s packet sent to broadcast socket from %s:%d\n", … … 2018 2005 } 2019 2006 2020 2021 2007 if (is_processed_packet(processed_packet_list, packet)) { 2022 2008 DEBUG(7,("discarding duplicate packet from %s:%d\n", … … 2028 2014 store_processed_packet(&processed_packet_list, packet); 2029 2015 2030 /* 2031 * 0,2,4,... are unicast sockets 2032 * 1,3,5,... are broadcast sockets 2033 * 2034 * on broadcast socket we only receive packets 2035 * and send replies via the unicast socket. 2036 * 2037 * 0,1 and 2,3 and ... belong together. 2038 */ 2039 if ((i % 2) != 0) { 2016 if (attrs[i].broadcast) { 2040 2017 /* this is a broadcast socket */ 2041 packet->send_fd = sock_array[i-1];2018 packet->send_fd = fds[i-1].fd; 2042 2019 } else { 2043 2020 /* this is already a unicast socket */ 2044 packet->send_fd = sock_array[i];2021 packet->send_fd = fds[i].fd; 2045 2022 } 2046 2023
Note:
See TracChangeset
for help on using the changeset viewer.