libsmb/unexpected.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    handle unexpected packets
00004    Copyright (C) Andrew Tridgell 2000
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019    
00020 */
00021 
00022 #include "includes.h"
00023 
00024 static TDB_CONTEXT *tdbd = NULL;
00025 
00026 /* the key type used in the unexpeceted packet database */
00027 struct unexpected_key {
00028         enum packet_type packet_type;
00029         time_t timestamp;
00030         int count;
00031 };
00032 
00033 
00034 
00035 /****************************************************************************
00036  all unexpected packets are passed in here, to be stored in a unexpected
00037  packet database. This allows nmblookup and other tools to receive packets
00038  erroneoously sent to the wrong port by broken MS systems
00039   **************************************************************************/
00040 void unexpected_packet(struct packet_struct *p)
00041 {
00042         static int count;
00043         TDB_DATA kbuf, dbuf;
00044         struct unexpected_key key;
00045         char buf[1024];
00046         int len=0;
00047 
00048         if (!tdbd) {
00049                 tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0, 
00050                                TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
00051                                O_RDWR | O_CREAT, 0644);
00052                 if (!tdbd) {
00053                         DEBUG(0,("Failed to open unexpected.tdb\n"));
00054                         return;
00055                 }
00056         }
00057 
00058         memset(buf,'\0',sizeof(buf));
00059         
00060         len = build_packet(buf, p);
00061 
00062         ZERO_STRUCT(key);       /* needed for potential alignment */
00063 
00064         key.packet_type = p->packet_type;
00065         key.timestamp = p->timestamp;
00066         key.count = count++;
00067 
00068         kbuf.dptr = (char *)&key;
00069         kbuf.dsize = sizeof(key);
00070         dbuf.dptr = buf;
00071         dbuf.dsize = len;
00072 
00073         tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE);
00074 }
00075 
00076 
00077 static time_t lastt;
00078 
00079 /****************************************************************************
00080 delete the record if it is too old
00081   **************************************************************************/
00082 static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
00083 {
00084         struct unexpected_key key;
00085 
00086         if (kbuf.dsize != sizeof(key)) {
00087                 tdb_delete(ttdb, kbuf);
00088         }
00089 
00090         memcpy(&key, kbuf.dptr, sizeof(key));
00091 
00092         if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) {
00093                 tdb_delete(ttdb, kbuf);
00094         }
00095 
00096         return 0;
00097 }
00098 
00099 
00100 /****************************************************************************
00101 delete all old unexpected packets
00102   **************************************************************************/
00103 void clear_unexpected(time_t t)
00104 {
00105         if (!tdbd) return;
00106 
00107         if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT))
00108                 return;
00109 
00110         lastt = t;
00111 
00112         tdb_traverse(tdbd, traverse_fn, NULL);
00113 }
00114 
00115 
00116 static struct packet_struct *matched_packet;
00117 static int match_id;
00118 static enum packet_type match_type;
00119 static const char *match_name;
00120 
00121 /****************************************************************************
00122 tdb traversal fn to find a matching 137 packet
00123   **************************************************************************/
00124 static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
00125 {
00126         struct unexpected_key key;
00127         struct packet_struct *p;
00128 
00129         if (kbuf.dsize != sizeof(key)) {
00130                 return 0;
00131         }
00132 
00133         memcpy(&key, kbuf.dptr, sizeof(key));
00134 
00135         if (key.packet_type != match_type) return 0;
00136 
00137         p = parse_packet(dbuf.dptr, dbuf.dsize, match_type);
00138 
00139         if ((match_type == NMB_PACKET && 
00140              p->packet.nmb.header.name_trn_id == match_id) ||
00141             (match_type == DGRAM_PACKET && 
00142              match_mailslot_name(p, match_name))) {
00143                 matched_packet = p;
00144                 return -1;
00145         }
00146 
00147         free_packet(p);
00148 
00149         return 0;
00150 }
00151 
00152 
00153 /****************************************************************************
00154 check for a particular packet in the unexpected packet queue
00155   **************************************************************************/
00156 struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, 
00157                                          const char *mailslot_name)
00158 {
00159         TDB_CONTEXT *tdb2;
00160 
00161         tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0);
00162         if (!tdb2) return NULL;
00163 
00164         matched_packet = NULL;
00165         match_id = id;
00166         match_type = packet_type;
00167         match_name = mailslot_name;
00168 
00169         tdb_traverse(tdb2, traverse_match, NULL);
00170 
00171         tdb_close(tdb2);
00172 
00173         return matched_packet;
00174 }

Sambaに対してSat Aug 29 21:23:06 2009に生成されました。  doxygen 1.4.7