Revision f0cbd3ec
b/slirp/bootp.c | ||
---|---|---|
1 |
/* |
|
2 |
* QEMU BOOTP/DHCP server |
|
3 |
* |
|
4 |
* Copyright (c) 2004 Fabrice Bellard |
|
5 |
* |
|
6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
7 |
* of this software and associated documentation files (the "Software"), to deal |
|
8 |
* in the Software without restriction, including without limitation the rights |
|
9 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
10 |
* copies of the Software, and to permit persons to whom the Software is |
|
11 |
* furnished to do so, subject to the following conditions: |
|
12 |
* |
|
13 |
* The above copyright notice and this permission notice shall be included in |
|
14 |
* all copies or substantial portions of the Software. |
|
15 |
* |
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
17 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
18 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
19 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
20 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
21 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
22 |
* THE SOFTWARE. |
|
23 |
*/ |
|
24 |
#include <slirp.h> |
|
25 |
|
|
26 |
/* XXX: only DHCP is supported */ |
|
27 |
|
|
28 |
#define NB_ADDR 16 |
|
29 |
|
|
30 |
#define START_ADDR 15 |
|
31 |
|
|
32 |
#define LEASE_TIME (24 * 3600) |
|
33 |
|
|
34 |
typedef struct { |
|
35 |
uint8_t allocated; |
|
36 |
} BOOTPClient; |
|
37 |
|
|
38 |
BOOTPClient bootp_clients[NB_ADDR]; |
|
39 |
|
|
40 |
static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; |
|
41 |
|
|
42 |
#ifdef DEBUG |
|
43 |
#define dprintf(fmt, args...) \ |
|
44 |
if (slirp_debug & DBG_CALL) { fprintf(dfd, fmt, ## args); fflush(dfd); } |
|
45 |
#else |
|
46 |
#define dprintf(fmt, args...) |
|
47 |
#endif |
|
48 |
|
|
49 |
static BOOTPClient *get_new_addr(struct in_addr *paddr) |
|
50 |
{ |
|
51 |
BOOTPClient *bc; |
|
52 |
int i; |
|
53 |
|
|
54 |
for(i = 0; i < NB_ADDR; i++) { |
|
55 |
if (!bootp_clients[i].allocated) |
|
56 |
goto found; |
|
57 |
} |
|
58 |
return NULL; |
|
59 |
found: |
|
60 |
bc = &bootp_clients[i]; |
|
61 |
bc->allocated = 1; |
|
62 |
paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); |
|
63 |
return bc; |
|
64 |
} |
|
65 |
|
|
66 |
static void dhcp_decode(const uint8_t *buf, int size, |
|
67 |
int *pmsg_type) |
|
68 |
{ |
|
69 |
const uint8_t *p, *p_end; |
|
70 |
int len, tag; |
|
71 |
|
|
72 |
*pmsg_type = 0; |
|
73 |
|
|
74 |
p = buf; |
|
75 |
p_end = buf + size; |
|
76 |
if (size < 5) |
|
77 |
return; |
|
78 |
if (memcmp(p, rfc1533_cookie, 4) != 0) |
|
79 |
return; |
|
80 |
p += 4; |
|
81 |
while (p < p_end) { |
|
82 |
tag = p[0]; |
|
83 |
if (tag == RFC1533_PAD) { |
|
84 |
p++; |
|
85 |
} else if (tag == RFC1533_END) { |
|
86 |
break; |
|
87 |
} else { |
|
88 |
p++; |
|
89 |
if (p >= p_end) |
|
90 |
break; |
|
91 |
len = *p++; |
|
92 |
dprintf("dhcp: tag=0x%02x len=%d\n", tag, len); |
|
93 |
|
|
94 |
switch(tag) { |
|
95 |
case RFC2132_MSG_TYPE: |
|
96 |
if (len >= 1) |
|
97 |
*pmsg_type = p[0]; |
|
98 |
break; |
|
99 |
default: |
|
100 |
break; |
|
101 |
} |
|
102 |
p += len; |
|
103 |
} |
|
104 |
} |
|
105 |
} |
|
106 |
|
|
107 |
static void bootp_reply(struct bootp_t *bp) |
|
108 |
{ |
|
109 |
BOOTPClient *bc; |
|
110 |
struct mbuf *m; |
|
111 |
struct bootp_t *rbp; |
|
112 |
struct sockaddr_in saddr, daddr; |
|
113 |
struct in_addr dns_addr; |
|
114 |
int dhcp_msg_type, val; |
|
115 |
uint8_t *q; |
|
116 |
|
|
117 |
/* extract exact DHCP msg type */ |
|
118 |
dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type); |
|
119 |
dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type); |
|
120 |
|
|
121 |
if (dhcp_msg_type != DHCPDISCOVER && |
|
122 |
dhcp_msg_type != DHCPREQUEST) |
|
123 |
return; |
|
124 |
/* XXX: this is a hack to get the client mac address */ |
|
125 |
memcpy(client_ethaddr, bp->bp_hwaddr, 6); |
|
126 |
|
|
127 |
if ((m = m_get()) == NULL) |
|
128 |
return; |
|
129 |
m->m_data += if_maxlinkhdr; |
|
130 |
rbp = (struct bootp_t *)m->m_data; |
|
131 |
m->m_data += sizeof(struct udpiphdr); |
|
132 |
memset(rbp, 0, sizeof(struct bootp_t)); |
|
133 |
|
|
134 |
bc = get_new_addr(&daddr.sin_addr); |
|
135 |
if (!bc) { |
|
136 |
dprintf("no address left\n"); |
|
137 |
return; |
|
138 |
} |
|
139 |
dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr)); |
|
140 |
|
|
141 |
saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS); |
|
142 |
saddr.sin_port = htons(BOOTP_SERVER); |
|
143 |
|
|
144 |
daddr.sin_port = htons(BOOTP_CLIENT); |
|
145 |
|
|
146 |
rbp->bp_op = BOOTP_REPLY; |
|
147 |
rbp->bp_xid = bp->bp_xid; |
|
148 |
rbp->bp_htype = 1; |
|
149 |
rbp->bp_hlen = 6; |
|
150 |
memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); |
|
151 |
|
|
152 |
rbp->bp_yiaddr = daddr.sin_addr; /* IP address */ |
|
153 |
|
|
154 |
q = rbp->bp_vend; |
|
155 |
memcpy(q, rfc1533_cookie, 4); |
|
156 |
q += 4; |
|
157 |
|
|
158 |
if (dhcp_msg_type == DHCPDISCOVER) { |
|
159 |
*q++ = RFC2132_MSG_TYPE; |
|
160 |
*q++ = 1; |
|
161 |
*q++ = DHCPOFFER; |
|
162 |
} else if (dhcp_msg_type == DHCPREQUEST) { |
|
163 |
*q++ = RFC2132_MSG_TYPE; |
|
164 |
*q++ = 1; |
|
165 |
*q++ = DHCPACK; |
|
166 |
} |
|
167 |
|
|
168 |
if (dhcp_msg_type == DHCPDISCOVER || |
|
169 |
dhcp_msg_type == DHCPREQUEST) { |
|
170 |
*q++ = RFC2132_SRV_ID; |
|
171 |
*q++ = 4; |
|
172 |
memcpy(q, &saddr.sin_addr, 4); |
|
173 |
q += 4; |
|
174 |
|
|
175 |
*q++ = RFC1533_NETMASK; |
|
176 |
*q++ = 4; |
|
177 |
*q++ = 0xff; |
|
178 |
*q++ = 0xff; |
|
179 |
*q++ = 0xff; |
|
180 |
*q++ = 0x00; |
|
181 |
|
|
182 |
*q++ = RFC1533_GATEWAY; |
|
183 |
*q++ = 4; |
|
184 |
memcpy(q, &saddr.sin_addr, 4); |
|
185 |
q += 4; |
|
186 |
|
|
187 |
*q++ = RFC1533_DNS; |
|
188 |
*q++ = 4; |
|
189 |
dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); |
|
190 |
memcpy(q, &dns_addr, 4); |
|
191 |
q += 4; |
|
192 |
|
|
193 |
*q++ = RFC2132_LEASE_TIME; |
|
194 |
*q++ = 4; |
|
195 |
val = htonl(LEASE_TIME); |
|
196 |
memcpy(q, &val, 4); |
|
197 |
q += 4; |
|
198 |
} |
|
199 |
*q++ = RFC1533_END; |
|
200 |
|
|
201 |
m->m_len = sizeof(struct bootp_t); |
|
202 |
udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); |
|
203 |
} |
|
204 |
|
|
205 |
void bootp_input(struct mbuf *m) |
|
206 |
{ |
|
207 |
struct bootp_t *bp = (struct bootp_t *)m->m_data; |
|
208 |
|
|
209 |
if (bp->bp_op == BOOTP_REQUEST) { |
|
210 |
bootp_reply(bp); |
|
211 |
} |
|
212 |
} |
b/slirp/bootp.h | ||
---|---|---|
1 |
/* bootp/dhcp defines */ |
|
2 |
|
|
3 |
#define BOOTP_SERVER 67 |
|
4 |
#define BOOTP_CLIENT 68 |
|
5 |
|
|
6 |
#define BOOTP_REQUEST 1 |
|
7 |
#define BOOTP_REPLY 2 |
|
8 |
|
|
9 |
#define RFC1533_COOKIE 99, 130, 83, 99 |
|
10 |
#define RFC1533_PAD 0 |
|
11 |
#define RFC1533_NETMASK 1 |
|
12 |
#define RFC1533_TIMEOFFSET 2 |
|
13 |
#define RFC1533_GATEWAY 3 |
|
14 |
#define RFC1533_TIMESERVER 4 |
|
15 |
#define RFC1533_IEN116NS 5 |
|
16 |
#define RFC1533_DNS 6 |
|
17 |
#define RFC1533_LOGSERVER 7 |
|
18 |
#define RFC1533_COOKIESERVER 8 |
|
19 |
#define RFC1533_LPRSERVER 9 |
|
20 |
#define RFC1533_IMPRESSSERVER 10 |
|
21 |
#define RFC1533_RESOURCESERVER 11 |
|
22 |
#define RFC1533_HOSTNAME 12 |
|
23 |
#define RFC1533_BOOTFILESIZE 13 |
|
24 |
#define RFC1533_MERITDUMPFILE 14 |
|
25 |
#define RFC1533_DOMAINNAME 15 |
|
26 |
#define RFC1533_SWAPSERVER 16 |
|
27 |
#define RFC1533_ROOTPATH 17 |
|
28 |
#define RFC1533_EXTENSIONPATH 18 |
|
29 |
#define RFC1533_IPFORWARDING 19 |
|
30 |
#define RFC1533_IPSOURCEROUTING 20 |
|
31 |
#define RFC1533_IPPOLICYFILTER 21 |
|
32 |
#define RFC1533_IPMAXREASSEMBLY 22 |
|
33 |
#define RFC1533_IPTTL 23 |
|
34 |
#define RFC1533_IPMTU 24 |
|
35 |
#define RFC1533_IPMTUPLATEAU 25 |
|
36 |
#define RFC1533_INTMTU 26 |
|
37 |
#define RFC1533_INTLOCALSUBNETS 27 |
|
38 |
#define RFC1533_INTBROADCAST 28 |
|
39 |
#define RFC1533_INTICMPDISCOVER 29 |
|
40 |
#define RFC1533_INTICMPRESPOND 30 |
|
41 |
#define RFC1533_INTROUTEDISCOVER 31 |
|
42 |
#define RFC1533_INTROUTESOLICIT 32 |
|
43 |
#define RFC1533_INTSTATICROUTES 33 |
|
44 |
#define RFC1533_LLTRAILERENCAP 34 |
|
45 |
#define RFC1533_LLARPCACHETMO 35 |
|
46 |
#define RFC1533_LLETHERNETENCAP 36 |
|
47 |
#define RFC1533_TCPTTL 37 |
|
48 |
#define RFC1533_TCPKEEPALIVETMO 38 |
|
49 |
#define RFC1533_TCPKEEPALIVEGB 39 |
|
50 |
#define RFC1533_NISDOMAIN 40 |
|
51 |
#define RFC1533_NISSERVER 41 |
|
52 |
#define RFC1533_NTPSERVER 42 |
|
53 |
#define RFC1533_VENDOR 43 |
|
54 |
#define RFC1533_NBNS 44 |
|
55 |
#define RFC1533_NBDD 45 |
|
56 |
#define RFC1533_NBNT 46 |
|
57 |
#define RFC1533_NBSCOPE 47 |
|
58 |
#define RFC1533_XFS 48 |
|
59 |
#define RFC1533_XDM 49 |
|
60 |
|
|
61 |
#define RFC2132_REQ_ADDR 50 |
|
62 |
#define RFC2132_LEASE_TIME 51 |
|
63 |
#define RFC2132_MSG_TYPE 53 |
|
64 |
#define RFC2132_SRV_ID 54 |
|
65 |
#define RFC2132_PARAM_LIST 55 |
|
66 |
#define RFC2132_MAX_SIZE 57 |
|
67 |
#define RFC2132_RENEWAL_TIME 58 |
|
68 |
#define RFC2132_REBIND_TIME 59 |
|
69 |
|
|
70 |
#define DHCPDISCOVER 1 |
|
71 |
#define DHCPOFFER 2 |
|
72 |
#define DHCPREQUEST 3 |
|
73 |
#define DHCPACK 5 |
|
74 |
|
|
75 |
#define RFC1533_VENDOR_MAJOR 0 |
|
76 |
#define RFC1533_VENDOR_MINOR 0 |
|
77 |
|
|
78 |
#define RFC1533_VENDOR_MAGIC 128 |
|
79 |
#define RFC1533_VENDOR_ADDPARM 129 |
|
80 |
#define RFC1533_VENDOR_ETHDEV 130 |
|
81 |
#define RFC1533_VENDOR_HOWTO 132 |
|
82 |
#define RFC1533_VENDOR_MNUOPTS 160 |
|
83 |
#define RFC1533_VENDOR_SELECTION 176 |
|
84 |
#define RFC1533_VENDOR_MOTD 184 |
|
85 |
#define RFC1533_VENDOR_NUMOFMOTD 8 |
|
86 |
#define RFC1533_VENDOR_IMG 192 |
|
87 |
#define RFC1533_VENDOR_NUMOFIMG 16 |
|
88 |
|
|
89 |
#define RFC1533_END 255 |
|
90 |
#define BOOTP_VENDOR_LEN 64 |
|
91 |
#define DHCP_OPT_LEN 312 |
|
92 |
|
|
93 |
struct bootp_t { |
|
94 |
struct ip ip; |
|
95 |
struct udphdr udp; |
|
96 |
uint8_t bp_op; |
|
97 |
uint8_t bp_htype; |
|
98 |
uint8_t bp_hlen; |
|
99 |
uint8_t bp_hops; |
|
100 |
unsigned long bp_xid; |
|
101 |
unsigned short bp_secs; |
|
102 |
unsigned short unused; |
|
103 |
struct in_addr bp_ciaddr; |
|
104 |
struct in_addr bp_yiaddr; |
|
105 |
struct in_addr bp_siaddr; |
|
106 |
struct in_addr bp_giaddr; |
|
107 |
uint8_t bp_hwaddr[16]; |
|
108 |
uint8_t bp_sname[64]; |
|
109 |
uint8_t bp_file[128]; |
|
110 |
uint8_t bp_vend[DHCP_OPT_LEN]; |
|
111 |
}; |
|
112 |
|
|
113 |
void bootp_input(struct mbuf *m); |
b/slirp/cksum.c | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 1988, 1992, 1993 |
|
3 |
* The Regents of the University of California. All rights reserved. |
|
4 |
* |
|
5 |
* Redistribution and use in source and binary forms, with or without |
|
6 |
* modification, are permitted provided that the following conditions |
|
7 |
* are met: |
|
8 |
* 1. Redistributions of source code must retain the above copyright |
|
9 |
* notice, this list of conditions and the following disclaimer. |
|
10 |
* 2. Redistributions in binary form must reproduce the above copyright |
|
11 |
* notice, this list of conditions and the following disclaimer in the |
|
12 |
* documentation and/or other materials provided with the distribution. |
|
13 |
* 3. All advertising materials mentioning features or use of this software |
|
14 |
* must display the following acknowledgement: |
|
15 |
* This product includes software developed by the University of |
|
16 |
* California, Berkeley and its contributors. |
|
17 |
* 4. Neither the name of the University nor the names of its contributors |
|
18 |
* may be used to endorse or promote products derived from this software |
|
19 |
* without specific prior written permission. |
|
20 |
* |
|
21 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
22 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
23 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
24 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
25 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
26 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
27 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
28 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
29 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
30 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
31 |
* SUCH DAMAGE. |
|
32 |
* |
|
33 |
* @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 |
|
34 |
* in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp |
|
35 |
*/ |
|
36 |
|
|
37 |
#include <slirp.h> |
|
38 |
|
|
39 |
/* |
|
40 |
* Checksum routine for Internet Protocol family headers (Portable Version). |
|
41 |
* |
|
42 |
* This routine is very heavily used in the network |
|
43 |
* code and should be modified for each CPU to be as fast as possible. |
|
44 |
* |
|
45 |
* XXX Since we will never span more than 1 mbuf, we can optimise this |
|
46 |
*/ |
|
47 |
|
|
48 |
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) |
|
49 |
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} |
|
50 |
|
|
51 |
int cksum(struct mbuf *m, int len) |
|
52 |
{ |
|
53 |
register u_int16_t *w; |
|
54 |
register int sum = 0; |
|
55 |
register int mlen = 0; |
|
56 |
int byte_swapped = 0; |
|
57 |
|
|
58 |
union { |
|
59 |
u_int8_t c[2]; |
|
60 |
u_int16_t s; |
|
61 |
} s_util; |
|
62 |
union { |
|
63 |
u_int16_t s[2]; |
|
64 |
u_int32_t l; |
|
65 |
} l_util; |
|
66 |
|
|
67 |
if (m->m_len == 0) |
|
68 |
goto cont; |
|
69 |
w = mtod(m, u_int16_t *); |
|
70 |
|
|
71 |
mlen = m->m_len; |
|
72 |
|
|
73 |
if (len < mlen) |
|
74 |
mlen = len; |
|
75 |
len -= mlen; |
|
76 |
/* |
|
77 |
* Force to even boundary. |
|
78 |
*/ |
|
79 |
if ((1 & (long) w) && (mlen > 0)) { |
|
80 |
REDUCE; |
|
81 |
sum <<= 8; |
|
82 |
s_util.c[0] = *(u_int8_t *)w; |
|
83 |
w = (u_int16_t *)((int8_t *)w + 1); |
|
84 |
mlen--; |
|
85 |
byte_swapped = 1; |
|
86 |
} |
|
87 |
/* |
|
88 |
* Unroll the loop to make overhead from |
|
89 |
* branches &c small. |
|
90 |
*/ |
|
91 |
while ((mlen -= 32) >= 0) { |
|
92 |
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; |
|
93 |
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; |
|
94 |
sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11]; |
|
95 |
sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; |
|
96 |
w += 16; |
|
97 |
} |
|
98 |
mlen += 32; |
|
99 |
while ((mlen -= 8) >= 0) { |
|
100 |
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; |
|
101 |
w += 4; |
|
102 |
} |
|
103 |
mlen += 8; |
|
104 |
if (mlen == 0 && byte_swapped == 0) |
|
105 |
goto cont; |
|
106 |
REDUCE; |
|
107 |
while ((mlen -= 2) >= 0) { |
|
108 |
sum += *w++; |
|
109 |
} |
|
110 |
|
|
111 |
if (byte_swapped) { |
|
112 |
REDUCE; |
|
113 |
sum <<= 8; |
|
114 |
byte_swapped = 0; |
|
115 |
if (mlen == -1) { |
|
116 |
s_util.c[1] = *(u_int8_t *)w; |
|
117 |
sum += s_util.s; |
|
118 |
mlen = 0; |
|
119 |
} else |
|
120 |
|
|
121 |
mlen = -1; |
|
122 |
} else if (mlen == -1) |
|
123 |
s_util.c[0] = *(u_int8_t *)w; |
|
124 |
|
|
125 |
cont: |
|
126 |
#ifdef DEBUG |
|
127 |
if (len) { |
|
128 |
DEBUG_ERROR((dfd, "cksum: out of data\n")); |
|
129 |
DEBUG_ERROR((dfd, " len = %d\n", len)); |
|
130 |
} |
|
131 |
#endif |
|
132 |
if (mlen == -1) { |
|
133 |
/* The last mbuf has odd # of bytes. Follow the |
|
134 |
standard (the odd byte may be shifted left by 8 bits |
|
135 |
or not as determined by endian-ness of the machine) */ |
|
136 |
s_util.c[1] = 0; |
|
137 |
sum += s_util.s; |
|
138 |
} |
|
139 |
REDUCE; |
|
140 |
return (~sum & 0xffff); |
|
141 |
} |
b/slirp/ctl.h | ||
---|---|---|
1 |
#define CTL_CMD 0 |
|
2 |
#define CTL_EXEC 1 |
|
3 |
#define CTL_ALIAS 2 |
|
4 |
#define CTL_DNS 3 |
|
5 |
|
|
6 |
#define CTL_SPECIAL "10.0.2.0" |
|
7 |
#define CTL_LOCAL "10.0.2.15" |
b/slirp/debug.c | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 1995 Danny Gasparovski. |
|
3 |
* Portions copyright (c) 2000 Kelly Price. |
|
4 |
* |
|
5 |
* Please read the file COPYRIGHT for the |
|
6 |
* terms and conditions of the copyright. |
|
7 |
*/ |
|
8 |
|
|
9 |
#include <slirp.h> |
|
10 |
|
|
11 |
FILE *dfd = NULL; |
|
12 |
#ifdef DEBUG |
|
13 |
int dostats = 1; |
|
14 |
#else |
|
15 |
int dostats = 0; |
|
16 |
#endif |
|
17 |
int slirp_debug = 0; |
|
18 |
|
|
19 |
extern char *strerror _P((int)); |
|
20 |
|
|
21 |
/* Carry over one item from main.c so that the tty's restored. |
|
22 |
* Only done when the tty being used is /dev/tty --RedWolf */ |
|
23 |
extern struct termios slirp_tty_settings; |
|
24 |
extern int slirp_tty_restore; |
|
25 |
|
|
26 |
|
|
27 |
void |
|
28 |
debug_init(file, dbg) |
|
29 |
char *file; |
|
30 |
int dbg; |
|
31 |
{ |
|
32 |
/* Close the old debugging file */ |
|
33 |
if (dfd) |
|
34 |
fclose(dfd); |
|
35 |
|
|
36 |
dfd = fopen(file,"w"); |
|
37 |
if (dfd != NULL) { |
|
38 |
#if 0 |
|
39 |
fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION); |
|
40 |
#endif |
|
41 |
fprintf(dfd,"Debugging Started level %i.\r\n",dbg); |
|
42 |
fflush(dfd); |
|
43 |
slirp_debug = dbg; |
|
44 |
} else { |
|
45 |
lprint("Error: Debugging file \"%s\" could not be opened: %s\r\n", |
|
46 |
file, strerror(errno)); |
|
47 |
} |
|
48 |
} |
|
49 |
|
|
50 |
/* |
|
51 |
* Dump a packet in the same format as tcpdump -x |
|
52 |
*/ |
|
53 |
#ifdef DEBUG |
|
54 |
void |
|
55 |
dump_packet(dat, n) |
|
56 |
void *dat; |
|
57 |
int n; |
|
58 |
{ |
|
59 |
u_char *pptr = (u_char *)dat; |
|
60 |
int j,k; |
|
61 |
|
|
62 |
n /= 16; |
|
63 |
n++; |
|
64 |
DEBUG_MISC((dfd, "PACKET DUMPED: \n")); |
|
65 |
for(j = 0; j < n; j++) { |
|
66 |
for(k = 0; k < 6; k++) |
|
67 |
DEBUG_MISC((dfd, "%02x ", *pptr++)); |
|
68 |
DEBUG_MISC((dfd, "\n")); |
|
69 |
fflush(dfd); |
|
70 |
} |
|
71 |
} |
|
72 |
#endif |
|
73 |
|
|
74 |
#if 0 |
|
75 |
/* |
|
76 |
* Statistic routines |
|
77 |
* |
|
78 |
* These will print statistics to the screen, the debug file (dfd), or |
|
79 |
* a buffer, depending on "type", so that the stats can be sent over |
|
80 |
* the link as well. |
|
81 |
*/ |
|
82 |
|
|
83 |
void |
|
84 |
ttystats(ttyp) |
|
85 |
struct ttys *ttyp; |
|
86 |
{ |
|
87 |
struct slirp_ifstats *is = &ttyp->ifstats; |
|
88 |
char buff[512]; |
|
89 |
|
|
90 |
lprint(" \r\n"); |
|
91 |
|
|
92 |
if (if_comp & IF_COMPRESS) |
|
93 |
strcpy(buff, "on"); |
|
94 |
else if (if_comp & IF_NOCOMPRESS) |
|
95 |
strcpy(buff, "off"); |
|
96 |
else |
|
97 |
strcpy(buff, "off (for now)"); |
|
98 |
lprint("Unit %d:\r\n", ttyp->unit); |
|
99 |
lprint(" using %s encapsulation (VJ compression is %s)\r\n", ( |
|
100 |
#ifdef USE_PPP |
|
101 |
ttyp->proto==PROTO_PPP?"PPP": |
|
102 |
#endif |
|
103 |
"SLIP"), buff); |
|
104 |
lprint(" %d baudrate\r\n", ttyp->baud); |
|
105 |
lprint(" interface is %s\r\n", ttyp->up?"up":"down"); |
|
106 |
lprint(" using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid); |
|
107 |
#ifndef FULL_BOLT |
|
108 |
lprint(" towrite is %d bytes\r\n", ttyp->towrite); |
|
109 |
#endif |
|
110 |
if (ttyp->zeros) |
|
111 |
lprint(" %d zeros have been typed\r\n", ttyp->zeros); |
|
112 |
else if (ttyp->ones) |
|
113 |
lprint(" %d ones have been typed\r\n", ttyp->ones); |
|
114 |
lprint("Interface stats:\r\n"); |
|
115 |
lprint(" %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes); |
|
116 |
lprint(" %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes); |
|
117 |
lprint(" %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes); |
|
118 |
lprint(" %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes); |
|
119 |
lprint(" %6d bad input packets\r\n", is->in_mbad); |
|
120 |
} |
|
121 |
|
|
122 |
void |
|
123 |
allttystats() |
|
124 |
{ |
|
125 |
struct ttys *ttyp; |
|
126 |
|
|
127 |
for (ttyp = ttys; ttyp; ttyp = ttyp->next) |
|
128 |
ttystats(ttyp); |
|
129 |
} |
|
130 |
#endif |
|
131 |
|
|
132 |
void |
|
133 |
ipstats() |
|
134 |
{ |
|
135 |
lprint(" \r\n"); |
|
136 |
|
|
137 |
lprint("IP stats:\r\n"); |
|
138 |
lprint(" %6d total packets received (%d were unaligned)\r\n", |
|
139 |
ipstat.ips_total, ipstat.ips_unaligned); |
|
140 |
lprint(" %6d with incorrect version\r\n", ipstat.ips_badvers); |
|
141 |
lprint(" %6d with bad header checksum\r\n", ipstat.ips_badsum); |
|
142 |
lprint(" %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort); |
|
143 |
lprint(" %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall); |
|
144 |
lprint(" %6d with bad header length\r\n", ipstat.ips_badhlen); |
|
145 |
lprint(" %6d with bad packet length\r\n", ipstat.ips_badlen); |
|
146 |
lprint(" %6d fragments received\r\n", ipstat.ips_fragments); |
|
147 |
lprint(" %6d fragments dropped\r\n", ipstat.ips_fragdropped); |
|
148 |
lprint(" %6d fragments timed out\r\n", ipstat.ips_fragtimeout); |
|
149 |
lprint(" %6d packets reassembled ok\r\n", ipstat.ips_reassembled); |
|
150 |
lprint(" %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented); |
|
151 |
lprint(" %6d total outgoing fragments\r\n", ipstat.ips_ofragments); |
|
152 |
lprint(" %6d with bad protocol field\r\n", ipstat.ips_noproto); |
|
153 |
lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered); |
|
154 |
} |
|
155 |
|
|
156 |
#if 0 |
|
157 |
void |
|
158 |
vjstats() |
|
159 |
{ |
|
160 |
lprint(" \r\n"); |
|
161 |
|
|
162 |
lprint("VJ compression stats:\r\n"); |
|
163 |
|
|
164 |
lprint(" %6d outbound packets (%d compressed)\r\n", |
|
165 |
comp_s.sls_packets, comp_s.sls_compressed); |
|
166 |
lprint(" %6d searches for connection stats (%d misses)\r\n", |
|
167 |
comp_s.sls_searches, comp_s.sls_misses); |
|
168 |
lprint(" %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin); |
|
169 |
lprint(" %6d inbound compressed packets\r\n", comp_s.sls_compressedin); |
|
170 |
lprint(" %6d inbound unknown type packets\r\n", comp_s.sls_errorin); |
|
171 |
lprint(" %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed); |
|
172 |
} |
|
173 |
#endif |
|
174 |
|
|
175 |
void |
|
176 |
tcpstats() |
|
177 |
{ |
|
178 |
lprint(" \r\n"); |
|
179 |
|
|
180 |
lprint("TCP stats:\r\n"); |
|
181 |
|
|
182 |
lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal); |
|
183 |
lprint(" %6d data packets (%d bytes)\r\n", |
|
184 |
tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte); |
|
185 |
lprint(" %6d data packets retransmitted (%d bytes)\r\n", |
|
186 |
tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte); |
|
187 |
lprint(" %6d ack-only packets (%d delayed)\r\n", |
|
188 |
tcpstat.tcps_sndacks, tcpstat.tcps_delack); |
|
189 |
lprint(" %6d URG only packets\r\n", tcpstat.tcps_sndurg); |
|
190 |
lprint(" %6d window probe packets\r\n", tcpstat.tcps_sndprobe); |
|
191 |
lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup); |
|
192 |
lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl); |
|
193 |
lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin); |
|
194 |
|
|
195 |
lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal); |
|
196 |
lprint(" %6d acks (for %d bytes)\r\n", |
|
197 |
tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte); |
|
198 |
lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack); |
|
199 |
lprint(" %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch); |
|
200 |
lprint(" %6d packets received in sequence (%d bytes)\r\n", |
|
201 |
tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte); |
|
202 |
lprint(" %6d completely duplicate packets (%d bytes)\r\n", |
|
203 |
tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte); |
|
204 |
|
|
205 |
lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n", |
|
206 |
tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte); |
|
207 |
lprint(" %6d out-of-order packets (%d bytes)\r\n", |
|
208 |
tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte); |
|
209 |
lprint(" %6d packets of data after window (%d bytes)\r\n", |
|
210 |
tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin); |
|
211 |
lprint(" %6d window probes\r\n", tcpstat.tcps_rcvwinprobe); |
|
212 |
lprint(" %6d window update packets\r\n", tcpstat.tcps_rcvwinupd); |
|
213 |
lprint(" %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose); |
|
214 |
lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum); |
|
215 |
lprint(" %6d discarded for bad header offset fields\r\n", |
|
216 |
tcpstat.tcps_rcvbadoff); |
|
217 |
|
|
218 |
lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt); |
|
219 |
lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts); |
|
220 |
lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects); |
|
221 |
lprint(" %6d connections closed (including %d drop)\r\n", |
|
222 |
tcpstat.tcps_closed, tcpstat.tcps_drops); |
|
223 |
lprint(" %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops); |
|
224 |
lprint(" %6d segments we tried to get rtt (%d succeeded)\r\n", |
|
225 |
tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated); |
|
226 |
lprint(" %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo); |
|
227 |
lprint(" %6d connections dropped by rxmt timeout\r\n", |
|
228 |
tcpstat.tcps_timeoutdrop); |
|
229 |
lprint(" %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo); |
|
230 |
lprint(" %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo); |
|
231 |
lprint(" %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe); |
|
232 |
lprint(" %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops); |
|
233 |
lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack); |
|
234 |
lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat); |
|
235 |
lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss); |
|
236 |
|
|
237 |
|
|
238 |
/* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */ |
|
239 |
/* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */ |
|
240 |
|
|
241 |
} |
|
242 |
|
|
243 |
void |
|
244 |
udpstats() |
|
245 |
{ |
|
246 |
lprint(" \r\n"); |
|
247 |
|
|
248 |
lprint("UDP stats:\r\n"); |
|
249 |
lprint(" %6d datagrams received\r\n", udpstat.udps_ipackets); |
|
250 |
lprint(" %6d with packets shorter than header\r\n", udpstat.udps_hdrops); |
|
251 |
lprint(" %6d with bad checksums\r\n", udpstat.udps_badsum); |
|
252 |
lprint(" %6d with data length larger than packet\r\n", udpstat.udps_badlen); |
|
253 |
lprint(" %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss); |
|
254 |
lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets); |
|
255 |
} |
|
256 |
|
|
257 |
void |
|
258 |
icmpstats() |
|
259 |
{ |
|
260 |
lprint(" \r\n"); |
|
261 |
lprint("ICMP stats:\r\n"); |
|
262 |
lprint(" %6d ICMP packets received\r\n", icmpstat.icps_received); |
|
263 |
lprint(" %6d were too short\r\n", icmpstat.icps_tooshort); |
|
264 |
lprint(" %6d with bad checksums\r\n", icmpstat.icps_checksum); |
|
265 |
lprint(" %6d with type not supported\r\n", icmpstat.icps_notsupp); |
|
266 |
lprint(" %6d with bad type feilds\r\n", icmpstat.icps_badtype); |
|
267 |
lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect); |
|
268 |
} |
|
269 |
|
|
270 |
void |
|
271 |
mbufstats() |
|
272 |
{ |
|
273 |
struct mbuf *m; |
|
274 |
int i; |
|
275 |
|
|
276 |
lprint(" \r\n"); |
|
277 |
|
|
278 |
lprint("Mbuf stats:\r\n"); |
|
279 |
|
|
280 |
lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max); |
|
281 |
|
|
282 |
i = 0; |
|
283 |
for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next) |
|
284 |
i++; |
|
285 |
lprint(" %6d mbufs on free list\r\n", i); |
|
286 |
|
|
287 |
i = 0; |
|
288 |
for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) |
|
289 |
i++; |
|
290 |
lprint(" %6d mbufs on used list\r\n", i); |
|
291 |
lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued); |
|
292 |
} |
|
293 |
|
|
294 |
void |
|
295 |
sockstats() |
|
296 |
{ |
|
297 |
char buff[256]; |
|
298 |
int n; |
|
299 |
struct socket *so; |
|
300 |
|
|
301 |
lprint(" \r\n"); |
|
302 |
|
|
303 |
lprint( |
|
304 |
"Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n"); |
|
305 |
|
|
306 |
for (so = tcb.so_next; so != &tcb; so = so->so_next) { |
|
307 |
|
|
308 |
n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE"); |
|
309 |
while (n < 17) |
|
310 |
buff[n++] = ' '; |
|
311 |
buff[17] = 0; |
|
312 |
lprint("%s %3d %15s %5d ", |
|
313 |
buff, so->s, |
|
314 |
inet_ntoa(so->so_laddr), ntohs(so->so_lport)); |
|
315 |
lprint("%15s %5d %5d %5d\r\n", |
|
316 |
inet_ntoa(so->so_faddr), ntohs(so->so_fport), |
|
317 |
so->so_rcv.sb_cc, so->so_snd.sb_cc); |
|
318 |
} |
|
319 |
|
|
320 |
for (so = udb.so_next; so != &udb; so = so->so_next) { |
|
321 |
|
|
322 |
n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000); |
|
323 |
while (n < 17) |
|
324 |
buff[n++] = ' '; |
|
325 |
buff[17] = 0; |
|
326 |
lprint("%s %3d %15s %5d ", |
|
327 |
buff, so->s, |
|
328 |
inet_ntoa(so->so_laddr), ntohs(so->so_lport)); |
|
329 |
lprint("%15s %5d %5d %5d\r\n", |
|
330 |
inet_ntoa(so->so_faddr), ntohs(so->so_fport), |
|
331 |
so->so_rcv.sb_cc, so->so_snd.sb_cc); |
|
332 |
} |
|
333 |
} |
|
334 |
|
|
335 |
#if 0 |
|
336 |
void |
|
337 |
slirp_exit(exit_status) |
|
338 |
int exit_status; |
|
339 |
{ |
|
340 |
struct ttys *ttyp; |
|
341 |
|
|
342 |
DEBUG_CALL("slirp_exit"); |
|
343 |
DEBUG_ARG("exit_status = %d", exit_status); |
|
344 |
|
|
345 |
if (dostats) { |
|
346 |
lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf; |
|
347 |
if (!dfd) |
|
348 |
debug_init("slirp_stats", 0xf); |
|
349 |
lprint_arg = (char **)&dfd; |
|
350 |
|
|
351 |
ipstats(); |
|
352 |
tcpstats(); |
|
353 |
udpstats(); |
|
354 |
icmpstats(); |
|
355 |
mbufstats(); |
|
356 |
sockstats(); |
|
357 |
allttystats(); |
|
358 |
vjstats(); |
|
359 |
} |
|
360 |
|
|
361 |
for (ttyp = ttys; ttyp; ttyp = ttyp->next) |
|
362 |
tty_detached(ttyp, 1); |
|
363 |
|
|
364 |
if (slirp_forked) { |
|
365 |
/* Menendez time */ |
|
366 |
if (kill(getppid(), SIGQUIT) < 0) |
|
367 |
lprint("Couldn't kill parent process %ld!\n", |
|
368 |
(long) getppid()); |
|
369 |
} |
|
370 |
|
|
371 |
/* Restore the terminal if we gotta */ |
|
372 |
if(slirp_tty_restore) |
|
373 |
tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */ |
|
374 |
exit(exit_status); |
|
375 |
} |
|
376 |
#endif |
b/slirp/debug.h | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 1995 Danny Gasparovski. |
|
3 |
* |
|
4 |
* Please read the file COPYRIGHT for the |
|
5 |
* terms and conditions of the copyright. |
|
6 |
*/ |
|
7 |
|
|
8 |
#define PRN_STDERR 1 |
|
9 |
#define PRN_SPRINTF 2 |
|
10 |
|
|
11 |
extern FILE *dfd; |
|
12 |
extern FILE *lfd; |
|
13 |
extern int dostats; |
|
14 |
extern int slirp_debug; |
|
15 |
|
|
16 |
#define DBG_CALL 0x1 |
|
17 |
#define DBG_MISC 0x2 |
|
18 |
#define DBG_ERROR 0x4 |
|
19 |
#define DEBUG_DEFAULT DBG_CALL|DBG_MISC|DBG_ERROR |
|
20 |
|
|
21 |
#ifdef DEBUG |
|
22 |
#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); } |
|
23 |
#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); } |
|
24 |
#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); } |
|
25 |
#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); } |
|
26 |
#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); } |
|
27 |
|
|
28 |
|
|
29 |
#else |
|
30 |
|
|
31 |
#define DEBUG_CALL(x) |
|
32 |
#define DEBUG_ARG(x, y) |
|
33 |
#define DEBUG_ARGS(x) |
|
34 |
#define DEBUG_MISC(x) |
|
35 |
#define DEBUG_ERROR(x) |
|
36 |
|
|
37 |
#endif |
|
38 |
|
|
39 |
void debug_init _P((char *, int)); |
|
40 |
//void ttystats _P((struct ttys *)); |
|
41 |
void allttystats _P((void)); |
|
42 |
void ipstats _P((void)); |
|
43 |
void vjstats _P((void)); |
|
44 |
void tcpstats _P((void)); |
|
45 |
void udpstats _P((void)); |
|
46 |
void icmpstats _P((void)); |
|
47 |
void mbufstats _P((void)); |
|
48 |
void sockstats _P((void)); |
|
49 |
void slirp_exit _P((int)); |
|
50 |
|
b/slirp/icmp_var.h | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 1982, 1986, 1993 |
|
3 |
* The Regents of the University of California. All rights reserved. |
|
4 |
* |
|
5 |
* Redistribution and use in source and binary forms, with or without |
|
6 |
* modification, are permitted provided that the following conditions |
|
7 |
* are met: |
|
8 |
* 1. Redistributions of source code must retain the above copyright |
|
9 |
* notice, this list of conditions and the following disclaimer. |
|
10 |
* 2. Redistributions in binary form must reproduce the above copyright |
|
11 |
* notice, this list of conditions and the following disclaimer in the |
|
12 |
* documentation and/or other materials provided with the distribution. |
|
13 |
* 3. All advertising materials mentioning features or use of this software |
|
14 |
* must display the following acknowledgement: |
|
15 |
* This product includes software developed by the University of |
|
16 |
* California, Berkeley and its contributors. |
|
17 |
* 4. Neither the name of the University nor the names of its contributors |
|
18 |
* may be used to endorse or promote products derived from this software |
|
19 |
* without specific prior written permission. |
|
20 |
* |
|
21 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
22 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
23 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
24 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
25 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
26 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
27 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
28 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
29 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
30 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
31 |
* SUCH DAMAGE. |
|
32 |
* |
|
33 |
* @(#)icmp_var.h 8.1 (Berkeley) 6/10/93 |
|
34 |
* icmp_var.h,v 1.4 1995/02/16 00:27:40 wollman Exp |
|
35 |
*/ |
|
36 |
|
|
37 |
#ifndef _NETINET_ICMP_VAR_H_ |
|
38 |
#define _NETINET_ICMP_VAR_H_ |
|
39 |
|
|
40 |
/* |
|
41 |
* Variables related to this implementation |
|
42 |
* of the internet control message protocol. |
|
43 |
*/ |
|
44 |
struct icmpstat { |
|
45 |
/* statistics related to input messages processed */ |
|
46 |
u_long icps_received; /* #ICMP packets received */ |
|
47 |
u_long icps_tooshort; /* packet < ICMP_MINLEN */ |
|
48 |
u_long icps_checksum; /* bad checksum */ |
|
49 |
u_long icps_notsupp; /* #ICMP packets not supported */ |
|
50 |
u_long icps_badtype; /* #with bad type feild */ |
|
51 |
u_long icps_reflect; /* number of responses */ |
|
52 |
}; |
|
53 |
|
|
54 |
/* |
|
55 |
* Names for ICMP sysctl objects |
|
56 |
*/ |
|
57 |
#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */ |
|
58 |
#define ICMPCTL_STATS 2 /* statistics (read-only) */ |
|
59 |
#define ICMPCTL_MAXID 3 |
|
60 |
|
|
61 |
#define ICMPCTL_NAMES { \ |
|
62 |
{ 0, 0 }, \ |
|
63 |
{ "maskrepl", CTLTYPE_INT }, \ |
|
64 |
{ "stats", CTLTYPE_STRUCT }, \ |
|
65 |
} |
|
66 |
|
|
67 |
extern struct icmpstat icmpstat; |
|
68 |
|
|
69 |
#endif |
b/slirp/if.c | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 1995 Danny Gasparovski. |
|
3 |
* |
|
4 |
* Please read the file COPYRIGHT for the |
|
5 |
* terms and conditions of the copyright. |
|
6 |
*/ |
|
7 |
|
|
8 |
#include <slirp.h> |
|
9 |
|
|
10 |
int if_mtu, if_mru; |
|
11 |
int if_comp; |
|
12 |
int if_maxlinkhdr; |
|
13 |
int if_queued = 0; /* Number of packets queued so far */ |
|
14 |
int if_thresh = 10; /* Number of packets queued before we start sending |
|
15 |
* (to prevent allocing too many mbufs) */ |
|
16 |
|
|
17 |
struct mbuf if_fastq; /* fast queue (for interactive data) */ |
|
18 |
struct mbuf if_batchq; /* queue for non-interactive data */ |
|
19 |
struct mbuf *next_m; /* Pointer to next mbuf to output */ |
|
20 |
|
|
21 |
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) |
|
22 |
|
|
23 |
void |
|
24 |
ifs_insque(ifm, ifmhead) |
|
25 |
struct mbuf *ifm, *ifmhead; |
|
26 |
{ |
|
27 |
ifm->ifs_next = ifmhead->ifs_next; |
|
28 |
ifmhead->ifs_next = ifm; |
|
29 |
ifm->ifs_prev = ifmhead; |
|
30 |
ifm->ifs_next->ifs_prev = ifm; |
|
31 |
} |
|
32 |
|
|
33 |
void |
|
34 |
ifs_remque(ifm) |
|
35 |
struct mbuf *ifm; |
|
36 |
{ |
|
37 |
ifm->ifs_prev->ifs_next = ifm->ifs_next; |
|
38 |
ifm->ifs_next->ifs_prev = ifm->ifs_prev; |
|
39 |
} |
|
40 |
|
|
41 |
void |
|
42 |
if_init() |
|
43 |
{ |
|
44 |
#if 0 |
|
45 |
/* |
|
46 |
* Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP, |
|
47 |
* and 8 bytes for PPP, but need to have it on an 8byte boundary |
|
48 |
*/ |
|
49 |
#ifdef USE_PPP |
|
50 |
if_maxlinkhdr = 48; |
|
51 |
#else |
|
52 |
if_maxlinkhdr = 40; |
|
53 |
#endif |
|
54 |
#else |
|
55 |
/* 14 for ethernet + 40 */ |
|
56 |
if_maxlinkhdr = 14 + 40; |
|
57 |
#endif |
|
58 |
if_mtu = 1500; |
|
59 |
if_mru = 1500; |
|
60 |
if_comp = IF_AUTOCOMP; |
|
61 |
if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; |
|
62 |
if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; |
|
63 |
// sl_compress_init(&comp_s); |
|
64 |
next_m = &if_batchq; |
|
65 |
} |
|
66 |
|
|
67 |
#if 0 |
|
68 |
/* |
|
69 |
* This shouldn't be needed since the modem is blocking and |
|
70 |
* we don't expect any signals, but what the hell.. |
|
71 |
*/ |
|
72 |
inline int |
|
73 |
writen(fd, bptr, n) |
|
74 |
int fd; |
|
75 |
char *bptr; |
|
76 |
int n; |
|
77 |
{ |
|
78 |
int ret; |
|
79 |
int total; |
|
80 |
|
|
81 |
/* This should succeed most of the time */ |
|
82 |
ret = write(fd, bptr, n); |
|
83 |
if (ret == n || ret <= 0) |
|
84 |
return ret; |
|
85 |
|
|
86 |
/* Didn't write everything, go into the loop */ |
|
87 |
total = ret; |
|
88 |
while (n > total) { |
|
89 |
ret = write(fd, bptr+total, n-total); |
|
90 |
if (ret <= 0) |
|
91 |
return ret; |
|
92 |
total += ret; |
|
93 |
} |
|
94 |
return total; |
|
95 |
} |
|
96 |
|
|
97 |
/* |
|
98 |
* if_input - read() the tty, do "top level" processing (ie: check for any escapes), |
|
99 |
* and pass onto (*ttyp->if_input) |
|
100 |
* |
|
101 |
* XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet. |
|
102 |
*/ |
|
103 |
#define INBUFF_SIZE 2048 /* XXX */ |
|
104 |
void |
|
105 |
if_input(ttyp) |
|
106 |
struct ttys *ttyp; |
|
107 |
{ |
|
108 |
u_char if_inbuff[INBUFF_SIZE]; |
|
109 |
int if_n; |
|
110 |
|
|
111 |
DEBUG_CALL("if_input"); |
|
112 |
DEBUG_ARG("ttyp = %lx", (long)ttyp); |
|
113 |
|
|
114 |
if_n = read(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE); |
|
115 |
|
|
116 |
DEBUG_MISC((dfd, " read %d bytes\n", if_n)); |
|
117 |
|
|
118 |
if (if_n <= 0) { |
|
119 |
if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) { |
|
120 |
if (ttyp->up) |
|
121 |
link_up--; |
|
122 |
tty_detached(ttyp, 0); |
|
123 |
} |
|
124 |
return; |
|
125 |
} |
|
126 |
if (if_n == 1) { |
|
127 |
if (*if_inbuff == '0') { |
|
128 |
ttyp->ones = 0; |
|
129 |
if (++ttyp->zeros >= 5) |
|
130 |
slirp_exit(0); |
|
131 |
return; |
|
132 |
} |
|
133 |
if (*if_inbuff == '1') { |
|
134 |
ttyp->zeros = 0; |
|
135 |
if (++ttyp->ones >= 5) |
|
136 |
tty_detached(ttyp, 0); |
|
137 |
return; |
|
138 |
} |
|
139 |
} |
|
140 |
ttyp->ones = ttyp->zeros = 0; |
|
141 |
|
|
142 |
(*ttyp->if_input)(ttyp, if_inbuff, if_n); |
|
143 |
} |
|
144 |
#endif |
|
145 |
|
|
146 |
/* |
|
147 |
* if_output: Queue packet into an output queue. |
|
148 |
* There are 2 output queue's, if_fastq and if_batchq. |
|
149 |
* Each output queue is a doubly linked list of double linked lists |
|
150 |
* of mbufs, each list belonging to one "session" (socket). This |
|
151 |
* way, we can output packets fairly by sending one packet from each |
|
152 |
* session, instead of all the packets from one session, then all packets |
|
153 |
* from the next session, etc. Packets on the if_fastq get absolute |
|
154 |
* priority, but if one session hogs the link, it gets "downgraded" |
|
155 |
* to the batchq until it runs out of packets, then it'll return |
|
156 |
* to the fastq (eg. if the user does an ls -alR in a telnet session, |
|
157 |
* it'll temporarily get downgraded to the batchq) |
|
158 |
*/ |
|
159 |
void |
|
160 |
if_output(so, ifm) |
|
161 |
struct socket *so; |
|
162 |
struct mbuf *ifm; |
|
163 |
{ |
|
164 |
struct mbuf *ifq; |
|
165 |
int on_fastq = 1; |
|
166 |
|
|
167 |
DEBUG_CALL("if_output"); |
|
168 |
DEBUG_ARG("so = %lx", (long)so); |
|
169 |
DEBUG_ARG("ifm = %lx", (long)ifm); |
|
170 |
|
|
171 |
/* |
|
172 |
* First remove the mbuf from m_usedlist, |
|
173 |
* since we're gonna use m_next and m_prev ourselves |
|
174 |
* XXX Shouldn't need this, gotta change dtom() etc. |
|
175 |
*/ |
|
176 |
if (ifm->m_flags & M_USEDLIST) { |
|
177 |
remque(ifm); |
|
178 |
ifm->m_flags &= ~M_USEDLIST; |
|
179 |
} |
|
180 |
|
|
181 |
/* |
|
182 |
* See if there's already a batchq list for this session. |
|
183 |
* This can include an interactive session, which should go on fastq, |
|
184 |
* but gets too greedy... hence it'll be downgraded from fastq to batchq. |
|
185 |
* We mustn't put this packet back on the fastq (or we'll send it out of order) |
|
186 |
* XXX add cache here? |
|
187 |
*/ |
|
188 |
for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) { |
|
189 |
if (so == ifq->ifq_so) { |
|
190 |
/* A match! */ |
|
191 |
ifm->ifq_so = so; |
|
192 |
ifs_insque(ifm, ifq->ifs_prev); |
|
193 |
goto diddit; |
|
194 |
} |
|
195 |
} |
|
196 |
|
|
197 |
/* No match, check which queue to put it on */ |
|
198 |
if (so && (so->so_iptos & IPTOS_LOWDELAY)) { |
|
199 |
ifq = if_fastq.ifq_prev; |
|
200 |
on_fastq = 1; |
|
201 |
/* |
|
202 |
* Check if this packet is a part of the last |
|
203 |
* packet's session |
|
204 |
*/ |
|
205 |
if (ifq->ifq_so == so) { |
|
206 |
ifm->ifq_so = so; |
|
207 |
ifs_insque(ifm, ifq->ifs_prev); |
|
208 |
goto diddit; |
|
209 |
} |
|
210 |
} else |
|
211 |
ifq = if_batchq.ifq_prev; |
|
212 |
|
|
213 |
/* Create a new doubly linked list for this session */ |
|
214 |
ifm->ifq_so = so; |
|
215 |
ifs_init(ifm); |
|
216 |
insque(ifm, ifq); |
|
217 |
|
|
218 |
diddit: |
|
219 |
++if_queued; |
|
220 |
|
|
221 |
if (so) { |
|
222 |
/* Update *_queued */ |
|
223 |
so->so_queued++; |
|
224 |
so->so_nqueued++; |
|
225 |
/* |
|
226 |
* Check if the interactive session should be downgraded to |
|
227 |
* the batchq. A session is downgraded if it has queued 6 |
|
228 |
* packets without pausing, and at least 3 of those packets |
|
229 |
* have been sent over the link |
|
230 |
* (XXX These are arbitrary numbers, probably not optimal..) |
|
231 |
*/ |
|
232 |
if (on_fastq && ((so->so_nqueued >= 6) && |
|
233 |
(so->so_nqueued - so->so_queued) >= 3)) { |
|
234 |
|
|
235 |
/* Remove from current queue... */ |
|
236 |
remque(ifm->ifs_next); |
|
237 |
|
|
238 |
/* ...And insert in the new. That'll teach ya! */ |
|
239 |
insque(ifm->ifs_next, &if_batchq); |
|
240 |
} |
|
241 |
} |
|
242 |
|
|
243 |
#ifndef FULL_BOLT |
|
244 |
/* |
|
245 |
* This prevents us from malloc()ing too many mbufs |
|
246 |
*/ |
|
247 |
if (link_up) { |
|
248 |
/* if_start will check towrite */ |
|
249 |
if_start(); |
|
250 |
} |
|
251 |
#endif |
|
252 |
} |
|
253 |
|
|
254 |
/* |
|
255 |
* Send a packet |
|
256 |
* We choose a packet based on it's position in the output queues; |
|
257 |
* If there are packets on the fastq, they are sent FIFO, before |
|
258 |
* everything else. Otherwise we choose the first packet from the |
|
259 |
* batchq and send it. the next packet chosen will be from the session |
|
260 |
* after this one, then the session after that one, and so on.. So, |
|
261 |
* for example, if there are 3 ftp session's fighting for bandwidth, |
|
262 |
* one packet will be sent from the first session, then one packet |
|
263 |
* from the second session, then one packet from the third, then back |
|
264 |
* to the first, etc. etc. |
|
265 |
*/ |
|
266 |
void |
|
267 |
if_start(void) |
|
268 |
{ |
|
269 |
struct mbuf *ifm, *ifqt; |
|
270 |
|
|
271 |
DEBUG_CALL("if_start"); |
|
272 |
|
|
273 |
if (if_queued == 0) |
|
274 |
return; /* Nothing to do */ |
|
275 |
|
|
276 |
again: |
|
277 |
/* check if we can really output */ |
|
278 |
if (!slirp_can_output()) |
|
279 |
return; |
|
280 |
|
|
281 |
/* |
|
282 |
* See which queue to get next packet from |
|
283 |
* If there's something in the fastq, select it immediately |
|
284 |
*/ |
|
285 |
if (if_fastq.ifq_next != &if_fastq) { |
|
286 |
ifm = if_fastq.ifq_next; |
|
287 |
} else { |
|
288 |
/* Nothing on fastq, see if next_m is valid */ |
|
289 |
if (next_m != &if_batchq) |
|
290 |
ifm = next_m; |
|
291 |
else |
|
292 |
ifm = if_batchq.ifq_next; |
|
293 |
|
|
294 |
/* Set which packet to send on next iteration */ |
|
295 |
next_m = ifm->ifq_next; |
|
296 |
} |
|
297 |
/* Remove it from the queue */ |
|
298 |
ifqt = ifm->ifq_prev; |
|
299 |
remque(ifm); |
|
300 |
--if_queued; |
|
301 |
|
|
302 |
/* If there are more packets for this session, re-queue them */ |
|
303 |
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { |
|
304 |
insque(ifm->ifs_next, ifqt); |
|
305 |
ifs_remque(ifm); |
|
306 |
} |
|
307 |
|
|
308 |
/* Update so_queued */ |
|
309 |
if (ifm->ifq_so) { |
|
310 |
if (--ifm->ifq_so->so_queued == 0) |
|
311 |
/* If there's no more queued, reset nqueued */ |
|
312 |
ifm->ifq_so->so_nqueued = 0; |
|
313 |
} |
|
314 |
|
|
315 |
/* Encapsulate the packet for sending */ |
|
316 |
if_encap(ifm->m_data, ifm->m_len); |
|
317 |
|
|
318 |
if (if_queued) |
|
319 |
goto again; |
|
320 |
} |
b/slirp/if.h | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 1995 Danny Gasparovski. |
|
3 |
* |
|
4 |
* Please read the file COPYRIGHT for the |
|
5 |
* terms and conditions of the copyright. |
|
6 |
*/ |
|
7 |
|
|
8 |
#ifndef _IF_H_ |
|
9 |
#define _IF_H_ |
|
10 |
|
|
11 |
#define IF_COMPRESS 0x01 /* We want compression */ |
|
12 |
#define IF_NOCOMPRESS 0x02 /* Do not do compression */ |
|
13 |
#define IF_AUTOCOMP 0x04 /* Autodetect (default) */ |
|
14 |
#define IF_NOCIDCOMP 0x08 /* CID compression */ |
|
15 |
|
|
16 |
/* Needed for FreeBSD */ |
|
17 |
#undef if_mtu |
|
18 |
extern int if_mtu; |
|
19 |
extern int if_mru; /* MTU and MRU */ |
|
20 |
extern int if_comp; /* Flags for compression */ |
|
21 |
extern int if_maxlinkhdr; |
|
22 |
extern int if_queued; /* Number of packets queued so far */ |
|
23 |
extern int if_thresh; /* Number of packets queued before we start sending |
|
24 |
* (to prevent allocing too many mbufs) */ |
|
25 |
|
|
26 |
extern struct mbuf if_fastq; /* fast queue (for interactive data) */ |
|
27 |
extern struct mbuf if_batchq; /* queue for non-interactive data */ |
|
28 |
extern struct mbuf *next_m; |
|
29 |
|
|
30 |
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) |
|
31 |
|
|
32 |
/* Interface statistics */ |
|
33 |
struct slirp_ifstats { |
|
34 |
u_int out_pkts; /* Output packets */ |
|
35 |
u_int out_bytes; /* Output bytes */ |
|
36 |
u_int out_errpkts; /* Output Error Packets */ |
|
37 |
u_int out_errbytes; /* Output Error Bytes */ |
|
38 |
u_int in_pkts; /* Input packets */ |
|
39 |
u_int in_bytes; /* Input bytes */ |
|
40 |
u_int in_errpkts; /* Input Error Packets */ |
|
41 |
u_int in_errbytes; /* Input Error Bytes */ |
|
42 |
|
|
43 |
u_int bytes_saved; /* Number of bytes that compression "saved" */ |
|
44 |
/* ie: number of bytes that didn't need to be sent over the link |
|
45 |
* because of compression */ |
|
46 |
|
|
47 |
u_int in_mbad; /* Bad incoming packets */ |
|
48 |
}; |
|
49 |
|
|
50 |
#endif |
b/slirp/ip.h | ||
---|---|---|
1 |
/* |
|
2 |
* Copyright (c) 1982, 1986, 1993 |
|
3 |
* The Regents of the University of California. All rights reserved. |
|
4 |
* |
|
5 |
* Redistribution and use in source and binary forms, with or without |
|
6 |
* modification, are permitted provided that the following conditions |
|
7 |
* are met: |
|
8 |
* 1. Redistributions of source code must retain the above copyright |
|
9 |
* notice, this list of conditions and the following disclaimer. |
|
10 |
* 2. Redistributions in binary form must reproduce the above copyright |
|
11 |
* notice, this list of conditions and the following disclaimer in the |
|
12 |
* documentation and/or other materials provided with the distribution. |
|
13 |
* 3. All advertising materials mentioning features or use of this software |
|
14 |
* must display the following acknowledgement: |
|
15 |
* This product includes software developed by the University of |
|
16 |
* California, Berkeley and its contributors. |
|
17 |
* 4. Neither the name of the University nor the names of its contributors |
|
18 |
* may be used to endorse or promote products derived from this software |
|
19 |
* without specific prior written permission. |
|
20 |
* |
|
21 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
22 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
23 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
24 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
25 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
26 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
27 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
28 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
29 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
30 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
31 |
* SUCH DAMAGE. |
|
32 |
* |
|
33 |
* @(#)ip.h 8.1 (Berkeley) 6/10/93 |
|
34 |
* ip.h,v 1.3 1994/08/21 05:27:30 paul Exp |
|
35 |
*/ |
|
36 |
|
|
37 |
#ifndef _IP_H_ |
|
38 |
#define _IP_H_ |
|
39 |
|
|
40 |
#ifdef WORDS_BIGENDIAN |
|
41 |
# ifndef NTOHL |
|
42 |
# define NTOHL(d) |
|
43 |
# endif |
|
44 |
# ifndef NTOHS |
|
45 |
# define NTOHS(d) |
|
46 |
# endif |
|
47 |
# ifndef HTONL |
|
48 |
# define HTONL(d) |
|
49 |
# endif |
|
50 |
# ifndef HTONS |
|
51 |
# define HTONS(d) |
|
52 |
# endif |
|
53 |
#else |
|
54 |
# ifndef NTOHL |
|
55 |
# define NTOHL(d) ((d) = ntohl((d))) |
|
56 |
# endif |
|
57 |
# ifndef NTOHS |
|
58 |
# define NTOHS(d) ((d) = ntohs((u_int16_t)(d))) |
|
59 |
# endif |
|
60 |
# ifndef HTONL |
|
61 |
# define HTONL(d) ((d) = htonl((d))) |
|
62 |
# endif |
|
63 |
# ifndef HTONS |
|
64 |
# define HTONS(d) ((d) = htons((u_int16_t)(d))) |
|
65 |
# endif |
|
66 |
#endif |
|
67 |
|
|
68 |
typedef u_int32_t n_long; /* long as received from the net */ |
|
69 |
|
|
70 |
/* |
|
71 |
* Definitions for internet protocol version 4. |
|
72 |
* Per RFC 791, September 1981. |
|
73 |
*/ |
|
74 |
#define IPVERSION 4 |
|
75 |
|
|
76 |
/* |
|
77 |
* Structure of an internet header, naked of options. |
|
78 |
* |
|
79 |
* We declare ip_len and ip_off to be short, rather than u_short |
|
80 |
* pragmatically since otherwise unsigned comparisons can result |
|
81 |
* against negative integers quite easily, and fail in subtle ways. |
|
82 |
*/ |
|
83 |
struct ip { |
|
84 |
#ifdef WORDS_BIGENDIAN |
|
85 |
u_int ip_v:4, /* version */ |
|
86 |
ip_hl:4; /* header length */ |
|
87 |
#else |
|
88 |
u_int ip_hl:4, /* header length */ |
|
89 |
ip_v:4; /* version */ |
|
90 |
#endif |
|
91 |
u_int8_t ip_tos; /* type of service */ |
|
92 |
int16_t ip_len; /* total length */ |
|
93 |
u_int16_t ip_id; /* identification */ |
|
94 |
int16_t ip_off; /* fragment offset field */ |
Also available in: Unified diff