00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025
00026
00027
00028
00029 static void wins_proxy_name_query_request_success( struct subnet_record *subrec,
00030 struct userdata_struct *userdata,
00031 struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec)
00032 {
00033 unstring name;
00034 struct packet_struct *original_packet;
00035 struct subnet_record *orig_broadcast_subnet;
00036 struct name_record *namerec = NULL;
00037 uint16 nb_flags;
00038 int num_ips;
00039 int i;
00040 int ttl = 3600;
00041 struct in_addr *iplist;
00042
00043
00044
00045
00046 memcpy( (char *)&orig_broadcast_subnet, userdata->data, sizeof(struct subnet_record *) );
00047 memcpy( (char *)&original_packet, &userdata->data[sizeof(struct subnet_record *)],
00048 sizeof(struct packet_struct *) );
00049
00050 if (rrec) {
00051 nb_flags = get_nb_flags( rrec->rdata );
00052 num_ips = rrec->rdlength / 6;
00053 } else {
00054 nb_flags = 0;
00055 num_ips = 0;
00056 }
00057
00058 if(num_ips == 0) {
00059 DEBUG(0,("wins_proxy_name_query_request_success: Invalid number of IP records (0) \
00060 returned for name %s.\n", nmb_namestr(nmbname) ));
00061 return;
00062 }
00063
00064 if(num_ips == 1) {
00065 iplist = &ip;
00066 } else {
00067 if((iplist = SMB_MALLOC_ARRAY( struct in_addr, num_ips )) == NULL) {
00068 DEBUG(0,("wins_proxy_name_query_request_success: malloc fail !\n"));
00069 return;
00070 }
00071
00072 for(i = 0; i < num_ips; i++) {
00073 putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
00074 }
00075 }
00076
00077
00078
00079 if(rrec->ttl == PERMANENT_TTL) {
00080 ttl = lp_max_ttl();
00081 }
00082
00083 pull_ascii_nstring(name, sizeof(name), nmbname->name);
00084 add_name_to_subnet( orig_broadcast_subnet, name,
00085 nmbname->name_type, nb_flags, ttl,
00086 WINS_PROXY_NAME, num_ips, iplist );
00087
00088 if(iplist != &ip) {
00089 SAFE_FREE(iplist);
00090 }
00091
00092 namerec = find_name_on_subnet(orig_broadcast_subnet, nmbname, FIND_ANY_NAME);
00093 if (!namerec) {
00094 DEBUG(0,("wins_proxy_name_query_request_success: failed to add "
00095 "name %s to subnet %s !\n",
00096 name,
00097 orig_broadcast_subnet->subnet_name ));
00098 return;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 if(namerec && original_packet->packet.nmb.header.nm_flags.bcast) {
00110 for( i = 0; i < namerec->data.num_ips; i++) {
00111 if( same_net( namerec->data.ip[i], orig_broadcast_subnet->myip,
00112 orig_broadcast_subnet->mask_ip ) ) {
00113 DEBUG( 5, ( "wins_proxy_name_query_request_success: name %s is a WINS \
00114 proxy name and is also on the same subnet (%s) as the requestor. \
00115 Not replying.\n", nmb_namestr(&namerec->name), orig_broadcast_subnet->subnet_name ) );
00116 return;
00117 }
00118 }
00119 }
00120
00121
00122 reply_netbios_packet(original_packet,
00123 0,
00124 NMB_QUERY,
00125 NMB_NAME_QUERY_OPCODE,
00126 ttl,
00127 rrec->rdata,
00128 rrec->rdlength);
00129 }
00130
00131
00132
00133
00134
00135 static void wins_proxy_name_query_request_fail(struct subnet_record *subrec,
00136 struct response_record *rrec,
00137 struct nmb_name *question_name, int fail_code)
00138 {
00139 DEBUG(4,("wins_proxy_name_query_request_fail: WINS server returned error code %d for lookup \
00140 of name %s.\n", fail_code, nmb_namestr(question_name) ));
00141 }
00142
00143
00144
00145
00146
00147
00148 static struct userdata_struct *wins_proxy_userdata_copy_fn(struct userdata_struct *userdata)
00149 {
00150 struct packet_struct *p, *copy_of_p;
00151 struct userdata_struct *new_userdata = (struct userdata_struct *)SMB_MALLOC( userdata->userdata_len );
00152
00153 if(new_userdata == NULL)
00154 return NULL;
00155
00156 new_userdata->copy_fn = userdata->copy_fn;
00157 new_userdata->free_fn = userdata->free_fn;
00158 new_userdata->userdata_len = userdata->userdata_len;
00159
00160
00161 memcpy( new_userdata->data, userdata->data, sizeof(struct subnet_record *) );
00162
00163
00164 memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)], sizeof(struct packet_struct *) );
00165
00166
00167 if((copy_of_p = copy_packet(p)) == NULL) {
00168 SAFE_FREE(new_userdata);
00169 return NULL;
00170 }
00171
00172
00173 copy_of_p->locked = True;
00174
00175 memcpy( &new_userdata->data[sizeof(struct subnet_record *)], (char *)©_of_p,
00176 sizeof(struct packet_struct *) );
00177
00178 return new_userdata;
00179 }
00180
00181
00182
00183
00184
00185
00186 static void wins_proxy_userdata_free_fn(struct userdata_struct *userdata)
00187 {
00188 struct packet_struct *p;
00189
00190
00191 memcpy((char *)&p, &userdata->data[sizeof(struct subnet_record *)],
00192 sizeof(struct packet_struct *));
00193
00194
00195 p->locked = False;
00196
00197 free_packet(p);
00198 ZERO_STRUCTP(userdata);
00199 SAFE_FREE(userdata);
00200 }
00201
00202
00203
00204
00205
00206 void make_wins_proxy_name_query_request( struct subnet_record *subrec,
00207 struct packet_struct *incoming_packet,
00208 struct nmb_name *question_name)
00209 {
00210 union {
00211 struct userdata_struct ud;
00212 char c[sizeof(struct userdata_struct) + sizeof(struct subrec *) +
00213 sizeof(struct packet_struct *)+sizeof(long*)];
00214 } ud;
00215 struct userdata_struct *userdata = &ud.ud;
00216 unstring qname;
00217
00218 memset(&ud, '\0', sizeof(ud));
00219
00220 userdata->copy_fn = wins_proxy_userdata_copy_fn;
00221 userdata->free_fn = wins_proxy_userdata_free_fn;
00222 userdata->userdata_len = sizeof(ud);
00223 memcpy( userdata->data, (char *)&subrec, sizeof(struct subnet_record *));
00224 memcpy( &userdata->data[sizeof(struct subnet_record *)], (char *)&incoming_packet,
00225 sizeof(struct packet_struct *));
00226
00227
00228 pull_ascii_nstring(qname, sizeof(qname), question_name->name);
00229 query_name( unicast_subnet, qname, question_name->name_type,
00230 wins_proxy_name_query_request_success,
00231 wins_proxy_name_query_request_fail,
00232 userdata);
00233 }