diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-04-05 08:35:02 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:11:26 -0500 |
commit | 769070d502a95439ea7d6e2c6616cfa08fc5d673 (patch) | |
tree | d8bac8a0d0df76c1a135913288599d9784b0578f /source4/libcli/dgram/mailslot.c | |
parent | e1e8928840b632297e3cbbd19aeef5e075ff7798 (diff) | |
download | samba-769070d502a95439ea7d6e2c6616cfa08fc5d673.tar.gz samba-769070d502a95439ea7d6e2c6616cfa08fc5d673.tar.bz2 samba-769070d502a95439ea7d6e2c6616cfa08fc5d673.zip |
r6209: started added code to support mailslot requests over UDP/138
datagrams. This adds the IDL to parse mailslot packets, plus mailslot
dispatch and listener registration code.
mailslots are used for UDP/138 browse and netlogon packets
(This used to be commit f20e7e5200de736b3451d748ed716be638f93502)
Diffstat (limited to 'source4/libcli/dgram/mailslot.c')
-rw-r--r-- | source4/libcli/dgram/mailslot.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c new file mode 100644 index 0000000000..da9b6cdd20 --- /dev/null +++ b/source4/libcli/dgram/mailslot.c @@ -0,0 +1,132 @@ +/* + Unix SMB/CIFS implementation. + + packet handling for mailslot requests + + Copyright (C) Andrew Tridgell 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include "dlinklist.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" + +/* + destroy a mailslot handler +*/ +static int dgram_mailslot_destructor(void *ptr) +{ + struct dgram_mailslot_handler *dgmslot = + talloc_get_type(ptr, struct dgram_mailslot_handler); + + DLIST_REMOVE(dgmslot->dgmsock->mailslot_handlers, dgmslot); + return 0; +} + +/* + start listening on a mailslot. talloc_free() the handle to stop listening +*/ +struct dgram_mailslot_handler *dgram_mailslot_listen(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name, + dgram_mailslot_handler_t handler, + void *private) +{ + struct dgram_mailslot_handler *dgmslot; + + dgmslot = talloc(dgmsock, struct dgram_mailslot_handler); + if (dgmslot == NULL) return NULL; + + dgmslot->dgmsock = dgmsock; + dgmslot->mailslot_name = talloc_strdup(dgmslot, mailslot_name); + if (dgmslot->mailslot_name == NULL) { + talloc_free(dgmslot); + return NULL; + } + dgmslot->handler = handler; + dgmslot->private = private; + + DLIST_ADD(dgmsock->mailslot_handlers, dgmslot); + talloc_set_destructor(dgmslot, dgram_mailslot_destructor); + + return dgmslot; +} + +/* + find the handler for a specific mailslot name +*/ +struct dgram_mailslot_handler *dgram_mailslot_find(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name) +{ + struct dgram_mailslot_handler *h; + for (h=dgmsock->mailslot_handlers;h;h=h->next) { + if (strcasecmp(h->mailslot_name, mailslot_name) == 0) { + return h; + } + } + return NULL; +} + +/* + check that a datagram packet is a valid mailslot request, and return the + mailslot name if it is, otherwise return NULL +*/ +const char *dgram_mailslot_name(struct nbt_dgram_packet *packet) +{ + if (packet->msg_type != DGRAM_DIRECT_UNIQUE && + packet->msg_type != DGRAM_DIRECT_GROUP && + packet->msg_type != DGRAM_BCAST) { + return NULL; + } + if (packet->data.msg.dgram_body_type != DGRAM_SMB) return NULL; + if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL; + if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL; + return packet->data.msg.body.smb.body.trans.mailslot_name; +} + + +/* + create a temporary mailslot handler for a reply mailslot, allocating + a new mailslot name using the given base name and a random integer extension +*/ +struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgmsock, + const char *mailslot_name, + dgram_mailslot_handler_t handler, + void *private) +{ + char *name; + int i; + struct dgram_mailslot_handler *dgmslot; + + /* try a 100 times at most */ + for (i=0;i<100;i++) { + name = talloc_asprintf(dgmsock, "%s%u", + mailslot_name, + generate_random() % UINT16_MAX); + if (name == NULL) return NULL; + if (dgram_mailslot_find(dgmsock, name)) { + talloc_free(name); + return NULL; + } + dgmslot = dgram_mailslot_listen(dgmsock, name, handler, private); + talloc_free(name); + return dgmslot; + } + DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name)); + return NULL; +} |