summaryrefslogtreecommitdiff
path: root/source3/libsmb/nmblib.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2000-01-03 03:17:16 +0000
committerAndrew Tridgell <tridge@samba.org>2000-01-03 03:17:16 +0000
commit574788039f53fada4769731ea3fafe9710417b71 (patch)
tree98e454727d3fe01fc12b921cb7b3fe0b9e2ce8ad /source3/libsmb/nmblib.c
parentc0ad729de6a09cb6334f49ca31d606c215f30632 (diff)
downloadsamba-574788039f53fada4769731ea3fafe9710417b71.tar.gz
samba-574788039f53fada4769731ea3fafe9710417b71.tar.bz2
samba-574788039f53fada4769731ea3fafe9710417b71.zip
added the unexpected packet database (unexpected.tdb)
this means "nmblookup -S" now always works, even with broken servers the database stores all unexpected replies and these can be accessed by any client. while doing this I cleaned up a couple of functions, and put in place a better trn_id generator. in most places the code got quite a bit simpler due to the addition of simple helper functions. I haven't yet put the code in to take advantage of this for pdc replies - that will be next. Jeremys pdc finding code will then work :) (This used to be commit 280e6359d36c9bc8dcded302f15c3a1db8e3feeb)
Diffstat (limited to 'source3/libsmb/nmblib.c')
-rw-r--r--source3/libsmb/nmblib.c174
1 files changed, 110 insertions, 64 deletions
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 3b14fd2c6b..13f7e11123 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -678,55 +678,69 @@ void free_packet(struct packet_struct *packet)
}
/*******************************************************************
- read a packet from a socket and parse it, returning a packet ready
- to be used or put on the queue. This assumes a UDP socket
+parse a packet buffer into a packet structure
******************************************************************/
-struct packet_struct *read_packet(int fd,enum packet_type packet_type)
+struct packet_struct *parse_packet(char *buf,int length,
+ enum packet_type packet_type)
{
- extern struct in_addr lastip;
- extern int lastport;
- struct packet_struct *packet;
- char buf[MAX_DGRAM_SIZE];
- int length;
- BOOL ok=False;
-
- length = read_udp_socket(fd,buf,sizeof(buf));
- if (length < MIN_DGRAM_SIZE) return(NULL);
-
- packet = (struct packet_struct *)malloc(sizeof(*packet));
- if (!packet) return(NULL);
-
- packet->next = NULL;
- packet->prev = NULL;
- packet->ip = lastip;
- packet->port = lastport;
- packet->fd = fd;
- packet->locked = False;
- packet->timestamp = time(NULL);
- packet->packet_type = packet_type;
- switch (packet_type)
- {
- case NMB_PACKET:
- ok = parse_nmb(buf,length,&packet->packet.nmb);
- break;
+ extern struct in_addr lastip;
+ extern int lastport;
+ struct packet_struct *p;
+ BOOL ok=False;
+
+ p = (struct packet_struct *)malloc(sizeof(*p));
+ if (!p) return(NULL);
+
+ p->next = NULL;
+ p->prev = NULL;
+ p->ip = lastip;
+ p->port = lastport;
+ p->locked = False;
+ p->timestamp = time(NULL);
+ p->packet_type = packet_type;
+
+ switch (packet_type) {
+ case NMB_PACKET:
+ ok = parse_nmb(buf,length,&p->packet.nmb);
+ break;
+
+ case DGRAM_PACKET:
+ ok = parse_dgram(buf,length,&p->packet.dgram);
+ break;
+ }
- case DGRAM_PACKET:
- ok = parse_dgram(buf,length,&packet->packet.dgram);
- break;
- }
- if (!ok) {
- DEBUG(10,("read_packet: discarding packet id = %d\n",
- packet->packet.nmb.header.name_trn_id));
- free_packet(packet);
- return(NULL);
- }
+ if (!ok) {
+ free_packet(p);
+ return NULL;
+ }
- num_good_receives++;
+ return p;
+}
- DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
- length, inet_ntoa(packet->ip), packet->port ) );
+/*******************************************************************
+ read a packet from a socket and parse it, returning a packet ready
+ to be used or put on the queue. This assumes a UDP socket
+ ******************************************************************/
+struct packet_struct *read_packet(int fd,enum packet_type packet_type)
+{
+ struct packet_struct *packet;
+ char buf[MAX_DGRAM_SIZE];
+ int length;
+
+ length = read_udp_socket(fd,buf,sizeof(buf));
+ if (length < MIN_DGRAM_SIZE) return(NULL);
+
+ packet = parse_packet(buf, length, packet_type);
+ if (!packet) return NULL;
- return(packet);
+ packet->fd = fd;
+
+ num_good_receives++;
+
+ DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
+ length, inet_ntoa(packet->ip), packet->port ) );
+
+ return(packet);
}
@@ -901,6 +915,26 @@ static int build_nmb(char *buf,struct packet_struct *p)
/*******************************************************************
+linearise a packet
+ ******************************************************************/
+int build_packet(char *buf, struct packet_struct *p)
+{
+ int len = 0;
+
+ switch (p->packet_type) {
+ case NMB_PACKET:
+ len = build_nmb(buf,p);
+ break;
+
+ case DGRAM_PACKET:
+ len = build_dgram(buf,p);
+ break;
+ }
+
+ return len;
+}
+
+/*******************************************************************
send a packet_struct
******************************************************************/
BOOL send_packet(struct packet_struct *p)
@@ -910,17 +944,7 @@ BOOL send_packet(struct packet_struct *p)
memset(buf,'\0',sizeof(buf));
- switch (p->packet_type)
- {
- case NMB_PACKET:
- len = build_nmb(buf,p);
- debug_nmb_packet(p);
- break;
-
- case DGRAM_PACKET:
- len = build_dgram(buf,p);
- break;
- }
+ len = build_packet(buf, p);
if (!len) return(False);
@@ -933,20 +957,42 @@ BOOL send_packet(struct packet_struct *p)
***************************************************************************/
struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
{
- fd_set fds;
- struct timeval timeout;
+ fd_set fds;
+ struct timeval timeout;
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
- timeout.tv_sec = t/1000;
- timeout.tv_usec = 1000*(t%1000);
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
+ timeout.tv_sec = t/1000;
+ timeout.tv_usec = 1000*(t%1000);
- sys_select(fd+1,&fds,&timeout);
+ sys_select(fd+1,&fds,&timeout);
- if (FD_ISSET(fd,&fds))
- return(read_packet(fd,type));
+ if (FD_ISSET(fd,&fds))
+ return(read_packet(fd,type));
+
+ return(NULL);
+}
+
+
+/****************************************************************************
+ receive a UDP/137 packet either via UDP or from the unexpected packet
+ queue. The packet must be a reply packet and have the specified trn_id
+ The timeout is in milliseconds
+ ***************************************************************************/
+struct packet_struct *receive_reply_packet(int fd, int t, int trn_id)
+{
+ struct packet_struct *p;
+
+ p = receive_packet(fd, NMB_PACKET, t);
+
+ if (p && p->packet.nmb.header.response &&
+ p->packet.nmb.header.name_trn_id == trn_id) {
+ return p;
+ }
+ if (p) free_packet(p);
- return(NULL);
+ /* try the unexpected packet queue */
+ return receive_unexpected_137(trn_id);
}