/* This code generates a comparison bitmask for the ipt_delete_entry() call.
*/
/*
* Author: Derrik Pates <dpates@dsdk12.net>
*
* 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.
*/
#define __USE_GNU
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <stdio.h>
#include "maskgen.h"
#include "loader.h"
#include "module_iface.h"
/* Generate the matchmask for iptc_delete_entry(). */
unsigned char *ipt_gen_delmask(ENTRY *entry) {
unsigned int size;
ENTRY_MATCH *match;
ENTRY_TARGET *target;
unsigned char *mask, *mptr;
ModuleDef *module;
size = entry->next_offset;
/* Setup the actual mask data field */
if(!(mask = calloc(1, size)))
return(NULL);
/* Mark off the size of a (struct ipt_entry) as data to compare against -
* an entry is never going to be smaller than this. */
memset(mask, 0xFF, sizeof(ENTRY));
mptr = mask + sizeof(ENTRY);
/* Go through each of the matches, and ask each available match module
* how much of its data should be compared. */
for(match = (void *)entry->elems;
(void *)match < (void *)entry + entry->target_offset;
match = (void *)match + match->u.match_size) {
module = ipt_find_module(match->u.user.name, MODULE_MATCH, NULL);
size = ALIGN(sizeof(ENTRY_MATCH));
if(module)
size += module->size_uspace;
else if(match->u.match_size >
ALIGN(sizeof(ENTRY_MATCH)))
size = match->u.match_size;
memset(mptr, 0xFF, size);
mptr += match->u.match_size;
}
/* Now do the same for the target, if target data exists (it probably
* will, but never hurts to be careful). */
if(entry->target_offset < entry->next_offset) {
target = (void *)entry + entry->target_offset;
module = ipt_find_module(target->u.user.name, MODULE_TARGET, NULL);
size = ALIGN(sizeof(ENTRY_TARGET));
if(module)
size += module->size_uspace;
else if(target->u.target_size >
ALIGN(sizeof(ENTRY_TARGET)))
size = target->u.target_size;
memset(mptr, 0xFF, size);
}
return(mask);
}
/* vim: ts=4
*/