SCCS-vsn: sys/netinet/in.h 4.9
SCCS-vsn: sys/netinet/in_pcb.c 4.17
SCCS-vsn: sys/netinet/tcp_input.c 1.55
SCCS-vsn: sys/netinet/tcp_usrreq.c 1.52
SCCS-vsn: sys/netinet/udp_usrreq.c 4.20
/*
* Constants and structures defined by the internet system,
/*
* Constants and structures defined by the internet system,
* Protocols
*/
#define IPPROTO_ICMP 1 /* control message protocol */
* Protocols
*/
#define IPPROTO_ICMP 1 /* control message protocol */
-#define IPPROTO_GG 2 /* gateway^2 (deprecated) */
+#define IPPROTO_GGP 2 /* gateway^2 (deprecated) */
#define IPPROTO_TCP 6 /* tcp */
#define IPPROTO_PUP 12 /* pup */
#define IPPROTO_UDP 17 /* user datagram protocol */
#define IPPROTO_TCP 6 /* tcp */
#define IPPROTO_PUP 12 /* pup */
#define IPPROTO_UDP 17 /* user datagram protocol */
#define IPPORT_TTYLINK 87
#define IPPORT_SUPDUP 95
#define IPPORT_TTYLINK 87
#define IPPORT_SUPDUP 95
+#define IPPORT_RESERVED 1024
+
+#define INADDR_ANY 0x00000000
+
/*
* Socket address, internet style.
*/
/*
* Socket address, internet style.
*/
-/* in_pcb.c 4.16 82/02/15 */
+/* in_pcb.c 4.17 82/02/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
{
struct mbuf *m;
register struct inpcb *inp;
{
struct mbuf *m;
register struct inpcb *inp;
- struct ifnet *ifp;
- u_short lport;
+ if (ifnet == 0)
+ return (EADDRNOTAVAIL);
if (sin) {
if (sin->sin_family != AF_INET)
return (EAFNOSUPPORT);
if (sin) {
if (sin->sin_family != AF_INET)
return (EAFNOSUPPORT);
- if (ifnet && sin->sin_addr.s_addr == 0)
- sin->sin_addr = ifnet->if_addr;
- ifp = if_ifwithaddr(sin->sin_addr);
+ if (sin->sin_addr.s_addr &&
+ if_ifwithaddr(sin->sin_addr.s_addr) == 0)
+ return (EADDRNOTAVAIL);
- if (lport &&
- in_pcblookup(head, zeroin_addr, 0, sin->sin_addr, lport))
- return (EADDRINUSE);
- } else {
- ifp = ifnet;
- lport = 0;
+ if (lport) {
+ u_short aport = lport;
+#if vax
+ aport = htons(aport);
+#endif
+ /* GROSS */
+ if (aport < IPPORT_RESERVED && u.u_uid != 0)
+ return (EPERM);
+ if (in_pcblookup(head,
+ zeroin_addr, 0, sin->sin_addr, lport, 0))
+ return (EADDRINUSE);
+ }
- if (ifp == 0)
- return (EADDRNOTAVAIL);
m = m_getclr(M_DONTWAIT);
if (m == 0)
return (ENOBUFS);
m = m_getclr(M_DONTWAIT);
if (m == 0)
return (ENOBUFS);
goto bad2;
inp = mtod(m, struct inpcb *);
inp->inp_head = head;
goto bad2;
inp = mtod(m, struct inpcb *);
inp->inp_head = head;
- inp->inp_laddr = ifp->if_addr;
+ if (sin)
+ inp->inp_laddr = sin->sin_addr;
- if (head->inp_lport++ < 1024)
- head->inp_lport = 1024;
+ if (head->inp_lport++ < IPPORT_RESERVED)
+ head->inp_lport = IPPORT_RESERVED;
lport = htons(head->inp_lport);
lport = htons(head->inp_lport);
- } while (in_pcblookup(head, zeroin_addr, 0, inp->inp_laddr, lport));
+ } while (in_pcblookup(head,
+ zeroin_addr, 0, inp->inp_laddr, lport, 0));
inp->inp_lport = lport;
inp->inp_socket = so;
insque(inp, head);
so->so_pcb = (caddr_t)inp;
inp->inp_lport = lport;
inp->inp_socket = so;
insque(inp, head);
so->so_pcb = (caddr_t)inp;
- sin = (struct sockaddr_in *)&so->so_addr;
- sin->sin_family = AF_INET;
- sin->sin_addr = inp->inp_laddr;
- sin->sin_port = inp->inp_lport;
return (0);
bad2:
sbrelease(&so->so_snd);
return (0);
bad2:
sbrelease(&so->so_snd);
struct inpcb *inp;
struct sockaddr_in *sin;
{
struct inpcb *inp;
struct sockaddr_in *sin;
{
COUNT(IN_PCBCONNECT);
if (sin->sin_family != AF_INET)
return (EAFNOSUPPORT);
if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0)
return (EADDRNOTAVAIL);
COUNT(IN_PCBCONNECT);
if (sin->sin_family != AF_INET)
return (EAFNOSUPPORT);
if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0)
return (EADDRNOTAVAIL);
- xp = in_pcblookup(inp->inp_head, sin->sin_addr, sin->sin_port, inp->inp_laddr, inp->inp_lport);
- if (xp->inp_faddr.s_addr)
+ if (inp->inp_laddr.s_addr == 0) {
+ ifp = if_ifonnetof(sin->sin_addr.s_addr);
+ if (ifp == 0)
+ ifp = ifnet;
+ inp->inp_laddr = ifp->if_addr;
+ }
+ if (in_pcblookup(inp->inp_head,
+ sin->sin_addr, sin->sin_port, inp->inp_laddr, inp->inp_lport, 0))
return (EADDRINUSE);
inp->inp_faddr = sin->sin_addr;
inp->inp_fport = sin->sin_port;
return (0);
}
return (EADDRINUSE);
inp->inp_faddr = sin->sin_addr;
inp->inp_fport = sin->sin_port;
return (0);
}
- register struct sockaddr_in *sin = (struct sockaddr_in *)sp;
+ register struct sockaddr_in *sin =
+ (struct sockaddr_in *)&inp->inp_socket->so_addr;
sin->sin_family = AF_INET;
sin->sin_family = AF_INET;
- sin->sin_port = inp->inp_fport;
- sin->sin_addr = inp->inp_faddr;
+ sin->sin_addr = inp->inp_laddr;
+ sin->sin_port = inp->inp_lport;
/*
* Look for a control block to accept a segment.
* First choice is an exact address match.
/*
* Look for a control block to accept a segment.
* First choice is an exact address match.
- * Second choice is a match of local address, with
- * unspecified foreign address.
+ * Second choice is a match with either the foreign or the local
+ * address specified.
+ *
+ * SHOULD ALLOW MATCH ON MULTI-HOMING ONLY
-in_pcblookup(head, faddr, fport, laddr, lport)
+in_pcblookup(head, faddr, fport, laddr, lport, enter)
struct inpcb *head;
struct in_addr faddr, laddr;
u_short fport, lport;
struct inpcb *head;
struct in_addr faddr, laddr;
u_short fport, lport;
- register struct inpcb *inp;
- struct inpcb *match = 0;
+ register struct inpcb *inp, *match = 0;
+ int matchwild = 3, wildcard;
for (inp = head->inp_next; inp != head; inp = inp->inp_next) {
for (inp = head->inp_next; inp != head; inp = inp->inp_next) {
- if (inp->inp_laddr.s_addr != laddr.s_addr ||
- inp->inp_lport != lport)
+ if (inp->inp_lport != lport)
- if (inp->inp_faddr.s_addr == 0) {
- match = inp;
+ wildcard = 0;
+ if (inp->inp_laddr.s_addr != 0) {
+ if (inp->inp_laddr.s_addr != laddr.s_addr)
+ continue;
+ } else {
+ if (laddr.s_addr != 0)
+ wildcard++;
+ }
+ if (inp->inp_faddr.s_addr != 0) {
+ if (inp->inp_faddr.s_addr != faddr.s_addr)
+ continue;
+ } else {
+ if (faddr.s_addr != 0)
+ wildcard++;
+ }
+ if (enter == 0 && wildcard)
+ if (wildcard < matchwild) {
+ match = inp;
+ matchwild = wildcard;
+ if (matchwild == 0)
+ break;
- if (inp->inp_faddr.s_addr == faddr.s_addr &&
- inp->inp_fport == fport)
- return (inp);
+ }
+ if (match && enter) {
+ match->inp_laddr = laddr;
+ in_setsockaddr(match);
-/* tcp_input.c 1.54 82/02/25 */
+/* tcp_input.c 1.55 82/02/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
- * Locate pcb for segment.
+ * Locate pcb for segment. On match, update the local
+ * address stored in the block to reflect anchoring.
- (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport);
+ (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport, 1);
/*
* If the state is CLOSED (i.e., TCB does not exist) then
/*
* If the state is CLOSED (i.e., TCB does not exist) then
-/* tcp_usrreq.c 1.51 82/02/25 */
+/* tcp_usrreq.c 1.52 82/02/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
* of the peer, storing through addr.
*/
case PRU_ACCEPT:
* of the peer, storing through addr.
*/
case PRU_ACCEPT:
- in_pcbconnaddr(inp, (struct sockaddr *)addr);
-/* udp_usrreq.c 4.19 82/01/19 */
+/* udp_usrreq.c 4.20 82/02/27 */
#include "../h/param.h"
#include "../h/dir.h"
#include "../h/param.h"
#include "../h/dir.h"
- * Locate pcb for datagram.
+ * Locate pcb for datagram. On wildcard match, update
+ * control block to anchor network and host address.
*/
inp = in_pcblookup(&udb,
*/
inp = in_pcblookup(&udb,
- ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport);
+ ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport, 1);
socantsendmore(so);
break;
socantsendmore(so);
break;
+ case PRU_SEND: {
+ struct in_addr laddr;
+
+ laddr = inp->inp_laddr;
if (inp->inp_faddr.s_addr)
return (EISCONN);
error = in_pcbconnect(inp, (struct sockaddr_in *)addr);
if (inp->inp_faddr.s_addr)
return (EISCONN);
error = in_pcbconnect(inp, (struct sockaddr_in *)addr);
return (ENOTCONN);
}
udp_output(inp, m);
return (ENOTCONN);
}
udp_output(inp, m);
+ inp->inp_laddr = laddr;
+ }
+ }