diff options
Diffstat (limited to '')
| -rw-r--r-- | c/tcp.c | 107 |
1 files changed, 0 insertions, 107 deletions
diff --git a/c/tcp.c b/c/tcp.c deleted file mode 100644 index 07eb2b1..0000000 --- a/c/tcp.c +++ /dev/null @@ -1,107 +0,0 @@ -#include "netlib.h" -/* tcp - a minimal TCP client over SLIP (milestone C). Connects to 10.0.0.1:7, - sends a line, prints the reply, closes. No retransmission: the GB<->gateway - link is lossless, and the gateway's real socket handles the lossy side. - Us = 10.0.0.2, peer = 10.0.0.1. */ - -static unsigned char pkt[256]; -static unsigned long snd_nxt, rcv_nxt; -#define LPORT 40000u -#define RPORT 7u - -/* SYN 0x02, ACK 0x10, FIN 0x01, PSH 0x08, RST 0x04 */ - -static unsigned int sum16(unsigned char *d, unsigned int len, unsigned int sum) { - unsigned int w, i = 0; - while (i + 1 < len) { w = ((unsigned int)d[i] << 8) | d[i + 1]; sum += w; if (sum < w) sum++; i += 2; } - if (len & 1) { w = (unsigned int)d[len - 1] << 8; sum += w; if (sum < w) sum++; } - return sum; -} -static void put32(unsigned char *p, unsigned long v) { - p[0] = (unsigned char)(v >> 24); p[1] = (unsigned char)(v >> 16); - p[2] = (unsigned char)(v >> 8); p[3] = (unsigned char)v; -} -static unsigned long get32(unsigned char *p) { - return ((unsigned long)p[0] << 24) | ((unsigned long)p[1] << 16) - | ((unsigned long)p[2] << 8) | p[3]; -} - -/* build+send IP+TCP with 'flags' and 'dlen' payload bytes already at pkt[40..] */ -static void tcp_send(unsigned char flags, unsigned char dlen) { - unsigned int c, psum, tcplen = 20 + dlen, total = 20 + tcplen; - pkt[0] = 0x45; pkt[1] = 0; pkt[2] = (unsigned char)(total >> 8); pkt[3] = (unsigned char)total; - pkt[4] = 0; pkt[5] = 1; pkt[6] = 0x40; pkt[7] = 0; pkt[8] = 64; pkt[9] = 6; - pkt[10] = 0; pkt[11] = 0; - pkt[12] = 10; pkt[13] = 0; pkt[14] = 0; pkt[15] = 2; - pkt[16] = 10; pkt[17] = 0; pkt[18] = 0; pkt[19] = 1; - pkt[20] = LPORT >> 8; pkt[21] = (unsigned char)LPORT; - pkt[22] = RPORT >> 8; pkt[23] = (unsigned char)RPORT; - put32(pkt + 24, snd_nxt); - put32(pkt + 28, rcv_nxt); - pkt[32] = 0x50; pkt[33] = flags; pkt[34] = 2; pkt[35] = 0; /* window 512 */ - pkt[36] = 0; pkt[37] = 0; pkt[38] = 0; pkt[39] = 0; - psum = sum16(pkt + 12, 8, 0); - c = 6; psum += c; if (psum < c) psum++; - c = tcplen; psum += c; if (psum < c) psum++; - c = ~sum16(pkt + 20, tcplen, psum); - pkt[36] = (unsigned char)(c >> 8); pkt[37] = (unsigned char)c; - c = ~sum16(pkt, 20, 0); - pkt[10] = (unsigned char)(c >> 8); pkt[11] = (unsigned char)c; - slip_send((char *)pkt, (unsigned char)total); -} - -/* receive the next TCP segment for our connection; returns TCP header offset, - sets *flags,*seq,*dlen,*doff. */ -static unsigned char tcp_recv(unsigned char *flags, unsigned long *seq, - unsigned char *dlen, unsigned char *doff) { - unsigned char len, ihl, hl; - for (;;) { - len = slip_recv((char *)pkt, 255); - if (len < 40 || (pkt[0] >> 4) != 4 || pkt[9] != 6) continue; - ihl = (pkt[0] & 0x0f) << 2; - if (((unsigned int)pkt[22] << 8 | pkt[23]) != LPORT) continue; /* not our port */ - hl = (pkt[ihl + 12] >> 4) << 2; - *flags = pkt[ihl + 13]; - *seq = get32(pkt + ihl + 4); - *doff = (unsigned char)(ihl + hl); - *dlen = (unsigned char)(len - ihl - hl); - return ihl; - } -} - -void main(void) { - unsigned char flags, dlen, doff, i; - unsigned long seq; - puts("tcp: SYN -> 10.0.0.1:7"); nl(); - snd_nxt = 1000; rcv_nxt = 0; - tcp_send(0x02, 0); /* SYN */ - snd_nxt = 1001; - - tcp_recv(&flags, &seq, &dlen, &doff); /* expect SYN|ACK */ - if (!(flags & 0x02)) { puts("tcp: no SYN-ACK"); nl(); return; } - rcv_nxt = seq + 1; - tcp_send(0x10, 0); /* ACK -> ESTABLISHED */ - - pkt[40] = 'h'; pkt[41] = 'i'; pkt[42] = ' '; pkt[43] = 'g'; pkt[44] = 'b'; - tcp_send(0x18, 5); /* PSH|ACK "hi gb" */ - snd_nxt += 5; - - for (;;) { - tcp_recv(&flags, &seq, &dlen, &doff); - if (dlen) { - puts("tcp: recv '"); - for (i = 0; i < dlen; i++) putc(pkt[doff + i]); - puts("'"); nl(); - rcv_nxt = seq + dlen; - tcp_send(0x10, 0); /* ACK the data */ - tcp_send(0x11, 0); /* FIN|ACK - start closing */ - snd_nxt += 1; - } - if (flags & 0x01) { /* their FIN */ - rcv_nxt = seq + dlen + 1; - tcp_send(0x10, 0); /* ACK it */ - puts("tcp: closed"); nl(); - return; - } - } -} |
