mirror of https://github.com/dzavalishin/oskit/
213 lines
4.5 KiB
C
Executable File
213 lines
4.5 KiB
C
Executable File
/*
|
|
* Copyright (c) 1997-1998 University of Utah and the Flux Group.
|
|
* All rights reserved.
|
|
*
|
|
* This file is part of the Flux OSKit. The OSKit is free software, also known
|
|
* as "open source;" you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License (GPL), version 2, as published by the Free
|
|
* Software Foundation (FSF). To explore alternate licensing terms, contact
|
|
* the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
|
|
*
|
|
* The OSKit 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 GPL for more details. You should have
|
|
* received a copy of the GPL along with the OSKit; see the file COPYING. If
|
|
* not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include <oskit/clientos.h>
|
|
#include <oskit/io/netio.h>
|
|
#include <oskit/dpf.h>
|
|
#include <oskit/pd.h>
|
|
#include <malloc.h>
|
|
#include <stdio.h> /* for debugging printf()s */
|
|
|
|
/*#include "pd.h"*/
|
|
#include "../com/sfs_hashtab.h"
|
|
|
|
#define HASHTAB_SIZE 1024
|
|
|
|
void
|
|
hashremove(hashtab_key_t k, hashtab_datum_t d, void *args) {}
|
|
|
|
oskit_u32_t
|
|
hashfunc(hashtab_key_t key)
|
|
{
|
|
oskit_u32_t h = (oskit_u32_t) key;
|
|
return h % HASHTAB_SIZE;
|
|
}
|
|
|
|
/*
|
|
* This is called when the netio object created is no longer used.
|
|
* We `cleanup' -- release the storage, since there are
|
|
* no more references to it anyway.
|
|
*/
|
|
static void
|
|
cleanup(void *param)
|
|
{
|
|
osenv_mem_free(param, 0, sizeof(oskit_pd_t));
|
|
}
|
|
|
|
/* Our keys are really just integers */
|
|
oskit_s32_t keycmpfunc(hashtab_key_t key1, hashtab_key_t key2)
|
|
{
|
|
return !(key1 == key2);
|
|
}
|
|
|
|
static oskit_error_t
|
|
recv(void *param, oskit_bufio_t *b, oskit_size_t pkt_size)
|
|
{
|
|
oskit_pd_t *pd = (oskit_pd_t *)param;
|
|
oskit_netio_t *netio;
|
|
oskit_s32_t fid;
|
|
oskit_s32_t err;
|
|
char *pkt;
|
|
|
|
osenv_assert(param);
|
|
osenv_assert(b);
|
|
|
|
err = oskit_bufio_map(b, (void **)&pkt, 0, pkt_size);
|
|
if (err) {
|
|
return OSKIT_E_UNEXPECTED;
|
|
}
|
|
|
|
switch (pd->ft) {
|
|
case OSKIT_PD_FILTER_DPF_INTERP:
|
|
fid = oskit_dpf_iptr(pkt, pkt_size);
|
|
break;
|
|
default:
|
|
return OSKIT_E_NOTIMPL;
|
|
}
|
|
|
|
if (fid != 0) {
|
|
netio = (oskit_netio_t *)hashtab_search(pd->ht, (hashtab_key_t)fid);
|
|
osenv_assert(netio);
|
|
oskit_netio_push(netio, b, pkt_size);
|
|
} else {
|
|
oskit_netio_push(pd->default_netio, b, pkt_size);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifndef NULL
|
|
#define NULL 0
|
|
#endif // NULL
|
|
|
|
oskit_s32_t
|
|
oskit_packet_dispatcher_create(oskit_pd_t **ppd,
|
|
oskit_u32_t ft,
|
|
oskit_netio_t **push_netio,
|
|
oskit_netio_t *default_outgoing)
|
|
{
|
|
oskit_netio_t *pnetio;
|
|
oskit_pd_t *pd;
|
|
oskit_s32_t err;
|
|
|
|
osenv_assert(ppd);
|
|
osenv_assert(push_netio);
|
|
osenv_assert(default_outgoing);
|
|
|
|
/* create a new oskit_pd_t struct. */
|
|
if ((*ppd = (oskit_pd_t *)malloc(sizeof *pd)) == NULL) {
|
|
return OSKIT_ENOMEM;
|
|
}
|
|
pd = *ppd; /* for tidiness */
|
|
|
|
/* create the PID table */
|
|
if ((pd->ht = hashtab_create(hashfunc, keycmpfunc, HASHTAB_SIZE)) == NULL) {
|
|
err = OSKIT_ENOMEM;
|
|
goto error;
|
|
}
|
|
|
|
pd->default_netio = default_outgoing;
|
|
pd->ft = ft;
|
|
|
|
/*
|
|
* Set up the filter netio.
|
|
* Probably all types will use this same code.
|
|
*/
|
|
switch (ft) {
|
|
case OSKIT_PD_FILTER_DPF_INTERP:
|
|
pnetio = oskit_netio_create_cleanup(recv, pd, cleanup);
|
|
if (!pnetio) {
|
|
err = OSKIT_E_UNEXPECTED;
|
|
goto error;
|
|
}
|
|
*push_netio = pnetio;
|
|
break;
|
|
default:
|
|
err = OSKIT_E_NOTIMPL;
|
|
goto error;
|
|
}
|
|
|
|
return 0;
|
|
|
|
error:
|
|
*ppd = 0;
|
|
free(*ppd);
|
|
return err;
|
|
}
|
|
|
|
oskit_s32_t
|
|
oskit_packet_dispatcher_register(oskit_pd_t *pd,
|
|
oskit_s32_t *pfid,
|
|
oskit_netio_t *out_netio,
|
|
void *pdescr,
|
|
oskit_s32_t sz)
|
|
{
|
|
oskit_s32_t hterr;
|
|
|
|
osenv_assert(pd);
|
|
osenv_assert(pfid);
|
|
osenv_assert(out_netio);
|
|
osenv_assert(pdescr);
|
|
|
|
switch (pd->ft) {
|
|
case OSKIT_PD_FILTER_DPF_INTERP:
|
|
*pfid = oskit_dpf_insert(pdescr, sz);
|
|
osenv_assert(*pfid);
|
|
break;
|
|
default:
|
|
return OSKIT_E_NOTIMPL;
|
|
}
|
|
|
|
|
|
hterr = hashtab_insert(pd->ht, (hashtab_key_t) *pfid,
|
|
(hashtab_datum_t)out_netio);
|
|
if (hterr != HASHTAB_SUCCESS) {
|
|
oskit_dpf_delete(*pfid);
|
|
*pfid = 0;
|
|
return OSKIT_E_UNEXPECTED;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
oskit_s32_t
|
|
oskit_packet_dispatcher_delete(oskit_pd_t *pd,
|
|
oskit_s32_t fid)
|
|
{
|
|
oskit_s32_t hterr;
|
|
|
|
osenv_assert(pd);
|
|
|
|
switch (pd->ft) {
|
|
case OSKIT_PD_FILTER_DPF_INTERP:
|
|
oskit_dpf_delete(fid);
|
|
break;
|
|
default:
|
|
return OSKIT_E_NOTIMPL;
|
|
}
|
|
|
|
hterr = hashtab_remove(pd->ht, (hashtab_key_t) fid, hashremove, 0);
|
|
if (hterr != HASHTAB_SUCCESS) {
|
|
return OSKIT_E_UNEXPECTED;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|