Deleted Added
full compact
spx_reass.c (22975) spx_reass.c (24659)
1/*
2 * Copyright (c) 1995, Mike Mitchell
3 * Copyright (c) 1984, 1985, 1986, 1987, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 19 unchanged lines hidden (view full) ---

28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)spx_usrreq.h
35 *
1/*
2 * Copyright (c) 1995, Mike Mitchell
3 * Copyright (c) 1984, 1985, 1986, 1987, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 19 unchanged lines hidden (view full) ---

28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)spx_usrreq.h
35 *
36 * $Id$
36 * $Id: spx_usrreq.c,v 1.10 1997/02/22 09:42:00 peter Exp $
37 */
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/malloc.h>
42#include <sys/mbuf.h>
43#include <sys/protosw.h>
44#include <sys/queue.h>

--- 22 unchanged lines hidden (view full) ---

67int traceallspxs = 0;
68int spx_hardnosed;
69int spx_use_delack = 0;
70u_short spx_newchecks[50];
71
72struct spx_istat spx_istat;
73u_short spx_iss;
74
37 */
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/malloc.h>
42#include <sys/mbuf.h>
43#include <sys/protosw.h>
44#include <sys/queue.h>

--- 22 unchanged lines hidden (view full) ---

67int traceallspxs = 0;
68int spx_hardnosed;
69int spx_use_delack = 0;
70u_short spx_newchecks[50];
71
72struct spx_istat spx_istat;
73u_short spx_iss;
74
75static int spx_usr_abort(struct socket *so);
76static int spx_accept(struct socket *so, struct mbuf *nam);
77static int spx_attach(struct socket *so, int proto);
78static int spx_bind(struct socket *so, struct mbuf *nam);
79static int spx_connect(struct socket *so, struct mbuf *nam);
80static int spx_detach(struct socket *so);
81static int spx_usr_disconnect(struct socket *so);
82static int spx_listen(struct socket *so);
83static int spx_rcvd(struct socket *so, int flags);
84static int spx_rcvoob(struct socket *so, struct mbuf *m, int flags);
85static int spx_send(struct socket *so, int flags, struct mbuf *m,
86 struct mbuf *addr, struct mbuf *control);
87static int spx_shutdown(struct socket *so);
88static int spx_sp_attach(struct socket *so, int proto);
89
90struct pr_usrreqs spx_usrreqs = {
91 spx_usr_abort, spx_accept, spx_attach, spx_bind,
92 spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
93 spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
94 spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
95 ipx_sockaddr
96};
97
98struct pr_usrreqs spx_usrreq_sps = {
99 spx_usr_abort, spx_accept, spx_sp_attach, spx_bind,
100 spx_connect, pru_connect2_notsupp, ipx_control, spx_detach,
101 spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd,
102 spx_rcvoob, spx_send, pru_sense_null, spx_shutdown,
103 ipx_sockaddr
104};
105
75void
76spx_init()
77{
78
79 spx_iss = 1; /* WRONG !! should fish it out of TODR */
80}
81
82/*ARGSUSED*/

--- 1178 unchanged lines hidden (view full) ---

1261 }
1262 m_freem(*value);
1263 break;
1264 }
1265 release:
1266 return (error);
1267}
1268
106void
107spx_init()
108{
109
110 spx_iss = 1; /* WRONG !! should fish it out of TODR */
111}
112
113/*ARGSUSED*/

--- 1178 unchanged lines hidden (view full) ---

