📄 ip_ps.c
字号:
/*generic/ip_ps.cpseudo IP specific part of the IP implementationCreated: Apr 23, 1993 by Philip HomburgCopyright 1995 Philip Homburg*/#include "inet.h"#include "assert.h"#include "type.h"#include "buf.h"#include "event.h"#include "ip.h"#include "ip_int.h"#include "psip.h"THIS_FILEFORWARD void ipps_main ARGS(( ip_port_t *ip_port ));FORWARD void ipps_set_ipaddr ARGS(( ip_port_t *ip_port ));FORWARD int ipps_send ARGS(( struct ip_port *ip_port, ipaddr_t dest, acc_t *pack, int type ));PUBLIC int ipps_init(ip_port)ip_port_t *ip_port;{ int result; result= psip_enable(ip_port->ip_dl.dl_ps.ps_port, ip_port->ip_port); if (result == -1) return -1; ip_port->ip_dl.dl_ps.ps_send_head= NULL; ip_port->ip_dl.dl_ps.ps_send_tail= NULL; ip_port->ip_dev_main= ipps_main; ip_port->ip_dev_set_ipaddr= ipps_set_ipaddr; ip_port->ip_dev_send= ipps_send; return result;}PUBLIC void ipps_get(ip_port_nr)int ip_port_nr;{ int result; ipaddr_t dest; acc_t *acc, *pack, *next_part; ip_port_t *ip_port; assert(ip_port_nr >= 0 && ip_port_nr < ip_conf_nr); ip_port= &ip_port_table[ip_port_nr]; assert(ip_port->ip_dl_type == IPDL_PSIP); while (ip_port->ip_dl.dl_ps.ps_send_head != NULL) { pack= ip_port->ip_dl.dl_ps.ps_send_head; ip_port->ip_dl.dl_ps.ps_send_head= pack->acc_ext_link; /* Extract nexthop address */ pack= bf_packIffLess(pack, sizeof(dest)); dest= *(ipaddr_t *)ptr2acc_data(pack); pack= bf_delhead(pack, sizeof(dest)); if (bf_bufsize(pack) > ip_port->ip_mtu) { next_part= pack; pack= ip_split_pack(ip_port, &next_part, ip_port->ip_mtu); if (pack == NULL) continue; /* Prepend nexthop address */ acc= bf_memreq(sizeof(dest)); *(ipaddr_t *)(ptr2acc_data(acc))= dest; acc->acc_next= next_part; next_part= acc; acc= NULL; assert(next_part->acc_linkC == 1); next_part->acc_ext_link= NULL; if (ip_port->ip_dl.dl_ps.ps_send_head) { ip_port->ip_dl.dl_ps.ps_send_tail-> acc_ext_link= next_part; } else { ip_port->ip_dl.dl_ps.ps_send_head= next_part; } ip_port->ip_dl.dl_ps.ps_send_tail= next_part; } result= psip_send(ip_port->ip_dl.dl_ps.ps_port, dest, pack); if (result != NW_SUSPEND) { assert(result == NW_OK); continue; } /* Prepend nexthop address */ acc= bf_memreq(sizeof(dest)); *(ipaddr_t *)(ptr2acc_data(acc))= dest; acc->acc_next= pack; pack= acc; acc= NULL; pack->acc_ext_link= ip_port->ip_dl.dl_ps.ps_send_head; ip_port->ip_dl.dl_ps.ps_send_head= pack; if (pack->acc_ext_link == NULL) ip_port->ip_dl.dl_ps.ps_send_tail= pack; break; }}PUBLIC void ipps_put(ip_port_nr, nexthop, pack)int ip_port_nr;ipaddr_t nexthop;acc_t *pack;{ ip_port_t *ip_port; assert(ip_port_nr >= 0 && ip_port_nr < ip_conf_nr); ip_port= &ip_port_table[ip_port_nr]; assert(ip_port->ip_dl_type == IPDL_PSIP); if (nexthop == HTONL(0xffffffff)) ip_arrived_broadcast(ip_port, pack); else ip_arrived(ip_port, pack);}PRIVATE void ipps_main(ip_port)ip_port_t *ip_port;{ /* nothing to do */}PRIVATE void ipps_set_ipaddr(ip_port)ip_port_t *ip_port;{}PRIVATE int ipps_send(ip_port, dest, pack, type)struct ip_port *ip_port;ipaddr_t dest;acc_t *pack;int type;{ int result; acc_t *acc, *next_part; if (type != IP_LT_NORMAL) { ip_arrived_broadcast(ip_port, bf_dupacc(pack)); /* Map all broadcasts to the on-link broadcast address. * This saves the application from having to to find out * if the destination is a subnet broadcast. */ dest= HTONL(0xffffffff); } /* Note that allocating a packet may trigger a cleanup action, * which may cause the send queue to become empty. */ while (ip_port->ip_dl.dl_ps.ps_send_head != NULL) { acc= bf_memreq(sizeof(dest)); if (ip_port->ip_dl.dl_ps.ps_send_head == NULL) { bf_afree(acc); acc= NULL; continue; } /* Prepend nexthop address */ *(ipaddr_t *)(ptr2acc_data(acc))= dest; acc->acc_next= pack; pack= acc; acc= NULL; assert(pack->acc_linkC == 1); pack->acc_ext_link= NULL; ip_port->ip_dl.dl_ps.ps_send_tail->acc_ext_link= pack; ip_port->ip_dl.dl_ps.ps_send_tail= pack; return NW_OK; } while (pack) { if (bf_bufsize(pack) > ip_port->ip_mtu) { next_part= pack; pack= ip_split_pack(ip_port, &next_part, ip_port->ip_mtu); if (pack == NULL) { return NW_OK; } /* Prepend nexthop address */ acc= bf_memreq(sizeof(dest)); *(ipaddr_t *)(ptr2acc_data(acc))= dest; acc->acc_next= next_part; next_part= acc; acc= NULL; assert(next_part->acc_linkC == 1); next_part->acc_ext_link= NULL; ip_port->ip_dl.dl_ps.ps_send_head= next_part; ip_port->ip_dl.dl_ps.ps_send_tail= next_part; } result= psip_send(ip_port->ip_dl.dl_ps.ps_port, dest, pack); if (result == NW_SUSPEND) { /* Prepend nexthop address */ acc= bf_memreq(sizeof(dest)); *(ipaddr_t *)(ptr2acc_data(acc))= dest; acc->acc_next= pack; pack= acc; acc= NULL; assert(pack->acc_linkC == 1); pack->acc_ext_link= ip_port->ip_dl.dl_ps.ps_send_head; ip_port->ip_dl.dl_ps.ps_send_head= pack; if (!pack->acc_ext_link) ip_port->ip_dl.dl_ps.ps_send_tail= pack; break; } assert(result == NW_OK); pack= ip_port->ip_dl.dl_ps.ps_send_head; if (!pack) break; ip_port->ip_dl.dl_ps.ps_send_head= pack->acc_ext_link; /* Extract nexthop address */ pack= bf_packIffLess(pack, sizeof(dest)); dest= *(ipaddr_t *)ptr2acc_data(pack); pack= bf_delhead(pack, sizeof(dest)); } return NW_OK;}#if 0int ipps_check(ip_port_t *ip_port){ int n, bad; acc_t *prev, *curr; for (n= 0, prev= NULL, curr= ip_port->ip_dl.dl_ps.ps_send_head_; curr; prev= curr, curr= curr->acc_ext_link) { n++; } bad= 0; if (prev != NULL && prev != ip_port->ip_dl.dl_ps.ps_send_tail_) { printf("ipps_check, ip[%d]: wrong tail: got %p, expected %p\n", ip_port-ip_port_table, ip_port->ip_dl.dl_ps.ps_send_tail_, prev); bad++; } if (n != ip_port->ip_dl.dl_ps.ps_send_nr) { printf("ipps_check, ip[%d]: wrong count: got %d, expected %d\n", ip_port-ip_port_table, ip_port->ip_dl.dl_ps.ps_send_nr, n); bad++; } return bad == 0;}#endif/* * $PchId: ip_ps.c,v 1.15 2003/01/21 15:57:52 philip Exp $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -