Please wait until the page is fully downloaded and then press the "Expand" button or the blue line numbers.
0047001 /*
0047002 generic/psip.c
0047003
0047004 Implementation of a pseudo IP device.
0047005
0047006 Created: Apr 22, 1993 by Philip Homburg
0047007
0047008 Copyright 1995 Philip Homburg
0047009 */
0047010
0047011 #include "inet.h"
0047012 #include "assert.h"
0047013 #include "buf.h"
0047014 #include "event.h"
0047015 #include "type.h"
0047016 #include "ip_int.h"
0047017 #include "psip.h"
0047018 #include "sr.h"
0047019
0047020 #if ENABLE_PSIP
0047021
0047022 THIS_FILE
0047023
0047024 typedef struct psip_port
0047025 {
0047026 int pp_flags;
0047027 int pp_ipdev;
0047028 int pp_opencnt;
0047029 struct psip_fd *pp_rd_head;
0047030 struct psip_fd *pp_rd_tail;
0047031 acc_t *pp_promisc_head;
0047032 acc_t *pp_promisc_tail;
0047033 } psip_port_t;
0047034
0047035 #define PPF_EMPTY 0
0047036 #define PPF_CONFIGURED 1
0047037 #define PPF_ENABLED 2
0047038 #define PPF_PROMISC 4
0047039
0047040 #define PSIP_FD_NR (1*IP_PORT_MAX)
0047041
0047042 typedef struct psip_fd
0047043 {
0047044 int pf_flags;
0047045 int pf_srfd;
0047046 psip_port_t *pf_port;
0047047 get_userdata_t pf_get_userdata;
0047048 put_userdata_t pf_put_userdata;
0047049 struct psip_fd *pf_rd_next;
0047050 size_t pf_rd_count;
0047051 nwio_psipopt_t pf_psipopt;
0047052 } psip_fd_t;
0047053
0047054 #define PFF_EMPTY 0
0047055 #define PFF_INUSE 1
0047056 #define PFF_READ_IP 2
0047057 #define PFF_PROMISC 4
0047058
0047059 PRIVATE psip_port_t *psip_port_table;
0047060 PRIVATE psip_fd_t psip_fd_table[PSIP_FD_NR];
0047061
0047062 FORWARD int psip_open ARGS(( int port, int srfd,
0047063 get_userdata_t get_userdata, put_userdata_t put_userdata,
0047064 put_pkt_t pkt_pkt ));
0047065 FORWARD int psip_ioctl ARGS(( int fd, ioreq_t req ));
0047066 FORWARD int psip_read ARGS(( int fd, size_t count ));
0047067 FORWARD int psip_write ARGS(( int fd, size_t count ));
0047068 FORWARD void psip_close ARGS(( int fd ));
0047069 FORWARD int psip_cancel ARGS(( int fd, int which_operation ));
0047070 FORWARD void promisc_restart_read ARGS(( psip_port_t *psip_port ));
0047071 FORWARD int psip_setopt ARGS(( psip_fd_t *psip_fd, nwio_psipopt_t *newoptp ));
0047072 FORWARD void psip_buffree ARGS(( int priority ));
0047073 #ifdef BUF_CONSISTENCY_CHECK
0047074 FORWARD void psip_bufcheck ARGS(( void ));
0047075 #endif
0047076 FORWARD void reply_thr_put ARGS(( psip_fd_t *psip_fd, int reply,
0047077 int for_ioctl ));
0047078 FORWARD void reply_thr_get ARGS(( psip_fd_t *psip_fd, int reply,
0047079 int for_ioctl ));
0047080
0047081 PUBLIC void psip_prep()
0047082 {
0047083 psip_port_table= alloc(psip_conf_nr * sizeof(psip_port_table[0]));
0047084 }
0047085
0047086 PUBLIC void psip_init()
0047087 {
0047088 int i;
0047089 psip_port_t *psip_port;
0047090 psip_fd_t *psip_fd;
0047091
0047092 #if ZERO
0047093 for (i=0, psip_port= psip_port_table; i<psip_conf_nr; i++, psip_port++)
0047094 psip_port->pp_flags= PPF_EMPTY;
0047095
0047096 for (i=0, psip_fd= psip_fd_table; i<PSIP_FD_NR; i++, psip_fd++)
0047097 psip_fd->pf_flags= PFF_EMPTY;
0047098 #endif
0047099
0047100 for (i=0, psip_port= psip_port_table; i<psip_conf_nr; i++, psip_port++)
0047101 {
0047102 psip_port->pp_flags |= PPF_CONFIGURED;
0047103 #if ZERO
0047104 psip_port->pp_opencnt= 0;
0047105 psip_port->pp_rd_head= NULL;
0047106 psip_port->pp_promisc_head= NULL;
0047107 #endif
0047108 }
0047109
0047110 #ifndef BUF_CONSISTENCY_CHECK
0047111 bf_logon(psip_buffree);
0047112 #else
0047113 bf_logon(psip_buffree, psip_bufcheck);
0047114 #endif
0047115 }
0047116
0047117 PUBLIC int psip_enable(port_nr, ip_port_nr)
0047118 int port_nr;
0047119 int ip_port_nr;
0047120 {
0047121 psip_port_t *psip_port;
0047122
0047123 assert(port_nr >= 0 && port_nr < psip_conf_nr);
0047124
0047125 psip_port= &psip_port_table[port_nr];
0047126 assert(psip_port->pp_flags & PPF_CONFIGURED);
0047127
0047128 psip_port->pp_ipdev= ip_port_nr;
0047129 psip_port->pp_flags |= PPF_ENABLED;
0047130
0047131 sr_add_minor(if2minor(psip_conf[port_nr].pc_ifno, PSIP_DEV_OFF),
0047132 port_nr, psip_open, psip_close, psip_read,
0047133 psip_write, psip_ioctl, psip_cancel);
0047134
0047135 return NW_OK;
0047136 }
0047137
0047138 PUBLIC int psip_send(port_nr, pack)
0047139 int port_nr;
0047140 acc_t *pack;
0047141 {
0047142 psip_port_t *psip_port;
0047143 psip_fd_t *psip_fd, *mark_fd;
0047144 int i, result, result1;
0047145 size_t buf_size;
0047146 acc_t *hdr_pack;
0047147 psip_io_hdr_t *hdr;
0047148
0047149 assert(port_nr >= 0 && port_nr < psip_conf_nr);
0047150 psip_port= &psip_port_table[port_nr];
0047151
0047152 if (psip_port->pp_opencnt == 0)
0047153 {
0047154 bf_afree(pack);
0047155 return NW_OK;
0047156 }
0047157
0047158 for(;;)
0047159 {
0047160 mark_fd= psip_port->pp_rd_tail;
0047161
0047162 for(i= 0; i<PSIP_FD_NR; i++)
0047163 {
0047164 psip_fd= psip_port->pp_rd_head;
0047165 if (!psip_fd)
0047166 return NW_SUSPEND;
0047167 psip_port->pp_rd_head= psip_fd->pf_rd_next;
0047168 if (!(psip_fd->pf_flags & PFF_PROMISC))
0047169 break;
0047170 psip_fd->pf_rd_next= NULL;
0047171 if (psip_port->pp_rd_head == NULL)
0047172 psip_port->pp_rd_head= psip_fd;
0047173 else
0047174 psip_port->pp_rd_tail->pf_rd_next= psip_fd;
0047175 psip_port->pp_rd_tail= psip_fd;
0047176 if (psip_fd == mark_fd)
0047177 return NW_SUSPEND;
0047178 }
0047179 if (i == PSIP_FD_NR)
0047180 ip_panic(( "psip_send: loop" ));
0047181
0047182 assert(psip_fd->pf_flags & PFF_READ_IP);
0047183 psip_fd->pf_flags &= ~PFF_READ_IP;
0047184
0047185 buf_size= bf_bufsize(pack);
0047186 if (buf_size <= psip_fd->pf_rd_count)
0047187 {
0047188 if (psip_port->pp_flags & PPF_PROMISC)
0047189 {
0047190 /* Deal with promiscuous mode. */
0047191 hdr_pack= bf_memreq(sizeof(*hdr));
0047192 hdr= (psip_io_hdr_t *)ptr2acc_data(hdr_pack);
0047193 memset(hdr, '\0', sizeof(*hdr));
0047194 hdr->pih_flags |= PF_LOC2REM;
0047195
0047196 pack->acc_linkC++;
0047197 hdr_pack->acc_next= pack;
0047198 hdr_pack->acc_ext_link= NULL;
0047199 if (psip_port->pp_promisc_head)
0047200 {
0047201 /* Append at the end. */
0047202 psip_port->pp_promisc_tail->
0047203 acc_ext_link= hdr_pack;
0047204 psip_port->pp_promisc_tail= hdr_pack;
0047205 }
0047206 else
0047207 {
0047208 /* First packet. */
0047209 psip_port->pp_promisc_head= hdr_pack;
0047210 psip_port->pp_promisc_tail= hdr_pack;
0047211 if (psip_port->pp_rd_head)
0047212 promisc_restart_read(psip_port);
0047213 }
0047214 }
0047215 result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd,
0047216 (size_t)0, pack, FALSE);
0047217 if (result == NW_OK)
0047218 result= buf_size;
0047219 }
0047220 else
0047221 result= EPACKSIZE;
0047222
0047223 result1= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd,
0047224 (size_t)result, NULL, FALSE);
0047225 assert(result1 == NW_OK);
0047226 if (result == EPACKSIZE)
0047227 continue;
0047228 return NW_OK;
0047229 }
0047230 return NW_SUSPEND;
0047231 }
0047232
0047233 PRIVATE int psip_open(port, srfd, get_userdata, put_userdata, put_pkt)
0047234 int port;
0047235 int srfd;
0047236 get_userdata_t get_userdata;
0047237 put_userdata_t put_userdata;
0047238 put_pkt_t put_pkt;
0047239 {
0047240 psip_port_t *psip_port;
0047241 psip_fd_t *psip_fd;
0047242 int i;
0047243
0047244 assert(port >= 0 && port < psip_conf_nr);
0047245 psip_port= &psip_port_table[port];
0047246
0047247 if (!(psip_port->pp_flags & PPF_ENABLED))
0047248 return ENXIO;
0047249
0047250 for (i= 0, psip_fd= psip_fd_table; i<PSIP_FD_NR; i++, psip_fd++)
0047251 {
0047252 if (psip_fd->pf_flags & PFF_INUSE)
0047253 continue;
0047254 break;
0047255 }
0047256 if (i == PSIP_FD_NR)
0047257 return ENFILE;
0047258 psip_fd->pf_flags |= PFF_INUSE;
0047259 psip_fd->pf_srfd= srfd;
0047260 psip_fd->pf_port= psip_port;
0047261 psip_fd->pf_get_userdata= get_userdata;
0047262 psip_fd->pf_put_userdata= put_userdata;
0047263 psip_port->pp_opencnt++;
0047264
0047265 return i;
0047266 }
0047267
0047268 PRIVATE int psip_ioctl(fd, req)
0047269 int fd;
0047270 ioreq_t req;
0047271 {
0047272 int result;
0047273 psip_fd_t *psip_fd;
0047274 acc_t *data;
0047275 nwio_psipopt_t *psip_opt, *newoptp;
0047276
0047277 assert(fd >= 0 && fd < PSIP_FD_NR);
0047278 psip_fd= &psip_fd_table[fd];
0047279
0047280 switch(req)
0047281 {
0047282 case NWIOSPSIPOPT:
0047283 data= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, 0,
0047284 sizeof(*psip_opt), TRUE);
0047285 if (!data)
0047286 {
0047287 result= EFAULT;
0047288 break;
0047289 }
0047290 data= bf_packIffLess(data, sizeof(*psip_opt));
0047291 assert (data->acc_length == sizeof(*psip_opt));
0047292
0047293 newoptp= (nwio_psipopt_t *)ptr2acc_data(data);
0047294 result= psip_setopt(psip_fd, newoptp);
0047295 bf_afree(data);
0047296 if (result == NW_OK)
0047297 {
0047298 if (psip_fd->pf_psipopt.nwpo_flags & NWPO_EN_PROMISC)
0047299 {
0047300 psip_fd->pf_flags |= PFF_PROMISC;
0047301 psip_fd->pf_port->pp_flags |= PPF_PROMISC;
0047302 }
0047303 else
0047304 {
0047305 psip_fd->pf_flags &= ~PFF_PROMISC;
0047306 /* XXX check port flags */
0047307 }
0047308 }
0047309 reply_thr_get(psip_fd, result, TRUE);
0047310 break;
0047311 case NWIOGPSIPOPT:
0047312 data= bf_memreq(sizeof(*psip_opt));
0047313 psip_opt= (nwio_psipopt_t *)ptr2acc_data(data);
0047314
0047315 *psip_opt= psip_fd->pf_psipopt;
0047316 result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, 0,
0047317 data, TRUE);
0047318 if (result == NW_OK)
0047319 reply_thr_put(psip_fd, NW_OK, TRUE);
0047320 break;
0047321 default:
0047322 reply_thr_put(psip_fd, ENOTTY, TRUE);
0047323 break;
0047324 }
0047325 return NW_OK;
0047326 }
0047327
0047328 PRIVATE int psip_read(fd, count)
0047329 int fd;
0047330 size_t count;
0047331 {
0047332 psip_port_t *psip_port;
0047333 psip_fd_t *psip_fd;
0047334
0047335 assert(fd >= 0 && fd < PSIP_FD_NR);
0047336 psip_fd= &psip_fd_table[fd];
0047337 psip_port= psip_fd->pf_port;
0047338
0047339 psip_fd->pf_rd_count= count;
0047340 if (psip_port->pp_rd_head == NULL)
0047341 psip_port->pp_rd_head= psip_fd;
0047342 else
0047343 psip_port->pp_rd_tail->pf_rd_next= psip_fd;
0047344 psip_fd->pf_rd_next= NULL;
0047345 psip_port->pp_rd_tail= psip_fd;
0047346
0047347 psip_fd->pf_flags |= PFF_READ_IP;
0047348 if (psip_fd->pf_flags & PFF_PROMISC)
0047349 promisc_restart_read(psip_port);
0047350 else
0047351 ipps_get(psip_port->pp_ipdev);
0047352 if (psip_fd->pf_flags & PFF_READ_IP)
0047353 return NW_SUSPEND;
0047354 return NW_OK;
0047355 }
0047356
0047357 PRIVATE int psip_write(fd, count)
0047358 int fd;
0047359 size_t count;
0047360 {
0047361 psip_port_t *psip_port;
0047362 psip_fd_t *psip_fd;
0047363 acc_t *pack, *hdr_pack;
0047364 psip_io_hdr_t *hdr;
0047365
0047366 assert(fd >= 0 && fd < PSIP_FD_NR);
0047367 psip_fd= &psip_fd_table[fd];
0047368 psip_port= psip_fd->pf_port;
0047369
0047370 pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, (size_t)0,
0047371 count, FALSE);
0047372 if (pack == NULL)
0047373 {
0047374 pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd,
0047375 (size_t)EFAULT, (size_t)0, FALSE);
0047376 assert(pack == NULL);
0047377 return NW_OK;
0047378 }
0047379 if (psip_port->pp_flags & PPF_PROMISC)
0047380 {
0047381 /* Deal with promiscuous mode. */
0047382 hdr_pack= bf_memreq(sizeof(*hdr));
0047383 hdr= (psip_io_hdr_t *)ptr2acc_data(hdr_pack);
0047384 memset(hdr, '\0', sizeof(*hdr));
0047385 hdr->pih_flags |= PF_REM2LOC;
0047386
0047387 pack->acc_linkC++;
0047388 hdr_pack->acc_next= pack;
0047389 hdr_pack->acc_ext_link= NULL;
0047390 if (psip_port->pp_promisc_head)
0047391 {
0047392 /* Append at the end. */
0047393 psip_port->pp_promisc_tail->acc_ext_link= hdr_pack;
0047394 }
0047395 else
0047396 {
0047397 /* First packet. */
0047398 psip_port->pp_promisc_head= hdr_pack;
0047399 if (psip_port->pp_rd_head)
0047400 promisc_restart_read(psip_port);
0047401 }
0047402 }
0047403 ipps_put(psip_port->pp_ipdev, pack);
0047404 pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, (size_t)count,
0047405 (size_t)0, FALSE);
0047406 assert(pack == NULL);
0047407 return NW_OK;
0047408 }
0047409
0047410 PRIVATE void psip_close(fd)
0047411 int fd;
0047412 {
0047413 psip_port_t *psip_port;
0047414 psip_fd_t *psip_fd;
0047415 acc_t *acc, *acc_next;
0047416 int i;
0047417
0047418 assert(fd >= 0 && fd < PSIP_FD_NR);
0047419 psip_fd= &psip_fd_table[fd];
0047420 psip_port= psip_fd->pf_port;
0047421
0047422 assert(psip_port->pp_opencnt >0);
0047423 psip_port->pp_opencnt--;
0047424 psip_fd->pf_flags= PFF_EMPTY;
0047425 ipps_get(psip_port->pp_ipdev);
0047426
0047427 /* Check if the port should still be in promiscuous mode. */
0047428 if (psip_port->pp_flags & PPF_PROMISC)
0047429 {
0047430 psip_port->pp_flags &= ~PPF_PROMISC;
0047431 for (i= 0, psip_fd= psip_fd_table; i<PSIP_FD_NR;
0047432 i++, psip_fd++)
0047433 {
0047434 if ((psip_fd->pf_flags & (PFF_INUSE|PFF_PROMISC)) !=
0047435 (PFF_INUSE|PFF_PROMISC))
0047436 {
0047437 continue;
0047438 }
0047439 if (psip_fd->pf_port != psip_port)
0047440 continue;
0047441 psip_port->pp_flags |= PPF_PROMISC;
0047442 break;
0047443 }
0047444 if (!(psip_port->pp_flags & PPF_PROMISC))
0047445 {
0047446 /* Delete queued packets. */
0047447 acc= psip_port->pp_promisc_head;
0047448 psip_port->pp_promisc_head= NULL;
0047449 while (acc)
0047450 {
0047451 acc_next= acc->acc_ext_link;
0047452 bf_afree(acc);
0047453 acc= acc_next;
0047454 }
0047455 }
0047456 }
0047457 }
0047458
0047459 PRIVATE int psip_cancel(fd, which_operation)
0047460 int fd;
0047461 int which_operation;
0047462 {
0047463 psip_port_t *psip_port;
0047464 psip_fd_t *psip_fd, *prev_fd, *tmp_fd;
0047465 int result;
0047466
0047467 DBLOCK(1, printf("psip_cancel(%d, %d)\n", fd, which_operation));
0047468
0047469 assert(fd >= 0 && fd < PSIP_FD_NR);
0047470 psip_fd= &psip_fd_table[fd];
0047471 psip_port= psip_fd->pf_port;
0047472
0047473 switch(which_operation)
0047474 {
0047475 #if !CRAMPED
0047476 case SR_CANCEL_IOCTL:
0047477 ip_panic(( "should not be here" ));
0047478 #endif
0047479 case SR_CANCEL_READ:
0047480 assert(psip_fd->pf_flags & PFF_READ_IP);
0047481 for (prev_fd= NULL, tmp_fd= psip_port->pp_rd_head; tmp_fd;
0047482 prev_fd= tmp_fd, tmp_fd= tmp_fd->pf_rd_next)
0047483 {
0047484 if (tmp_fd == psip_fd)
0047485 break;
0047486 }
0047487 #if !CRAMPED
0047488 if (tmp_fd == NULL)
0047489 ip_panic(( "unable to find to request to cancel" ));
0047490 #endif
0047491 if (prev_fd == NULL)
0047492 psip_port->pp_rd_head= psip_fd->pf_rd_next;
0047493 else
0047494 prev_fd->pf_rd_next= psip_fd->pf_rd_next;
0047495 if (psip_fd->pf_rd_next == NULL)
0047496 psip_port->pp_rd_tail= prev_fd;
0047497 psip_fd->pf_flags &= ~PFF_READ_IP;
0047498 result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd,
0047499 (size_t)EINTR, NULL, FALSE);
0047500 assert(result == NW_OK);
0047501 break;
0047502 #if !CRAMPED
0047503 case SR_CANCEL_WRITE:
0047504 ip_panic(( "should not be here" ));
0047505 default:
0047506 ip_panic(( "invalid operation for cancel" ));
0047507 #endif
0047508 }
0047509 return NW_OK;
0047510 }
0047511
0047512 PRIVATE void promisc_restart_read(psip_port)
0047513 psip_port_t *psip_port;
0047514 {
0047515 psip_fd_t *psip_fd, *mark_fd;
0047516 acc_t *pack;
0047517 size_t buf_size;
0047518 int i, result, result1;
0047519
0047520 while (psip_port->pp_promisc_head)
0047521 {
0047522 mark_fd= psip_port->pp_rd_tail;
0047523
0047524 for(i= 0; i<PSIP_FD_NR; i++)
0047525 {
0047526 psip_fd= psip_port->pp_rd_head;
0047527 if (!psip_fd)
0047528 return;
0047529 psip_port->pp_rd_head= psip_fd->pf_rd_next;
0047530 if (psip_fd->pf_flags & PFF_PROMISC)
0047531 break;
0047532 psip_fd->pf_rd_next= NULL;
0047533 if (psip_port->pp_rd_head == NULL)
0047534 psip_port->pp_rd_head= psip_fd;
0047535 else
0047536 psip_port->pp_rd_tail->pf_rd_next= psip_fd;
0047537 psip_port->pp_rd_tail= psip_fd;
0047538 if (psip_fd == mark_fd)
0047539 return;
0047540 }
0047541 if (i == PSIP_FD_NR)
0047542 ip_panic(( "psip'promisc_restart_read: loop" ));
0047543
0047544 assert(psip_fd->pf_flags & PFF_READ_IP);
0047545 psip_fd->pf_flags &= ~PFF_READ_IP;
0047546
0047547 pack= psip_port->pp_promisc_head;
0047548 buf_size= bf_bufsize(pack);
0047549 if (buf_size <= psip_fd->pf_rd_count)
0047550 {
0047551 psip_port->pp_promisc_head= pack->acc_ext_link;
0047552 result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd,
0047553 (size_t)0, pack, FALSE);
0047554 if (result == NW_OK)
0047555 result= buf_size;
0047556 }
0047557 else
0047558 result= EPACKSIZE;
0047559
0047560 result1= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd,
0047561 (size_t)result, NULL, FALSE);
0047562 assert(result1 == NW_OK);
0047563 }
0047564 }
0047565
0047566 PRIVATE int psip_setopt(psip_fd, newoptp)
0047567 psip_fd_t *psip_fd;
0047568 nwio_psipopt_t *newoptp;
0047569 {
0047570 nwio_psipopt_t oldopt;
0047571 int result;
0047572 unsigned int new_en_flags, new_di_flags, old_en_flags, old_di_flags,
0047573 all_flags, flags;
0047574 unsigned long new_flags;
0047575 int i;
0047576
0047577 oldopt= psip_fd->pf_psipopt;
0047578
0047579 old_en_flags= oldopt.nwpo_flags & 0xffff;
0047580 old_di_flags= (oldopt.nwpo_flags >> 16) & 0xffff;
0047581
0047582 new_en_flags= newoptp->nwpo_flags & 0xffff;
0047583 new_di_flags= (newoptp->nwpo_flags >> 16) & 0xffff;
0047584
0047585 if (new_en_flags & new_di_flags)
0047586 return EBADMODE;
0047587
0047588 /* NWUO_LOCADDR_MASK */
0047589 if (!((new_en_flags | new_di_flags) & NWPO_PROMISC_MASK))
0047590 {
0047591 new_en_flags |= (old_en_flags & NWPO_PROMISC_MASK);
0047592 new_di_flags |= (old_di_flags & NWPO_PROMISC_MASK);
0047593 }
0047594
0047595 new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags;
0047596
0047597 psip_fd->pf_psipopt= *newoptp;
0047598 psip_fd->pf_psipopt.nwpo_flags= new_flags;
0047599
0047600 return NW_OK;
0047601 }
0047602
0047603 PRIVATE void psip_buffree (priority)
0047604 int priority;
0047605 {
0047606 int i;
0047607 psip_port_t *psip_port;
0047608 acc_t *tmp_acc, *next_acc;
0047609
0047610 if (priority == PSIP_PRI_EXP_PROMISC)
0047611 {
0047612 for (i=0, psip_port= psip_port_table; i<psip_conf_nr;
0047613 i++, psip_port++)
0047614 {
0047615 if (!(psip_port->pp_flags & PPF_CONFIGURED) )
0047616 continue;
0047617 if (psip_port->pp_promisc_head)
0047618 {
0047619 tmp_acc= psip_port->pp_promisc_head;
0047620 while(tmp_acc)
0047621 {
0047622 next_acc= tmp_acc->acc_ext_link;
0047623 bf_afree(tmp_acc);
0047624 tmp_acc= next_acc;
0047625 }
0047626 psip_port->pp_promisc_head= NULL;
0047627 }
0047628 }
0047629 }
0047630 }
0047631
0047632 #ifdef BUF_CONSISTENCY_CHECK
0047633 PRIVATE void psip_bufcheck()
0047634 {
0047635 int i;
0047636 psip_port_t *psip_port;
0047637 acc_t *tmp_acc;
0047638
0047639 for (i= 0, psip_port= psip_port_table; i<psip_conf_nr;
0047640 i++, psip_port++)
0047641 {
0047642 for (tmp_acc= psip_port->pp_promisc_head; tmp_acc;
0047643 tmp_acc= tmp_acc->acc_ext_link)
0047644 {
0047645 bf_check_acc(tmp_acc);
0047646 }
0047647 }
0047648 }
0047649 #endif
0047650
0047651 /*
0047652 reply_thr_put
0047653 */
0047654
0047655 PRIVATE void reply_thr_put(psip_fd, reply, for_ioctl)
0047656 psip_fd_t *psip_fd;
0047657 int reply;
0047658 int for_ioctl;
0047659 {
0047660 int result;
0047661
0047662 result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, reply,
0047663 (acc_t *)0, for_ioctl);
0047664 assert(result == NW_OK);
0047665 }
0047666
0047667 /*
0047668 reply_thr_get
0047669 */
0047670
0047671 PRIVATE void reply_thr_get(psip_fd, reply, for_ioctl)
0047672 psip_fd_t *psip_fd;
0047673 int reply;
0047674 int for_ioctl;
0047675 {
0047676 acc_t *result;
0047677 result= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, reply,
0047678 (size_t)0, for_ioctl);
0047679 assert (!result);
0047680 }
0047681
0047682 #endif /* ENABLE_PSIP */
0047683
0047684 /*
0047685 * $PchId: psip.c,v 1.6 1996/05/07 20:50:31 philip Exp $
0047686 */