1292 }
1293 m_freem(*value);
1294 break;
1295 }
1296 release:
1297 return (error);
1298}
1299
1269/*ARGSUSED*/
1270int
1271spx_usrreq(so, req, m, nam, controlp)
1300static int
1301spx_usr_abort(so)
1272 struct socket *so;
1302 struct socket *so;
1273 int req;
1274 struct mbuf *m, *nam, *controlp;
1275{
1303{
1276 struct ipxpcb *ipxp = sotoipxpcb(so);
1277 register struct spxpcb *cb = NULL;
1278 int s = splnet();
1279 int error = 0, ostate;
1280 struct mbuf *mm;
1281 register struct sockbuf *sb;
1304 int s;
1305 struct ipxpcb *ipxp;
1306 struct spxpcb *cb;
1282
1307
1283 if (req == PRU_CONTROL)
1284 return (ipx_control(so, (int)m, (caddr_t)nam,
1285 (struct ifnet *)controlp));
1286 if (ipxp == NULL) {
1287 if (req != PRU_ATTACH) {
1288 error = EINVAL;
1289 goto release;
1290 }
1291 } else
1292 cb = ipxtospxpcb(ipxp);
1308 ipxp = sotoipxpcb(so);
1309 cb = ipxtospxpcb(ipxp);
1293
1310
1294 ostate = cb ? cb->s_state : 0;
1311 s = splnet();
1312 spx_drop(cb, ECONNABORTED);
1313 splx(s);
1314 return (0);
1315}
1295
1316
1296 switch (req) {
1317/*
1318 * Accept a connection. Essentially all the work is
1319 * done at higher levels; just return the address
1320 * of the peer, storing through addr.
1321 */
1322static int
1323spx_accept(so, nam)
1324 struct socket *so;
1325 struct mbuf *nam;
1326{
1327 struct ipxpcb *ipxp;
1328 struct sockaddr_ipx *sipx;
1297
1329
1298 case PRU_ATTACH:
1299 if (ipxp != NULL) {
1300 error = EISCONN;
1301 break;
1302 }
1303 error = ipx_pcballoc(so, &ipxpcb);
1330 ipxp = sotoipxpcb(so);
1331 sipx = mtod(nam, struct sockaddr_ipx *);
1332
1333 nam->m_len = sizeof (struct sockaddr_ipx);
1334 sipx->sipx_family = AF_IPX;
1335 sipx->sipx_addr = ipxp->ipxp_faddr;
1336 return (0);
1337}
1338
1339static int
1340spx_attach(so, proto)
1341 struct socket *so;
1342 int proto;
1343{
1344 int error;
1345 int s;
1346 struct ipxpcb *ipxp;
1347 struct spxpcb *cb;
1348 struct mbuf *mm;
1349 struct sockbuf *sb;
1350
1351 ipxp = sotoipxpcb(so);
1352 cb = ipxtospxpcb(ipxp);
1353
1354 if (ipxp != NULL)
1355 return (EISCONN);
1356 s = splnet();
1357 error = ipx_pcballoc(so, &ipxpcb);
1358 if (error)
1359 goto spx_attach_end;
1360 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
1361 error = soreserve(so, (u_long) 3072, (u_long) 3072);
1304 if (error)
1362 if (error)
1305 break;
1306 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
1307 error = soreserve(so, (u_long) 3072, (u_long) 3072);
1308 if (error)
1309 break;
1310 }
1311 ipxp = sotoipxpcb(so);
1363 goto spx_attach_end;
1364 }
1365 ipxp = sotoipxpcb(so);
1312
1366
1313 mm = m_getclr(M_DONTWAIT, MT_PCB);
1314 sb = &so->so_snd;
1367 mm = m_getclr(M_DONTWAIT, MT_PCB);
1368 sb = &so->so_snd;
1315
1369
1316 if (mm == NULL) {
1317 error = ENOBUFS;
1318 break;
1319 }
1320 cb = mtod(mm, struct spxpcb *);
1321 mm = m_getclr(M_DONTWAIT, MT_HEADER);
1322 if (mm == NULL) {
1323 (void) m_free(dtom(m));
1324 error = ENOBUFS;
1325 break;
1326 }
1327 cb->s_ipx = mtod(mm, struct ipx *);
1328 cb->s_state = TCPS_LISTEN;
1329 cb->s_smax = -1;
1330 cb->s_swl1 = -1;
1331 cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
1332 cb->s_ipxpcb = ipxp;
1333 cb->s_mtu = 576 - sizeof (struct spx);
1334 cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
1335 cb->s_ssthresh = cb->s_cwnd;
1336 cb->s_cwmx = sbspace(sb) * CUNIT /
1337 (2 * sizeof (struct spx));
1338 /* Above is recomputed when connecting to account
1339 for changed buffering or mtu's */
1340 cb->s_rtt = SPXTV_SRTTBASE;
1341 cb->s_rttvar = SPXTV_SRTTDFLT << 2;
1342 SPXT_RANGESET(cb->s_rxtcur,
1343 ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1,
1344 SPXTV_MIN, SPXTV_REXMTMAX);
1345 ipxp->ipxp_pcb = (caddr_t) cb;
1346 break;
1370 if (mm == NULL) {
1371 error = ENOBUFS;
1372 goto spx_attach_end;
1373 }
1374 cb = mtod(mm, struct spxpcb *);
1375 mm = m_getclr(M_DONTWAIT, MT_HEADER);
1376 if (mm == NULL) {
1377 m_freem(dtom(cb));
1378 error = ENOBUFS;
1379 goto spx_attach_end;
1380 }
1381 cb->s_ipx = mtod(mm, struct ipx *);
1382 cb->s_state = TCPS_LISTEN;
1383 cb->s_smax = -1;
1384 cb->s_swl1 = -1;
1385 cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
1386 cb->s_ipxpcb = ipxp;
1387 cb->s_mtu = 576 - sizeof (struct spx);
1388 cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
1389 cb->s_ssthresh = cb->s_cwnd;
1390 cb->s_cwmx = sbspace(sb) * CUNIT /
1391 (2 * sizeof (struct spx));
1392 /* Above is recomputed when connecting to account
1393 for changed buffering or mtu's */
1394 cb->s_rtt = SPXTV_SRTTBASE;
1395 cb->s_rttvar = SPXTV_SRTTDFLT << 2;
1396 SPXT_RANGESET(cb->s_rxtcur,
1397 ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1,
1398 SPXTV_MIN, SPXTV_REXMTMAX);
1399 ipxp->ipxp_pcb = (caddr_t) cb;
1400spx_attach_end:
1401 splx(s);
1402 return (error);
1403}
1347
1404
1348 case PRU_DETACH:
1349 if (ipxp == NULL) {
1350 error = ENOTCONN;
1351 break;
1352 }
1353 if (cb->s_state > TCPS_LISTEN)
1354 cb = spx_disconnect(cb);
1355 else
1356 cb = spx_close(cb);
1357 break;
1405static int
1406spx_bind(so, nam)
1407 struct socket *so;
1408 struct mbuf *nam;
1409{
1410 struct ipxpcb *ipxp;
1358
1411
1359 case PRU_BIND:
1360 error = ipx_pcbbind(ipxp, nam);
1361 break;
1412 ipxp = sotoipxpcb(so);
1362
1413
1363 case PRU_LISTEN:
1364 if (ipxp->ipxp_lport == 0)
1365 error = ipx_pcbbind(ipxp, (struct mbuf *)0);
1366 if (error == 0)
1367 cb->s_state = TCPS_LISTEN;
1368 break;
1414 return (ipx_pcbbind(ipxp, nam));
1415}
1416
1417/*
1418 * Initiate connection to peer.
1419 * Enter SYN_SENT state, and mark socket as connecting.
1420 * Start keep-alive timer, setup prototype header,
1421 * Send initial system packet requesting connection.
1422 */
1423static int
1424spx_connect(so, nam)
1425 struct socket *so;
1426 struct mbuf *nam;
1427{
1428 int error;
1429 int s;
1430 struct ipxpcb *ipxp;
1431 struct spxpcb *cb;
1369
1432
1433 ipxp = sotoipxpcb(so);
1434 cb = ipxtospxpcb(ipxp);
1435
1436 s = splnet();
1437 if (ipxp->ipxp_lport == 0) {
1438 error = ipx_pcbbind(ipxp, (struct mbuf *)0);
1439 if (error)
1440 goto spx_connect_end;
1441 }
1442 error = ipx_pcbconnect(ipxp, nam);
1443 if (error)
1444 goto spx_connect_end;
1445 soisconnecting(so);
1446 spxstat.spxs_connattempt++;
1447 cb->s_state = TCPS_SYN_SENT;
1448 cb->s_did = 0;
1449 spx_template(cb);
1450 cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
1451 cb->s_force = 1 + SPXTV_KEEP;
1370 /*
1452 /*
1371 * Initiate connection to peer.
1372 * Enter SYN_SENT state, and mark socket as connecting.
1373 * Start keep-alive timer, setup prototype header,
1374 * Send initial system packet requesting connection.
1453 * Other party is required to respond to
1454 * the port I send from, but he is not
1455 * required to answer from where I am sending to,
1456 * so allow wildcarding.
1457 * original port I am sending to is still saved in
1458 * cb->s_dport.
1375 */
1459 */
1376 case PRU_CONNECT:
1377 if (ipxp->ipxp_lport == 0) {
1378 error = ipx_pcbbind(ipxp, (struct mbuf *)0);
1379 if (error)
1380 break;
1381 }
1382 error = ipx_pcbconnect(ipxp, nam);
1383 if (error)
1384 break;
1385 soisconnecting(so);
1386 spxstat.spxs_connattempt++;
1387 cb->s_state = TCPS_SYN_SENT;
1388 cb->s_did = 0;
1389 spx_template(cb);
1390 cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
1391 cb->s_force = 1 + SPXTV_KEEP;
1392 /*
1393 * Other party is required to respond to
1394 * the port I send from, but he is not
1395 * required to answer from where I am sending to,
1396 * so allow wildcarding.
1397 * original port I am sending to is still saved in
1398 * cb->s_dport.
1399 */
1400 ipxp->ipxp_fport = 0;
1401 error = spx_output(cb, (struct mbuf *) 0);
1402 break;
1460 ipxp->ipxp_fport = 0;
1461 error = spx_output(cb, (struct mbuf *) 0);
1462spx_connect_end:
1463 splx(s);
1464 return (error);
1465}
1403
1466
1404 case PRU_CONNECT2:
1405 error = EOPNOTSUPP;
1406 break;
1467static int
1468spx_detach(so)
1469 struct socket *so;
1470{
1471 int s;
1472 struct ipxpcb *ipxp;
1473 struct spxpcb *cb;
1407
1474
1408 /*
1409 * We may decide later to implement connection closing
1410 * handshaking at the spx level optionally.
1411 * here is the hook to do it:
1412 */
1413 case PRU_DISCONNECT:
1414 cb = spx_disconnect(cb);
1415 break;
1475 ipxp = sotoipxpcb(so);
1476 cb = ipxtospxpcb(ipxp);
1416
1477
1417 /*
1418 * Accept a connection. Essentially all the work is
1419 * done at higher levels; just return the address
1420 * of the peer, storing through addr.
1421 */
1422 case PRU_ACCEPT: {
1423 struct sockaddr_ipx *sipx = mtod(nam, struct sockaddr_ipx *);
1478 if (ipxp == NULL)
1479 return (ENOTCONN);
1480 s = splnet();
1481 if (cb->s_state > TCPS_LISTEN)
1482 spx_disconnect(cb);
1483 else
1484 spx_close(cb);
1485 splx(s);
1486 return (0);
1487}
1424
1488
1425 nam->m_len = sizeof (struct sockaddr_ipx);
1426 sipx->sipx_family = AF_IPX;
1427 sipx->sipx_addr = ipxp->ipxp_faddr;
1428 break;
1429 }
1489/*
1490 * We may decide later to implement connection closing
1491 * handshaking at the spx level optionally.
1492 * here is the hook to do it:
1493 */
1494static int
1495spx_usr_disconnect(so)
1496 struct socket *so;
1497{
1498 int s;
1499 struct ipxpcb *ipxp;
1500 struct spxpcb *cb;
1430
1501
1431 case PRU_SHUTDOWN:
1432 socantsendmore(so);
1433 cb = spx_usrclosed(cb);
1434 if (cb)
1435 error = spx_output(cb, (struct mbuf *) 0);
1436 break;
1502 ipxp = sotoipxpcb(so);
1503 cb = ipxtospxpcb(ipxp);
1437
1504
1438 /*
1439 * After a receive, possibly send acknowledgment
1440 * updating allocation.
1441 */
1442 case PRU_RCVD:
1443 cb->s_flags |= SF_RVD;
1444 (void) spx_output(cb, (struct mbuf *) 0);
1445 cb->s_flags &= ~SF_RVD;
1446 break;
1505 s = splnet();
1506 spx_disconnect(cb);
1507 splx(s);
1508 return (0);
1509}
1447
1510
1448 case PRU_ABORT:
1449 (void) spx_drop(cb, ECONNABORTED);
1450 break;
1511static int
1512spx_listen(so)
1513 struct socket *so;
1514{
1515 int error;
1516 struct ipxpcb *ipxp;
1517 struct spxpcb *cb;
1451
1518
1452 case PRU_SENSE:
1453 case PRU_CONTROL:
1454 m = NULL;
1455 error = EOPNOTSUPP;
1456 break;
1519 error = 0;
1520 ipxp = sotoipxpcb(so);
1521 cb = ipxtospxpcb(ipxp);
1457
1522
1458 case PRU_RCVOOB:
1459 if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark ||
1460 (so->so_state & SS_RCVATMARK)) {
1461 m->m_len = 1;
1462 *mtod(m, caddr_t) = cb->s_iobc;
1463 break;
1464 }
1465 error = EINVAL;
1466 break;
1523 if (ipxp->ipxp_lport == 0)
1524 error = ipx_pcbbind(ipxp, (struct mbuf *)0);
1525 if (error == 0)
1526 cb->s_state = TCPS_LISTEN;
1527 return (error);
1528}
1467
1529
1468 case PRU_SENDOOB:
1469 if (sbspace(&so->so_snd) < -512) {
1470 error = ENOBUFS;
1471 break;
1472 }
1473 cb->s_oobflags |= SF_SOOB;
1474 /* fall into */
1475 case PRU_SEND:
1476 if (controlp) {
1477 u_short *p = mtod(controlp, u_short *);
1478 spx_newchecks[2]++;
1479 if ((p[0] == 5) && p[1] == 1) { /* XXXX, for testing */
1480 cb->s_shdr.spx_dt = *(u_char *)(&p[2]);
1481 spx_newchecks[3]++;
1482 }
1483 m_freem(controlp);
1484 }
1485 controlp = NULL;
1486 error = spx_output(cb, m);
1487 m = NULL;
1488 break;
1530/*
1531 * After a receive, possibly send acknowledgment
1532 * updating allocation.
1533 */
1534static int
1535spx_rcvd(so, flags)
1536 struct socket *so;
1537 int flags;
1538{
1539 int s;
1540 struct ipxpcb *ipxp;
1541 struct spxpcb *cb;
1489
1542
1490 case PRU_SOCKADDR:
1491 ipx_setsockaddr(ipxp, nam);
1492 break;
1543 ipxp = sotoipxpcb(so);
1544 cb = ipxtospxpcb(ipxp);
1493
1545
1494 case PRU_PEERADDR:
1495 ipx_setpeeraddr(ipxp, nam);
1496 break;
1546 s = splnet();
1547 cb->s_flags |= SF_RVD;
1548 spx_output(cb, (struct mbuf *) 0);
1549 cb->s_flags &= ~SF_RVD;
1550 splx(s);
1551 return (0);
1552}
1497
1553
1498 case PRU_SLOWTIMO:
1499 cb = spx_timers(cb, (int)nam);
1500 req |= ((int)nam) << 8;
1501 break;
1554static int
1555spx_rcvoob(so, m, flags)
1556 struct socket *so;
1557 struct mbuf *m;
1558 int flags;
1559{
1560 struct ipxpcb *ipxp;
1561 struct spxpcb *cb;
1502
1562
1503 case PRU_FASTTIMO:
1504 case PRU_PROTORCV:
1505 case PRU_PROTOSEND:
1506 error = EOPNOTSUPP;
1507 break;
1563 ipxp = sotoipxpcb(so);
1564 cb = ipxtospxpcb(ipxp);
1508
1565
1509 default:
1510 panic("spx_usrreq");
1566 if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark ||
1567 (so->so_state & SS_RCVATMARK)) {
1568 m->m_len = 1;
1569 *mtod(m, caddr_t) = cb->s_iobc;
1570 return (0);
1511 }
1571 }
1512 if (cb && (so->so_options & SO_DEBUG || traceallspxs))
1513 spx_trace(SA_USER, (u_char)ostate, cb, (struct spx *)0, req);
1514release:
1572 return (EINVAL);
1573}
1574
1575static int
1576spx_send(so, flags, m, addr, controlp)
1577 struct socket *so;
1578 int flags;
1579 struct mbuf *m;
1580 struct mbuf *addr;
1581 struct mbuf *controlp;
1582{
1583 int error;
1584 int s;
1585 struct ipxpcb *ipxp;
1586 struct spxpcb *cb;
1587
1588 error = 0;
1589 ipxp = sotoipxpcb(so);
1590 cb = ipxtospxpcb(ipxp);
1591
1592 s = splnet();
1593 if (flags & PRUS_OOB) {
1594 if (sbspace(&so->so_snd) < -512) {
1595 error = ENOBUFS;
1596 goto spx_send_end;
1597 }
1598 cb->s_oobflags |= SF_SOOB;
1599 }
1600 if (controlp) {
1601 u_short *p = mtod(controlp, u_short *);
1602 spx_newchecks[2]++;
1603 if ((p[0] == 5) && p[1] == 1) { /* XXXX, for testing */
1604 cb->s_shdr.spx_dt = *(u_char *)(&p[2]);
1605 spx_newchecks[3]++;
1606 }
1607 m_freem(controlp);
1608 }
1609 controlp = NULL;
1610 error = spx_output(cb, m);
1611 m = NULL;
1612spx_send_end:
1515 if (controlp != NULL)
1516 m_freem(controlp);
1517 if (m != NULL)
1518 m_freem(m);
1519 splx(s);
1520 return (error);
1521}
1522
1613 if (controlp != NULL)
1614 m_freem(controlp);
1615 if (m != NULL)
1616 m_freem(m);
1617 splx(s);
1618 return (error);
1619}
1620
1523int
1524spx_usrreq_sp(so, req, m, nam, controlp)
1621static int
1622spx_shutdown(so)
1623 struct socket *so;
1624{
1625 int error;
1626 int s;
1627 struct ipxpcb *ipxp;
1628 struct spxpcb *cb;
1629
1630 error = 0;
1631 ipxp = sotoipxpcb(so);
1632 cb = ipxtospxpcb(ipxp);
1633
1634 s = splnet();
1635 socantsendmore(so);
1636 cb = spx_usrclosed(cb);
1637 if (cb)
1638 error = spx_output(cb, (struct mbuf *) 0);
1639 splx(s);
1640 return (error);
1641}
1642
1643static int
1644spx_sp_attach(so, proto)
1525 struct socket *so;
1645 struct socket *so;
1526 int req;
1527 struct mbuf *m, *nam, *controlp;
1646 int proto;
1528{
1647{
1529 int error = spx_usrreq(so, req, m, nam, controlp);
1648 int error;
1649 struct ipxpcb *ipxp;
1650 struct spxpcb *cb;
1530
1651
1531 if (req == PRU_ATTACH && error == 0) {
1532 struct ipxpcb *ipxp = sotoipxpcb(so);
1652 error = spx_attach(so, proto);
1653 if (error == 0) {
1654 ipxp = sotoipxpcb(so);
1533 ((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
1534 (SF_HI | SF_HO | SF_PI);
1535 }
1536 return (error);
1537}
1538
1539/*
1540 * Create template to be used to send spx packets on a connection.

--- 152 unchanged lines hidden (view full) ---

1693 }
1694 while (ip != &ipxpcb) {
1695 cb = ipxtospxpcb(ip);
1696 ipnxt = ip->ipxp_next;
1697 if (cb == 0)
1698 goto tpgone;
1699 for (i = 0; i < SPXT_NTIMERS; i++) {
1700 if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
1655 ((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
1656 (SF_HI | SF_HO | SF_PI);
1657 }
1658 return (error);
1659}
1660
1661/*
1662 * Create template to be used to send spx packets on a connection.

--- 152 unchanged lines hidden (view full) ---

1815 }
1816 while (ip != &ipxpcb) {
1817 cb = ipxtospxpcb(ip);
1818 ipnxt = ip->ipxp_next;
1819 if (cb == 0)
1820 goto tpgone;
1821 for (i = 0; i < SPXT_NTIMERS; i++) {
1822 if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
1701 (void) spx_usrreq(cb->s_ipxpcb->ipxp_socket,
1702 PRU_SLOWTIMO, (struct mbuf *)0,
1703 (struct mbuf *)i, (struct mbuf *)0);
1823 spx_timers(cb, i);
1704 if (ipnxt->ipxp_prev != ip)
1705 goto tpgone;
1706 }
1707 }
1708 cb->s_idle++;
1709 if (cb->s_rtt)
1710 cb->s_rtt++;
1711tpgone:

--- 107 unchanged lines hidden ---
1824 if (ipnxt->ipxp_prev != ip)
1825 goto tpgone;
1826 }
1827 }
1828 cb->s_idle++;
1829 if (cb->s_rtt)
1830 cb->s_rtt++;
1831tpgone:

--- 107 unchanged lines hidden ---