BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
BOOL send_packet(struct packet_struct *p);
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
+void sort_query_replies(char *data, int n, struct in_addr ip);
/*The following definitions come from libsmb/nterr.c */
}
+/****************************************************************************
+return the number of bits that match between two 4 character buffers
+ ***************************************************************************/
+static int matching_bits(uchar *p1, uchar *p2)
+{
+ int i, j, ret = 0;
+ for (i=0; i<4; i++) {
+ if (p1[i] != p2[i]) break;
+ ret += 8;
+ }
+
+ if (i==4) return ret;
+
+ for (j=0; j<8; j++) {
+ if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
+ ret++;
+ }
+
+ return ret;
+}
+
+
+static uchar sort_ip[4];
+
+/****************************************************************************
+compare two query reply records
+ ***************************************************************************/
+static int name_query_comp(uchar *p1, uchar *p2)
+{
+ return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
+}
+
+/****************************************************************************
+sort a set of 6 byte name query response records so that the IPs that
+have the most leading bits in common with the specified address come first
+ ***************************************************************************/
+void sort_query_replies(char *data, int n, struct in_addr ip)
+{
+ if (n <= 1) return;
+
+ putip(sort_ip, (char *)&ip);
+
+ qsort(data, n, 6, name_query_comp);
+}
set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
}
+
+ sort_query_replies(prdata, i, p->ip);
+
reply_data_len = namerec->data.num_ips * 6;
success = True;
}
char *prdata = rdata;
int reply_data_len = 0;
int ttl = 0;
- int i = 0;
- int j;
+ int i;
bzero(rdata,6);
if(rcode == 0)
{
- int same_net_index = -1;
-
ttl = (namerec->data.death_time != PERMANENT_TTL) ?
namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
return;
}
-
- /*
- * Look over the known IP addresses and see if one of them
- * is on the same (local) net as the requesting IP address. If so then
- * put that IP address into the packet as the first IP.
- * We can only do this for local nets as they're the only
- * ones we know the netmask for.
- */
-
- i = 0;
-
- if(is_local_net(p->ip))
- {
- struct in_addr *n_mask = iface_nmask(p->ip);
-
- for( j = 0; j < namerec->data.num_ips; j++)
- {
- if(same_net( namerec->data.ip[j], p->ip, *n_mask))
- {
- set_nb_flags(&prdata[0],namerec->data.nb_flags);
- putip((char *)&prdata[2], &namerec->data.ip[j]);
- same_net_index = j;
- i = 1;
- }
- }
- }
}
- for(j = 0; j < namerec->data.num_ips; j++)
+ for(i = 0; i < namerec->data.num_ips; i++)
{
- if(j == same_net_index)
- continue;
set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[j]);
- i++;
+ putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
}
- reply_data_len = namerec->data.num_ips * 6;
+ sort_query_replies(prdata, i, p->ip);
+
+ reply_data_len = namerec->data.num_ips * 6;
}
reply_netbios_packet(p, /* Packet to reply to. */