summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/tcpip/ip/ipstatus.c
blob: e71e362805e21ffdd944aa2bdeebbd72ebdffd22 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/********************************************************************/
/**                     Microsoft LAN Manager                      **/
/**               Copyright(c) Microsoft Corp., 1990-1992          **/
/********************************************************************/
/* :ts=4 */

//***   ipstatus.c - IP status routines.
//
//      This module contains all routines related to status indications.
//


#include        "oscfg.h"
#include        "cxport.h"
#include        "ndis.h"
#include        "ip.h"
#include        "ipdef.h"
#include        "llipif.h"
#include        "iproute.h"
#include		"ipinfo.h"

#if 0
EXTERNAL_LOCK(PILock)
#endif
extern  ProtInfo IPProtInfo[];	// Protocol information table.
extern  int     NextPI;			// Next PI field to be used.
extern  ProtInfo *RawPI;        // Raw IP protinfo

//* FindULStatus - Find the upper layer status handler.
//
//	Called when we need to find the upper layer status handler for a particular
//	protocol.
//
//	Entry:  Protocol        - Protocol to look up
//
//	Returns: A pointer to the ULStatus proc, or NULL if it can't find one.
//
ULStatusProc
FindULStatus(uchar Protocol)
{
    ULStatusProc            StatusProc = (ULStatusProc)NULL;
    int                                     i;
#if 0
	CTELockHandle           Handle;


    CTEGetLock(&PILock, &Handle);
#endif
    for ( i = 0; i < NextPI; i++) {
		if (IPProtInfo[i].pi_protocol == Protocol) {
			StatusProc = IPProtInfo[i].pi_status;
#if 0
            CTEFreeLock(&PILock, Handle);
#endif
            return StatusProc;
		}
    }

    if (RawPI != NULL) {
        StatusProc = RawPI->pi_status;
    }

#if 0
    CTEFreeLock(&PILock, Handle);
#endif

    return StatusProc;
}


//*	ULMTUNotify - Notify the upper layers of an MTU change.
//
//	Called when we need to notify the upper layers of an MTU change. We'll
//	loop through the status table, calling each status proc with the info.
//
//	This routine doesn't do any locking of the protinfo table. We might need
// 	to check this.
//
//	Input:  Dest		- Destination address affected.
// 			Src			- Source address affected.
//			Prot		- Protocol that triggered change, if any.
//			Ptr			- Pointer to protocol info, if any.
//			NewMTU		- New MTU to tell them about.
//
//      Returns: Nothing.
//
void
ULMTUNotify(IPAddr Dest, IPAddr Src, uchar Prot, void *Ptr, uint NewMTU)
{
	ULStatusProc		StatusProc;
    int					i;

    // First, notify the specific client that a frame has been dropped
    // and needs to be retransmitted.

    StatusProc = FindULStatus(Prot);
    if (StatusProc != NULL)
		(*StatusProc)(IP_NET_STATUS, IP_SPEC_MTU_CHANGE, Dest, Src,
			NULL_IP_ADDR, NewMTU, Ptr);

    // Now notify all UL entities that the MTU has changed.
    for (i = 0; i < NextPI; i++) {
		StatusProc = IPProtInfo[i].pi_status;

		if (StatusProc != NULL)
			(*StatusProc)(IP_HW_STATUS, IP_MTU_CHANGE, Dest, Src, NULL_IP_ADDR,
				NewMTU, Ptr);
    }
}

#ifdef	CHICAGO

//*	IPULUnloadNotify - Notify clients that we're unloading.
//
//	Called when we receive an unload message. We'll notify the upper layers
//	that we're unloading.
//
//	Input:  Nothing.
//
//  Returns: Nothing.
//
void
IPULUnloadNotify(void)
{
	ULStatusProc		StatusProc;
    int					i;
	
    // Now notify all UL entities that the MTU has changed.
    for (i = 0; i < NextPI; i++) {
		StatusProc = IPProtInfo[i].pi_status;

		if (StatusProc != NULL)
			(*StatusProc)(IP_HW_STATUS, IP_UNLOAD, NULL_IP_ADDR, NULL_IP_ADDR,
				NULL_IP_ADDR, 0, NULL);
    }
}

#endif

//*	IPStatus - Handle a link layer status call.
//
//	This is the routine called by the link layer when some sort of 'important'
//	status change occurs.
//
//	Entry:  Context         - Context value we gave to the link layer.
//			Status          - Status change code.
//			Buffer          - Pointer to buffer of status information.
//			BufferSize      - Size of Buffer.
//
//	Returns: Nothing.
//
void
IPStatus(void *Context, uint Status, void *Buffer, uint BufferSize)
{
	NetTableEntry			*NTE = (NetTableEntry *)Context;
	LLIPSpeedChange			*LSC;
	LLIPMTUChange			*LMC;
	LLIPAddrMTUChange		*LAM;
	uint					NewMTU;
	Interface				*IF;


	switch  (Status) {

		case LLIP_STATUS_SPEED_CHANGE:
			if (BufferSize < sizeof(LLIPSpeedChange))
				break;
			LSC = (LLIPSpeedChange *)Buffer;
			NTE->nte_if->if_speed = LSC->lsc_speed;
			break;
		case LLIP_STATUS_MTU_CHANGE:
			if (BufferSize < sizeof(LLIPMTUChange))
				break;
			// Walk through the NTEs on the IF, updating their MTUs.
			IF = NTE->nte_if;
			LMC = (LLIPMTUChange *)Buffer;
			IF->if_mtu = LMC->lmc_mtu;
			NewMTU = LMC->lmc_mtu - sizeof(IPHeader);
			NTE = IF->if_nte;
			while (NTE != NULL) {
				NTE->nte_mss = NewMTU;
				NTE = NTE->nte_ifnext;
			}
			RTWalk(SetMTUOnIF, IF, &NewMTU);
			break;
		case LLIP_STATUS_ADDR_MTU_CHANGE:
			if (BufferSize < sizeof(LLIPAddrMTUChange))
				break;
			// The MTU for a specific remote address has changed. Update all
			// routes that use that remote address as a first hop, and then
			// add a host route to that remote address, specifying the new
			// MTU.
			LAM = (LLIPAddrMTUChange *)Buffer;
			NewMTU = LAM->lam_mtu - sizeof(IPHeader);
			RTWalk(SetMTUToAddr, &LAM->lam_addr, &NewMTU);
			AddRoute(LAM->lam_addr, HOST_MASK, IPADDR_LOCAL, NTE->nte_if, NewMTU,
				1, IRE_PROTO_LOCAL, ATYPE_OVERRIDE, GetRouteContext(LAM->lam_addr,
				NTE->nte_addr));
			break;
		default:
			break;
    }

}