4 pseudo IP specific part of the IP implementation
6 Created: Apr 23, 1993 by Philip Homburg
8 Copyright 1995 Philip Homburg
22 FORWARD
void ipps_main
ARGS(( ip_port_t
*ip_port
));
23 FORWARD
void ipps_set_ipaddr
ARGS(( ip_port_t
*ip_port
));
24 FORWARD
int ipps_send
ARGS(( struct ip_port
*ip_port
, ipaddr_t dest
,
25 acc_t
*pack
, int type
));
27 PUBLIC
int ipps_init(ip_port
)
32 result
= psip_enable(ip_port
->ip_dl
.dl_ps
.ps_port
, ip_port
->ip_port
);
35 ip_port
->ip_dl
.dl_ps
.ps_send_head
= NULL
;
36 ip_port
->ip_dl
.dl_ps
.ps_send_tail
= NULL
;
37 ip_port
->ip_dev_main
= ipps_main
;
38 ip_port
->ip_dev_set_ipaddr
= ipps_set_ipaddr
;
39 ip_port
->ip_dev_send
= ipps_send
;
43 PUBLIC
void ipps_get(ip_port_nr
)
48 acc_t
*acc
, *pack
, *next_part
;
51 assert(ip_port_nr
>= 0 && ip_port_nr
< ip_conf_nr
);
52 ip_port
= &ip_port_table
[ip_port_nr
];
53 assert(ip_port
->ip_dl_type
== IPDL_PSIP
);
55 while (ip_port
->ip_dl
.dl_ps
.ps_send_head
!= NULL
)
57 pack
= ip_port
->ip_dl
.dl_ps
.ps_send_head
;
58 ip_port
->ip_dl
.dl_ps
.ps_send_head
= pack
->acc_ext_link
;
60 /* Extract nexthop address */
61 pack
= bf_packIffLess(pack
, sizeof(dest
));
62 dest
= *(ipaddr_t
*)ptr2acc_data(pack
);
63 pack
= bf_delhead(pack
, sizeof(dest
));
65 if (bf_bufsize(pack
) > ip_port
->ip_mtu
)
68 pack
= ip_split_pack(ip_port
, &next_part
,
73 /* Prepend nexthop address */
74 acc
= bf_memreq(sizeof(dest
));
75 *(ipaddr_t
*)(ptr2acc_data(acc
))= dest
;
76 acc
->acc_next
= next_part
;
77 next_part
= acc
; acc
= NULL
;
79 assert(next_part
->acc_linkC
== 1);
80 next_part
->acc_ext_link
= NULL
;
81 if (ip_port
->ip_dl
.dl_ps
.ps_send_head
)
83 ip_port
->ip_dl
.dl_ps
.ps_send_tail
->
84 acc_ext_link
= next_part
;
88 ip_port
->ip_dl
.dl_ps
.ps_send_head
=
91 ip_port
->ip_dl
.dl_ps
.ps_send_tail
= next_part
;
94 result
= psip_send(ip_port
->ip_dl
.dl_ps
.ps_port
, dest
, pack
);
95 if (result
!= NW_SUSPEND
)
97 assert(result
== NW_OK
);
101 /* Prepend nexthop address */
102 acc
= bf_memreq(sizeof(dest
));
103 *(ipaddr_t
*)(ptr2acc_data(acc
))= dest
;
105 pack
= acc
; acc
= NULL
;
107 pack
->acc_ext_link
= ip_port
->ip_dl
.dl_ps
.ps_send_head
;
108 ip_port
->ip_dl
.dl_ps
.ps_send_head
= pack
;
109 if (pack
->acc_ext_link
== NULL
)
110 ip_port
->ip_dl
.dl_ps
.ps_send_tail
= pack
;
115 PUBLIC
void ipps_put(ip_port_nr
, nexthop
, pack
)
122 assert(ip_port_nr
>= 0 && ip_port_nr
< ip_conf_nr
);
123 ip_port
= &ip_port_table
[ip_port_nr
];
124 assert(ip_port
->ip_dl_type
== IPDL_PSIP
);
125 if (nexthop
== HTONL(0xffffffff))
126 ip_arrived_broadcast(ip_port
, pack
);
128 ip_arrived(ip_port
, pack
);
131 PRIVATE
void ipps_main(ip_port
)
137 PRIVATE
void ipps_set_ipaddr(ip_port
)
142 PRIVATE
int ipps_send(ip_port
, dest
, pack
, type
)
143 struct ip_port
*ip_port
;
149 acc_t
*acc
, *next_part
;
151 if (type
!= IP_LT_NORMAL
)
153 ip_arrived_broadcast(ip_port
, bf_dupacc(pack
));
155 /* Map all broadcasts to the on-link broadcast address.
156 * This saves the application from having to to find out
157 * if the destination is a subnet broadcast.
159 dest
= HTONL(0xffffffff);
162 /* Note that allocating a packet may trigger a cleanup action,
163 * which may cause the send queue to become empty.
165 while (ip_port
->ip_dl
.dl_ps
.ps_send_head
!= NULL
)
167 acc
= bf_memreq(sizeof(dest
));
169 if (ip_port
->ip_dl
.dl_ps
.ps_send_head
== NULL
)
171 bf_afree(acc
); acc
= NULL
;
175 /* Prepend nexthop address */
176 *(ipaddr_t
*)(ptr2acc_data(acc
))= dest
;
178 pack
= acc
; acc
= NULL
;
180 assert(pack
->acc_linkC
== 1);
181 pack
->acc_ext_link
= NULL
;
183 ip_port
->ip_dl
.dl_ps
.ps_send_tail
->acc_ext_link
= pack
;
184 ip_port
->ip_dl
.dl_ps
.ps_send_tail
= pack
;
191 if (bf_bufsize(pack
) > ip_port
->ip_mtu
)
194 pack
= ip_split_pack(ip_port
, &next_part
,
201 /* Prepend nexthop address */
202 acc
= bf_memreq(sizeof(dest
));
203 *(ipaddr_t
*)(ptr2acc_data(acc
))= dest
;
204 acc
->acc_next
= next_part
;
205 next_part
= acc
; acc
= NULL
;
207 assert(next_part
->acc_linkC
== 1);
208 next_part
->acc_ext_link
= NULL
;
209 ip_port
->ip_dl
.dl_ps
.ps_send_head
= next_part
;
210 ip_port
->ip_dl
.dl_ps
.ps_send_tail
= next_part
;
212 result
= psip_send(ip_port
->ip_dl
.dl_ps
.ps_port
, dest
, pack
);
213 if (result
== NW_SUSPEND
)
215 /* Prepend nexthop address */
216 acc
= bf_memreq(sizeof(dest
));
217 *(ipaddr_t
*)(ptr2acc_data(acc
))= dest
;
219 pack
= acc
; acc
= NULL
;
221 assert(pack
->acc_linkC
== 1);
222 pack
->acc_ext_link
= ip_port
->ip_dl
.dl_ps
.ps_send_head
;
223 ip_port
->ip_dl
.dl_ps
.ps_send_head
= pack
;
224 if (!pack
->acc_ext_link
)
225 ip_port
->ip_dl
.dl_ps
.ps_send_tail
= pack
;
228 assert(result
== NW_OK
);
229 pack
= ip_port
->ip_dl
.dl_ps
.ps_send_head
;
232 ip_port
->ip_dl
.dl_ps
.ps_send_head
= pack
->acc_ext_link
;
234 /* Extract nexthop address */
235 pack
= bf_packIffLess(pack
, sizeof(dest
));
236 dest
= *(ipaddr_t
*)ptr2acc_data(pack
);
237 pack
= bf_delhead(pack
, sizeof(dest
));
244 int ipps_check(ip_port_t
*ip_port
)
249 for (n
= 0, prev
= NULL
, curr
= ip_port
->ip_dl
.dl_ps
.ps_send_head_
;
250 curr
; prev
= curr
, curr
= curr
->acc_ext_link
)
255 if (prev
!= NULL
&& prev
!= ip_port
->ip_dl
.dl_ps
.ps_send_tail_
)
257 printf("ipps_check, ip[%d]: wrong tail: got %p, expected %p\n",
258 ip_port
-ip_port_table
,
259 ip_port
->ip_dl
.dl_ps
.ps_send_tail_
, prev
);
262 if (n
!= ip_port
->ip_dl
.dl_ps
.ps_send_nr
)
264 printf("ipps_check, ip[%d]: wrong count: got %d, expected %d\n",
265 ip_port
-ip_port_table
,
266 ip_port
->ip_dl
.dl_ps
.ps_send_nr
, n
);
274 * $PchId: ip_ps.c,v 1.15 2003/01/21 15:57:52 philip Exp $