网络框架基础
This commit is contained in:
parent
9a851018f7
commit
8a2a8685e4
12
build.py
12
build.py
@ -71,6 +71,15 @@ def build_sysapp(): # 构建内置系统应用
|
||||
return 0
|
||||
|
||||
|
||||
def build_network(): # 构建网络系统
|
||||
print("Building network source code...")
|
||||
for file in os.listdir(cd + '\\network'):
|
||||
cmd = cd + gcc + " " + "network\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o"
|
||||
e = os.system(cmd)
|
||||
if e != 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
def linker(): # 交叉编译链接
|
||||
print("Linking object files...")
|
||||
source_file = ""
|
||||
@ -94,6 +103,9 @@ a = build_data()
|
||||
if a != 0:
|
||||
exit(-1)
|
||||
a = build_sysapp()
|
||||
if a != 0:
|
||||
exit(-1)
|
||||
a = build_network()
|
||||
if a != 0:
|
||||
exit(-1)
|
||||
a = linker()
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "../include/vdisk.h"
|
||||
#include "../include/printf.h"
|
||||
#include "../include/fifo.h"
|
||||
#include "../include/task.h"
|
||||
|
||||
int getReadyDisk();
|
||||
|
||||
@ -111,3 +113,52 @@ void Disk_Write(unsigned int lba, unsigned int number, void *buffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *drive_name[16] = {NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL};
|
||||
static struct FIFO8 drive_fifo[16];
|
||||
static unsigned char drive_buf[16][256];
|
||||
|
||||
bool SetDrive(unsigned char *name) {
|
||||
for (int i = 0; i != 16; i++) {
|
||||
if (drive_name[i] == NULL) {
|
||||
drive_name[i] = name;
|
||||
fifo8_init(&drive_fifo[i], 256, drive_buf[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int GetDriveCode(unsigned char *name) {
|
||||
for (int i = 0; i != 16; i++) {
|
||||
if (strcmp((char *)drive_name[i], (char *)name) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 16;
|
||||
}
|
||||
|
||||
bool DriveSemaphoreTake(unsigned int drive_code) {
|
||||
if (drive_code >= 16) {
|
||||
return 1;
|
||||
}
|
||||
fifo8_put(&drive_fifo[drive_code], get_current()->pid);
|
||||
// printk("FIFO: %d PUT: %d STATUS: %d\n", drive_code, Get_Tid(current_task()),
|
||||
// fifo8_status(&drive_fifo[drive_code]));
|
||||
while (drive_buf[drive_code][drive_fifo[drive_code].q] !=
|
||||
get_current()->pid) {
|
||||
// printk("Waiting....\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
void DriveSemaphoreGive(unsigned int drive_code) {
|
||||
if (drive_code >= 16) {
|
||||
return;
|
||||
}
|
||||
if (drive_buf[drive_code][drive_fifo[drive_code].q] != get_current()->pid) {
|
||||
return;
|
||||
}
|
||||
fifo8_get(&drive_fifo[drive_code]);
|
||||
}
|
||||
|
26
include/arp.h
Normal file
26
include/arp.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef CRASHPOWEROS_ARP_H
|
||||
#define CRASHPOWEROS_ARP_H
|
||||
|
||||
#define ARP_PROTOCOL 0x0806
|
||||
#define MAX_ARP_TABLE 256
|
||||
#define ARP_WAITTIME 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct ARPMessage {
|
||||
uint16_t hardwareType;
|
||||
uint16_t protocol;
|
||||
uint8_t hardwareAddressSize;
|
||||
uint8_t protocolAddressSize;
|
||||
uint16_t command;
|
||||
uint8_t src_mac[6];
|
||||
uint32_t src_ip;
|
||||
uint8_t dest_mac[6];
|
||||
uint32_t dest_ip;
|
||||
} __attribute__((packed));
|
||||
|
||||
uint64_t IPParseMAC(uint32_t dstIP);
|
||||
uint8_t *ARP_Packet(uint64_t dest_mac, uint32_t dest_ip, uint64_t src_mac,
|
||||
uint32_t src_ip, uint16_t command);
|
||||
|
||||
#endif
|
@ -7,6 +7,11 @@
|
||||
#define LONG_MAX 9223372036854775807L
|
||||
#define LONG_MIN -9223372036854775808L
|
||||
|
||||
#define swap32(x) \
|
||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||
#define swap16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
59
include/dhcp.h
Normal file
59
include/dhcp.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef CRASHPOWEROS_DHCP_H
|
||||
#define CRASHPOWEROS_DHCP_H
|
||||
|
||||
#define DHCP_CHADDR_LEN 16
|
||||
#define DHCP_SNAME_LEN 64
|
||||
#define DHCP_FILE_LEN 128
|
||||
|
||||
#define DHCP_BOOTREQUEST 1
|
||||
#define DHCP_BOOTREPLY 2
|
||||
|
||||
#define DHCP_HARDWARE_TYPE_10_EHTHERNET 1
|
||||
|
||||
#define MESSAGE_TYPE_PAD 0
|
||||
#define MESSAGE_TYPE_REQ_SUBNET_MASK 1
|
||||
#define MESSAGE_TYPE_ROUTER 3
|
||||
#define MESSAGE_TYPE_DNS 6
|
||||
#define MESSAGE_TYPE_DOMAIN_NAME 15
|
||||
#define MESSAGE_TYPE_REQ_IP 50
|
||||
#define MESSAGE_TYPE_DHCP 53
|
||||
#define MESSAGE_TYPE_PARAMETER_REQ_LIST 55
|
||||
#define MESSAGE_TYPE_END 255
|
||||
|
||||
#define DHCP_OPTION_DISCOVER 1
|
||||
#define DHCP_OPTION_OFFER 2
|
||||
#define DHCP_OPTION_REQUEST 3
|
||||
#define DHCP_OPTION_PACK 4
|
||||
|
||||
#define DHCP_SERVER_PORT 67
|
||||
#define DHCP_CLIENT_PORT 68
|
||||
|
||||
#define DHCP_MAGIC_COOKIE 0x63825363
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct DHCPMessage {
|
||||
uint8_t opcode;
|
||||
uint8_t htype;
|
||||
uint8_t hlen;
|
||||
uint8_t hops;
|
||||
uint32_t xid;
|
||||
uint16_t secs;
|
||||
uint16_t flags;
|
||||
uint32_t ciaddr;
|
||||
uint32_t yiaddr;
|
||||
uint32_t siaddr;
|
||||
uint32_t giaddr;
|
||||
uint8_t chaddr[DHCP_CHADDR_LEN];
|
||||
char bp_sname[DHCP_SNAME_LEN];
|
||||
char bp_file[DHCP_FILE_LEN];
|
||||
uint32_t magic_cookie;
|
||||
uint8_t bp_options[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
int dhcp_discovery(uint8_t *mac);
|
||||
void dhcp_handler(void *base);
|
||||
|
||||
#endif
|
69
include/dns.h
Normal file
69
include/dns.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef CRASHPOWEROS_DNS_H
|
||||
#define CRASHPOWEROS_DNS_H
|
||||
|
||||
#define DNS_Header_ID 0x2115
|
||||
|
||||
#define DNS_TYPE_A 1
|
||||
#define DNS_TYPE_NS 2
|
||||
#define DNS_TYPE_MD 3
|
||||
#define DNS_TYPE_MF 4
|
||||
#define DNS_TYPE_CNAME 5
|
||||
#define DNS_TYPE_SOA 6
|
||||
#define DNS_TYPE_MB 7
|
||||
#define DNS_TYPE_MG 8
|
||||
#define DNS_TYPE_MR 9
|
||||
#define DNS_TYPE_NULL 10
|
||||
#define DNS_TYPE_WKS 11
|
||||
#define DNS_TYPE_PTR 12
|
||||
#define DNS_TYPE_HINFO 13
|
||||
#define DNS_TYPE_MINFO 14
|
||||
#define DNS_TYPE_MX 15
|
||||
#define DNS_TYPE_TXT 16
|
||||
#define DNS_TYPE_ANY 255
|
||||
|
||||
#define DNS_CLASS_INET 1
|
||||
#define DNS_CLASS_CSNET 2
|
||||
#define DNS_CLASS_CHAOS 3
|
||||
#define DNS_CLASS_HESIOD 4
|
||||
#define DNS_CLASS_ANY 255
|
||||
|
||||
#define DNS_PORT 53
|
||||
#define DNS_SERVER_IP 0x08080808
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct DNS_Header {
|
||||
uint16_t ID;
|
||||
uint8_t RD : 1;
|
||||
uint8_t AA : 1;
|
||||
uint8_t Opcode : 4;
|
||||
uint8_t QR : 1;
|
||||
uint8_t RCODE : 4;
|
||||
uint8_t Z : 3;
|
||||
uint8_t RA : 1;
|
||||
uint8_t TC : 1;
|
||||
uint16_t QDcount;
|
||||
uint16_t ANcount;
|
||||
uint16_t NScount;
|
||||
uint16_t ARcount;
|
||||
uint8_t reserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct DNS_Question {
|
||||
uint16_t type;
|
||||
uint16_t Class;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct DNS_Answer {
|
||||
uint32_t name : 24;
|
||||
uint16_t type;
|
||||
uint16_t Class;
|
||||
uint32_t TTL;
|
||||
uint16_t RDlength;
|
||||
uint8_t reserved;
|
||||
uint8_t RData[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
void dns_handler(void *base);
|
||||
|
||||
#endif
|
19
include/etherframe.h
Normal file
19
include/etherframe.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef CRASHPOWEROS_ETHERFRAME_H
|
||||
#define CRASHPOWEROS_ETHERFRAME_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct EthernetFrame_head {
|
||||
uint8_t dest_mac[6];
|
||||
uint8_t src_mac[6];
|
||||
uint16_t type;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct EthernetFrame_tail {
|
||||
uint32_t CRC; // 这里可以填写为0,网卡会自动计算
|
||||
};
|
||||
|
||||
void ether_frame_provider_send(uint64_t dest_mac, uint16_t type, uint8_t *buffer,
|
||||
uint32_t size);
|
||||
|
||||
#endif
|
15
include/fifo.h
Normal file
15
include/fifo.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef CRASHPOWEROS_FIFO_H
|
||||
#define CRASHPOWEROS_FIFO_H
|
||||
|
||||
#define FLAGS_OVERRUN 0x0001
|
||||
|
||||
struct FIFO8 {
|
||||
unsigned char *buf;
|
||||
int p, q, size, free, flags;
|
||||
};
|
||||
|
||||
int fifo8_put(struct FIFO8* fifo, unsigned char data);
|
||||
int fifo8_get(struct FIFO8* fifo);
|
||||
void fifo8_init(struct FIFO8* fifo, int size, unsigned char* buf);
|
||||
|
||||
#endif
|
31
include/ipv4.h
Normal file
31
include/ipv4.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef CRASHPOWEROS_IPV4_H
|
||||
#define CRASHPOWEROS_IPV4_H
|
||||
|
||||
#define IP_PROTOCOL 0x0800
|
||||
#define MTU 1500
|
||||
#define IP_MF 13
|
||||
#define IP_DF 14
|
||||
#define IP_OFFSET 0
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct IPV4Message {
|
||||
uint8_t headerLength : 4;
|
||||
uint8_t version : 4;
|
||||
uint8_t tos;
|
||||
uint16_t totalLength;
|
||||
uint16_t ident;
|
||||
uint16_t flagsAndOffset;
|
||||
uint8_t timeToLive;
|
||||
uint8_t protocol;
|
||||
uint16_t checkSum;
|
||||
uint32_t srcIP;
|
||||
uint32_t dstIP;
|
||||
} __attribute__((packed));
|
||||
|
||||
void IPV4ProviderSend(uint8_t protocol, uint64_t dest_mac, uint32_t dest_ip,
|
||||
uint32_t src_ip, uint8_t *data, uint32_t size);
|
||||
uint16_t CheckSum(uint16_t *data, uint32_t size);
|
||||
uint32_t IP2UINT32_T(uint8_t *ip);
|
||||
|
||||
#endif
|
17
include/net.h
Normal file
17
include/net.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef CRASHPOWEROS_NET_H
|
||||
#define CRASHPOWEROS_NET_H
|
||||
|
||||
#include "../include/common.h"
|
||||
|
||||
typedef struct {
|
||||
bool (*find)();
|
||||
void (*init)();
|
||||
void (*Send)(unsigned char* buffer, unsigned int size);
|
||||
char card_name[50];
|
||||
int use; // 正在使用
|
||||
int flag;
|
||||
} network_card;
|
||||
|
||||
void netcard_send(unsigned char* buffer, unsigned int size);
|
||||
|
||||
#endif
|
37
include/socket.h
Normal file
37
include/socket.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef CRASHPOWEROS_SOCKET_H
|
||||
#define CRASHPOWEROS_SOCKET_H
|
||||
|
||||
#define MAX_SOCKET_NUM 256
|
||||
#define SOCKET_ALLOC -1
|
||||
#define SOCKET_FREE 0
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct Socket {
|
||||
// 函数格式
|
||||
int (*Connect)(struct Socket *socket); // TCP
|
||||
void (*Disconnect)(struct Socket *socket); // TCP
|
||||
void (*Listen)(struct Socket *socket); // TCP
|
||||
void (*Send)(struct Socket *socket, uint8_t *data, uint32_t size); // TCP/UDP
|
||||
void (*Handler)(struct Socket *socket, void *base); // TCP/UDP
|
||||
// TCP/UDP
|
||||
uint32_t remoteIP;
|
||||
uint16_t remotePort;
|
||||
uint32_t localIP;
|
||||
uint16_t localPort;
|
||||
uint8_t state;
|
||||
uint8_t protocol;
|
||||
// TCP
|
||||
uint32_t seqNum;
|
||||
uint32_t ackNum;
|
||||
uint16_t MSS;
|
||||
int flag; // 1 有包 0 没包
|
||||
int size;
|
||||
char *buf;
|
||||
} __attribute__((packed));
|
||||
|
||||
void socket_init();
|
||||
struct Socket *Socket_Find(uint32_t dstIP, uint16_t dstPort, uint32_t srcIP,
|
||||
uint16_t srcPort, uint8_t protocol);
|
||||
|
||||
#endif
|
59
include/tcp.h
Normal file
59
include/tcp.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef CRASHPOWEROS_TCP_H
|
||||
#define CRASHPOWEROS_TCP_H
|
||||
|
||||
#define TCP_PROTOCOL 6
|
||||
#define TCP_CONNECT_WAITTIME 10000
|
||||
#define MSS_Default 1460
|
||||
#define TCP_SEG_WAITTIME 100
|
||||
|
||||
#define SOCKET_TCP_CLOSED 1
|
||||
#define SOCKET_TCP_LISTEN 2
|
||||
#define SOCKET_TCP_SYN_SENT 3
|
||||
#define SOCKET_TCP_SYN_RECEIVED 4
|
||||
#define SOCKET_TCP_ESTABLISHED 5
|
||||
#define SOCKET_TCP_FIN_WAIT1 6
|
||||
#define SOCKET_TCP_FIN_WAIT2 7
|
||||
#define SOCKET_TCP_CLOSING 8
|
||||
#define SOCKET_TCP_TIME_WAIT 9
|
||||
#define SOCKET_TCP_CLOSE_WAIT 10
|
||||
#define SOCKET_TCP_LAST_ACK 11
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct TCPPesudoHeader {
|
||||
uint32_t srcIP;
|
||||
uint32_t dstIP;
|
||||
uint16_t protocol;
|
||||
uint16_t totalLength;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct TCPMessage {
|
||||
uint16_t srcPort;
|
||||
uint16_t dstPort;
|
||||
uint32_t seqNum;
|
||||
uint32_t ackNum;
|
||||
uint8_t reserved : 4;
|
||||
uint8_t headerLength : 4;
|
||||
uint8_t FIN : 1;
|
||||
uint8_t SYN : 1;
|
||||
uint8_t RST : 1;
|
||||
uint8_t PSH : 1;
|
||||
uint8_t ACK : 1;
|
||||
uint8_t URG : 1;
|
||||
uint8_t ECE : 1;
|
||||
uint8_t CWR : 1;
|
||||
uint16_t window;
|
||||
uint16_t checkSum;
|
||||
uint16_t pointer;
|
||||
uint32_t options[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
void tcp_provider_send(uint32_t dstIP, uint32_t srcIP, uint16_t dstPort,
|
||||
uint16_t srcPort, uint32_t Sequence, uint32_t ackNum,
|
||||
bool URG, bool ACK, bool PSH, bool RST, bool SYN, bool FIN,
|
||||
bool ECE, bool CWR, uint8_t *data, uint32_t size);
|
||||
void tcp_handler(void *base);
|
||||
|
||||
#endif
|
20
include/udp.h
Normal file
20
include/udp.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef CRASHPOWEROS_UDP_H
|
||||
#define CRASHPOWEROS_UDP_H
|
||||
|
||||
#define UDP_PROTOCOL 17
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct UDPMessage {
|
||||
uint16_t srcPort;
|
||||
uint16_t dstPort;
|
||||
uint16_t length;
|
||||
uint16_t checkSum;
|
||||
} __attribute__((packed));
|
||||
|
||||
uint8_t *UDP_Packet(uint16_t dest_port, uint16_t src_port, uint8_t *data, uint32_t size);
|
||||
void udp_provider_send(uint32_t destip, uint32_t srcip, uint16_t dest_port,
|
||||
uint16_t src_port, uint8_t *data, uint32_t size);
|
||||
void udp_handler(void *base);
|
||||
|
||||
#endif
|
@ -3,6 +3,8 @@
|
||||
|
||||
#define SECTORS_ONCE 8
|
||||
|
||||
#include "../include/common.h"
|
||||
|
||||
typedef struct {
|
||||
void (*Read)(char drive, unsigned char *buffer, unsigned int number,
|
||||
unsigned int lba);
|
||||
@ -42,5 +44,9 @@ int disk_Size(char drive);
|
||||
int DiskReady(char drive);
|
||||
void Disk_Write(unsigned int lba, unsigned int number, void *buffer,
|
||||
char drive);
|
||||
unsigned int GetDriveCode(unsigned char *name);
|
||||
bool SetDrive(unsigned char *name);
|
||||
void DriveSemaphoreGive(unsigned int drive_code);
|
||||
bool DriveSemaphoreTake(unsigned int drive_code);
|
||||
|
||||
#endif
|
||||
|
41
kernel/fifo.c
Normal file
41
kernel/fifo.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "../include/fifo.h"
|
||||
|
||||
void fifo8_init(struct FIFO8* fifo, int size, unsigned char* buf) {
|
||||
fifo->size = size;
|
||||
fifo->buf = buf;
|
||||
fifo->free = size; /* 缓冲区大小 */
|
||||
fifo->flags = 0;
|
||||
fifo->p = 0; /* 下一个数据写入位置 */
|
||||
fifo->q = 0; /* 下一个数据读出位置 */
|
||||
return;
|
||||
}
|
||||
|
||||
int fifo8_put(struct FIFO8* fifo, unsigned char data) {
|
||||
if (fifo->free == 0) {
|
||||
/* 没有空间了,溢出 */
|
||||
fifo->flags |= FLAGS_OVERRUN;
|
||||
return -1;
|
||||
}
|
||||
fifo->buf[fifo->p] = data;
|
||||
fifo->p++;
|
||||
if (fifo->p == fifo->size) {
|
||||
fifo->p = 0;
|
||||
}
|
||||
fifo->free--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fifo8_get(struct FIFO8* fifo) {
|
||||
int data;
|
||||
if (fifo->free == fifo->size) {
|
||||
/* 如果缓冲区为空则返回-1 */
|
||||
return -1;
|
||||
}
|
||||
data = fifo->buf[fifo->q];
|
||||
fifo->q++;
|
||||
if (fifo->q == fifo->size) {
|
||||
fifo->q = 0;
|
||||
}
|
||||
fifo->free++;
|
||||
return data;
|
||||
}
|
72
network/arp.c
Normal file
72
network/arp.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include "../include/arp.h"
|
||||
#include "../include/etherframe.h"
|
||||
#include "../include/memory.h"
|
||||
|
||||
uint8_t ARP_flags = 1;
|
||||
uint64_t ARP_mac_address[MAX_ARP_TABLE];
|
||||
uint32_t ARP_ip_address[MAX_ARP_TABLE];
|
||||
uint32_t ARP_write_pointer = 0;
|
||||
|
||||
uint8_t *ARP_Packet(uint64_t dest_mac, uint32_t dest_ip, uint64_t src_mac,
|
||||
uint32_t src_ip, uint16_t command) {
|
||||
struct ARPMessage *res =
|
||||
(struct ARPMessage *)kmalloc(sizeof(struct ARPMessage));
|
||||
res->hardwareType = 0x0100;
|
||||
res->protocol = 0x0008;
|
||||
res->hardwareAddressSize = 6;
|
||||
res->protocolAddressSize = 4;
|
||||
res->command = ((command & 0xff00) >> 8) | ((command & 0x00ff) << 8);
|
||||
res->dest_mac[0] = (uint8_t)dest_mac;
|
||||
res->dest_mac[1] = (uint8_t)(dest_mac >> 8);
|
||||
res->dest_mac[2] = (uint8_t)(dest_mac >> 16);
|
||||
res->dest_mac[3] = (uint8_t)(dest_mac >> 24);
|
||||
res->dest_mac[4] = (uint8_t)(dest_mac >> 32);
|
||||
res->dest_mac[5] = (uint8_t)(dest_mac >> 40);
|
||||
res->dest_ip = ((dest_ip << 24) & 0xff000000) |
|
||||
((dest_ip << 8) & 0x00ff0000) | ((dest_ip >> 8) & 0xff00) |
|
||||
((dest_ip >> 24) & 0xff);
|
||||
res->src_mac[0] = (uint8_t)src_mac;
|
||||
res->src_mac[1] = (uint8_t)(src_mac >> 8);
|
||||
res->src_mac[2] = (uint8_t)(src_mac >> 16);
|
||||
res->src_mac[3] = (uint8_t)(src_mac >> 24);
|
||||
res->src_mac[4] = (uint8_t)(src_mac >> 32);
|
||||
res->src_mac[5] = (uint8_t)(src_mac >> 40);
|
||||
res->src_ip = ((src_ip << 24) & 0xff000000) | ((src_ip << 8) & 0x00ff0000) |
|
||||
((src_ip >> 8) & 0xff00) | ((src_ip >> 24) & 0xff);
|
||||
return (uint8_t *)res;
|
||||
}
|
||||
|
||||
uint64_t IPParseMAC(uint32_t dstIP) {
|
||||
extern uint8_t ARP_flags;
|
||||
extern uint32_t ARP_write_pointer;
|
||||
extern uint64_t ARP_mac_address[MAX_ARP_TABLE];
|
||||
extern uint32_t ARP_ip_address[MAX_ARP_TABLE];
|
||||
extern uint32_t ip;
|
||||
extern uint8_t mac0;
|
||||
extern uint32_t gateway;
|
||||
//extern struct TIMERCTL timerctl;
|
||||
if ((dstIP & 0xffffff00) != (ip & 0xffffff00)) {
|
||||
dstIP = gateway;
|
||||
}
|
||||
for (int i = 0; i != ARP_write_pointer; i++) {
|
||||
if (dstIP == ARP_ip_address[i]) {
|
||||
return ARP_mac_address[i];
|
||||
}
|
||||
}
|
||||
ARP_flags = 1;
|
||||
//printk("send\n");
|
||||
ether_frame_provider_send(
|
||||
0xffffffffffff, 0x0806,
|
||||
ARP_Packet(0xffffffffffff, dstIP, *(uint64_t *)&mac0, ip, 1),
|
||||
sizeof(struct ARPMessage));
|
||||
//printk("ok\n");
|
||||
/*
|
||||
uint32_t time = timerctl.count;
|
||||
while (ARP_flags) {
|
||||
if (timerctl.count - time > ARP_WAITTIME) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return ARP_mac_address[ARP_write_pointer - 1];
|
||||
}
|
110
network/dhcp.c
Normal file
110
network/dhcp.c
Normal file
@ -0,0 +1,110 @@
|
||||
#include "../include/dhcp.h"
|
||||
#include "../include/memory.h"
|
||||
#include "../include/common.h"
|
||||
#include "../include/udp.h"
|
||||
#include "../include/ipv4.h"
|
||||
#include "../include/etherframe.h"
|
||||
|
||||
uint32_t gateway, submask, dns, ip, dhcp_ip;
|
||||
|
||||
static int fill_dhcp_option(uint8_t *packet, uint8_t code, uint8_t *data,
|
||||
uint8_t len) {
|
||||
packet[0] = code;
|
||||
packet[1] = len;
|
||||
memcpy(&packet[2], data, len);
|
||||
|
||||
return len + (sizeof(uint8_t) * 2);
|
||||
}
|
||||
|
||||
static int fill_dhcp_discovery_options(struct DHCPMessage *dhcp) {
|
||||
int len = 0;
|
||||
uint32_t req_ip;
|
||||
uint8_t parameter_req_list[] = {MESSAGE_TYPE_REQ_SUBNET_MASK,
|
||||
MESSAGE_TYPE_ROUTER, MESSAGE_TYPE_DNS,
|
||||
MESSAGE_TYPE_DOMAIN_NAME};
|
||||
uint8_t option;
|
||||
|
||||
option = DHCP_OPTION_DISCOVER;
|
||||
len += fill_dhcp_option(&dhcp->bp_options[len], MESSAGE_TYPE_DHCP, &option,
|
||||
sizeof(option));
|
||||
req_ip = swap32(0xffffffff);
|
||||
len += fill_dhcp_option(&dhcp->bp_options[len], MESSAGE_TYPE_REQ_IP,
|
||||
(uint8_t *)&req_ip, sizeof(req_ip));
|
||||
len += fill_dhcp_option(
|
||||
&dhcp->bp_options[len], MESSAGE_TYPE_PARAMETER_REQ_LIST,
|
||||
(uint8_t *)¶meter_req_list, sizeof(parameter_req_list));
|
||||
option = 0;
|
||||
len += fill_dhcp_option(&dhcp->bp_options[len], MESSAGE_TYPE_END, &option,
|
||||
sizeof(option));
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void dhcp_output(struct DHCPMessage *dhcp, uint8_t *mac, int *len) {
|
||||
*len += sizeof(struct DHCPMessage);
|
||||
memset(dhcp, 0, sizeof(struct DHCPMessage));
|
||||
|
||||
dhcp->opcode = DHCP_BOOTREQUEST;
|
||||
dhcp->htype = DHCP_HARDWARE_TYPE_10_EHTHERNET;
|
||||
dhcp->hlen = 6;
|
||||
memcpy(dhcp->chaddr, mac, DHCP_CHADDR_LEN);
|
||||
|
||||
dhcp->magic_cookie = swap32(DHCP_MAGIC_COOKIE);
|
||||
}
|
||||
|
||||
int dhcp_discovery(uint8_t *mac) {
|
||||
int len = 0;
|
||||
struct DHCPMessage *dhcp =
|
||||
(struct DHCPMessage *)kmalloc(sizeof(struct DHCPMessage));
|
||||
|
||||
len = fill_dhcp_discovery_options(dhcp);
|
||||
dhcp_output(dhcp, mac, &len);
|
||||
udp_provider_send(0xffffffff, 0x0, DHCP_SERVER_PORT, DHCP_CLIENT_PORT,
|
||||
(uint8_t *)dhcp, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dhcp_handler(void *base) {
|
||||
struct IPV4Message *ipv4 =
|
||||
(struct IPV4Message *)(base + sizeof(struct EthernetFrame_head));
|
||||
struct UDPMessage *udp =
|
||||
(struct UDPMessage *)(base + sizeof(struct EthernetFrame_head) +
|
||||
sizeof(struct IPV4Message));
|
||||
struct DHCPMessage *dhcp =
|
||||
(struct DHCPMessage *)(base + sizeof(struct EthernetFrame_head) +
|
||||
sizeof(struct IPV4Message) +
|
||||
sizeof(struct UDPMessage));
|
||||
if (dhcp->bp_options[0] == 53 && dhcp->bp_options[1] == 1 &&
|
||||
dhcp->bp_options[2] == DHCP_OPTION_OFFER) {
|
||||
// printk("DHCP Offer\n");
|
||||
ip = dhcp->yiaddr;
|
||||
uint8_t nip1 = ip;
|
||||
uint8_t nip2 = ip >> 8;
|
||||
uint8_t nip3 = ip >> 16;
|
||||
uint8_t nip4 = ip >> 24;
|
||||
// printk("DHCP: %d.%d.%d.%d\n", (uint8_t)(ipv4->srcIP),
|
||||
// (uint8_t)(ipv4->srcIP >> 8), (uint8_t)(ipv4->srcIP >> 16),
|
||||
// (uint8_t)(ipv4->srcIP >> 24));
|
||||
dhcp_ip = swap32(ipv4->srcIP);
|
||||
//printk("IP: %d.%d.%d.%d\n", nip1, nip2, nip3, nip4);
|
||||
ip = swap32(ip);
|
||||
|
||||
unsigned char *options = &dhcp->bp_options[0];
|
||||
while (options[0] != 0xff) {
|
||||
if (options[0] == MESSAGE_TYPE_DNS) {
|
||||
// printk("DNS: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
// options[5]);
|
||||
dns = swap32(*(uint32_t *)&options[2]);
|
||||
} else if (options[0] == MESSAGE_TYPE_REQ_SUBNET_MASK) {
|
||||
// printk("Subnet Mask: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
// options[5]);
|
||||
submask = swap32(*(uint32_t *)&options[2]);
|
||||
} else if (options[0] == MESSAGE_TYPE_ROUTER) {
|
||||
// printk("Gateway: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
// options[5]);
|
||||
gateway = swap32(*(uint32_t *)&options[2]);
|
||||
}
|
||||
options += options[1] + 2;
|
||||
}
|
||||
}
|
||||
}
|
20
network/dns.c
Normal file
20
network/dns.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "../include/dns.h"
|
||||
#include "../include/common.h"
|
||||
#include "../include/udp.h"
|
||||
#include "../include/ipv4.h"
|
||||
#include "../include/etherframe.h"
|
||||
|
||||
uint32_t dns_parse_ip_result = 0;
|
||||
|
||||
void dns_handler(void *base) {
|
||||
struct DNS_Header *dns_header =
|
||||
(struct DNS_Header *)(base + sizeof(struct EthernetFrame_head) +
|
||||
sizeof(struct IPV4Message) +
|
||||
sizeof(struct UDPMessage));
|
||||
if (swap16(dns_header->ID) == DNS_Header_ID) {
|
||||
uint8_t *p = (uint8_t *)(dns_header) + sizeof(struct DNS_Header);
|
||||
p += strlen(p) + sizeof(struct DNS_Question) - 1;
|
||||
struct DNS_Answer *dns_answer = (struct DNS_Answer *)p;
|
||||
dns_parse_ip_result = swap32(*(uint32_t *)&dns_answer->RData[0]);
|
||||
}
|
||||
}
|
37
network/etherframe.c
Normal file
37
network/etherframe.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "../include/etherframe.h"
|
||||
#include "../include/memory.h"
|
||||
#include "../include/net.h"
|
||||
|
||||
extern uint8_t mac0, mac1, mac2, mac3, mac4, mac5;
|
||||
// 以太网帧
|
||||
void ether_frame_provider_send(uint64_t dest_mac, uint16_t type, uint8_t *buffer,
|
||||
uint32_t size) {
|
||||
uint8_t *buffer2 =
|
||||
(uint8_t *)kmalloc(sizeof(struct EthernetFrame_head) + size +
|
||||
sizeof(struct EthernetFrame_tail));
|
||||
struct EthernetFrame_head *header = (struct EthernetFrame_head *)buffer2;
|
||||
struct EthernetFrame_tail *tailer =
|
||||
(struct EthernetFrame_tail *)(buffer2 +
|
||||
sizeof(struct EthernetFrame_head) + size);
|
||||
header->dest_mac[0] = (uint8_t)dest_mac;
|
||||
header->dest_mac[1] = (uint8_t)(dest_mac >> 8);
|
||||
header->dest_mac[2] = (uint8_t)(dest_mac >> 16);
|
||||
header->dest_mac[3] = (uint8_t)(dest_mac >> 24);
|
||||
header->dest_mac[4] = (uint8_t)(dest_mac >> 32);
|
||||
header->dest_mac[5] = (uint8_t)(dest_mac >> 40);
|
||||
header->src_mac[0] = mac0;
|
||||
header->src_mac[1] = mac1;
|
||||
header->src_mac[2] = mac2;
|
||||
header->src_mac[3] = mac3;
|
||||
header->src_mac[4] = mac4;
|
||||
header->src_mac[5] = mac5;
|
||||
header->type = (type << 8) | ((type & 0xff00) >> 8);
|
||||
tailer->CRC = 0;
|
||||
uint8_t *src = buffer;
|
||||
uint8_t *dst = buffer2 + sizeof(struct EthernetFrame_head);
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
dst[i] = src[i];
|
||||
netcard_send(buffer2, sizeof(struct EthernetFrame_head) + size +
|
||||
sizeof(struct EthernetFrame_tail));
|
||||
kfree(buffer2);
|
||||
}
|
110
network/ipv4.c
Normal file
110
network/ipv4.c
Normal file
@ -0,0 +1,110 @@
|
||||
#include "../include/ipv4.h"
|
||||
#include "../include/memory.h"
|
||||
#include "../include/common.h"
|
||||
|
||||
static uint16_t ident = 0;
|
||||
|
||||
void IPV4ProviderSend(uint8_t protocol, uint64_t dest_mac, uint32_t dest_ip,
|
||||
uint32_t src_ip, uint8_t *data, uint32_t size) {
|
||||
struct IPV4Message *res =
|
||||
(struct IPV4Message *)kmalloc(sizeof(struct IPV4Message) + size);
|
||||
uint8_t *dat = (uint8_t *)res;
|
||||
memcpy(dat + sizeof(struct IPV4Message), data, size);
|
||||
res->version = 4;
|
||||
res->headerLength = sizeof(struct IPV4Message) / 4;
|
||||
res->tos = 0;
|
||||
res->ident = ident;
|
||||
res->timeToLive = 64;
|
||||
res->protocol = protocol;
|
||||
res->dstIP = ((dest_ip << 24) & 0xff000000) | ((dest_ip << 8) & 0x00ff0000) |
|
||||
((dest_ip >> 8) & 0xff00) | ((dest_ip >> 24) & 0xff);
|
||||
res->srcIP = ((src_ip << 24) & 0xff000000) | ((src_ip << 8) & 0x00ff0000) |
|
||||
((src_ip >> 8) & 0xff00) | ((src_ip >> 24) & 0xff);
|
||||
if (sizeof(struct IPV4Message) + size <= MTU) {
|
||||
res->totalLength = swap16(sizeof(struct IPV4Message) + size);
|
||||
res->flagsAndOffset = 0;
|
||||
res->checkSum = 0;
|
||||
res->checkSum = CheckSum((uint16_t *)dat, sizeof(struct IPV4Message));
|
||||
ether_frame_provider_send(dest_mac, 0x0800, dat,
|
||||
sizeof(struct IPV4Message) + size);
|
||||
} else {
|
||||
int offset = 0;
|
||||
uint8_t *dat1 = (uint8_t *)kmalloc(MTU);
|
||||
for (int i = 0; i * (MTU - sizeof(struct IPV4Message)) <= size; i++) {
|
||||
if (i * (MTU - sizeof(struct IPV4Message)) >=
|
||||
size - (MTU - sizeof(struct IPV4Message))) {
|
||||
res->totalLength =
|
||||
swap16(size - i * (MTU - sizeof(struct IPV4Message)) +
|
||||
sizeof(struct IPV4Message));
|
||||
res->flagsAndOffset = offset << IP_OFFSET;
|
||||
res->flagsAndOffset = swap16(res->flagsAndOffset);
|
||||
res->checkSum = 0;
|
||||
res->checkSum = CheckSum((uint16_t *)dat, sizeof(struct IPV4Message));
|
||||
memcpy((void *)dat1, (void *)res, sizeof(struct IPV4Message));
|
||||
memcpy((void *)(dat1 + sizeof(struct IPV4Message)),
|
||||
(void *)(data + i * (MTU - sizeof(struct IPV4Message))),
|
||||
size - i * (MTU - sizeof(struct IPV4Message)));
|
||||
// printk("ip:%08x,%08x
|
||||
// size:%d\nMF:0\noffset:%d\n",swap32(res->srcIP),swap32(res->dstIP),swap16(res->totalLength),(swap16(res->flagsAndOffset)
|
||||
// >> 3));
|
||||
ether_frame_provider_send(dest_mac, 0x0800, dat1,
|
||||
size - i * (MTU - sizeof(struct IPV4Message)) +
|
||||
sizeof(struct IPV4Message));
|
||||
} else {
|
||||
res->totalLength = swap16(MTU);
|
||||
res->flagsAndOffset = (offset << IP_OFFSET) | (1 << IP_MF);
|
||||
res->flagsAndOffset = swap16(res->flagsAndOffset);
|
||||
res->checkSum = 0;
|
||||
res->checkSum = CheckSum((uint16_t *)dat, sizeof(struct IPV4Message));
|
||||
memcpy((void *)dat1, (void *)res, sizeof(struct IPV4Message));
|
||||
memcpy((void *)(dat1 + sizeof(struct IPV4Message)),
|
||||
(void *)(data + i * (MTU - sizeof(struct IPV4Message))),
|
||||
MTU - sizeof(struct IPV4Message));
|
||||
// printk("ip:%08x,%08x
|
||||
// size:%d\nMF:1\noffset:%d\n",swap32(res->srcIP),swap32(res->dstIP),swap16(res->totalLength),(swap16(res->flagsAndOffset)
|
||||
// >> 3));
|
||||
ether_frame_provider_send(dest_mac, 0x0800, dat1, MTU);
|
||||
}
|
||||
offset += (MTU - sizeof(struct IPV4Message)) / 8;
|
||||
}
|
||||
kfree((void *)dat1);
|
||||
}
|
||||
|
||||
kfree(dat);
|
||||
ident++;
|
||||
return;
|
||||
}
|
||||
uint16_t CheckSum(uint16_t *data, uint32_t size) {
|
||||
uint32_t tmp = 0;
|
||||
for (int i = 0; i < size / 2; i++) {
|
||||
tmp += ((data[i] & 0xff00) >> 8) | ((data[i] & 0x00ff) << 8);
|
||||
}
|
||||
if (size % 2)
|
||||
tmp += ((uint16_t)((char *)data)[size - 1]) << 8;
|
||||
while (tmp & 0xffff0000)
|
||||
tmp = (tmp & 0xffff) + (tmp >> 16);
|
||||
return ((~tmp & 0xff00) >> 8) | ((~tmp & 0x00ff) << 8);
|
||||
}
|
||||
uint32_t IP2UINT32_T(uint8_t *ip) {
|
||||
uint8_t ip0, ip1, ip2, ip3;
|
||||
ip0 = strtol(ip, '.', 10);
|
||||
uint8_t t = ip0;
|
||||
while (t >= 10) {
|
||||
t /= 10;
|
||||
ip++;
|
||||
}
|
||||
ip1 = strtol(ip + 2, '.', 10);
|
||||
t = ip1;
|
||||
while (t >= 10) {
|
||||
t /= 10;
|
||||
ip++;
|
||||
}
|
||||
ip2 = strtol(ip + 4, '.', 10);
|
||||
t = ip2;
|
||||
while (t >= 10) {
|
||||
t /= 10;
|
||||
ip++;
|
||||
}
|
||||
ip3 = strtol(ip + 6, NULL, 10);
|
||||
return (uint32_t)((ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3);
|
||||
}
|
23
network/net.c
Normal file
23
network/net.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "../include/net.h"
|
||||
#include "../include/vdisk.h"
|
||||
#include "../include/etherframe.h"
|
||||
|
||||
network_card network_card_CTL[25];
|
||||
static uint8_t* IP_Packet_Base[16] = {NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL};
|
||||
|
||||
void netcard_send(unsigned char* buffer, unsigned int size) {
|
||||
for (int i = 0; i < 25; i++) {
|
||||
if (network_card_CTL[i].use) {
|
||||
if (DriveSemaphoreTake(GetDriveCode("NETCARD_DRIVE"))) {
|
||||
// printk("Send....%s %d
|
||||
// %d\n",network_card_CTL[i].card_name,network_card_CTL[i].use,i);
|
||||
network_card_CTL[i].Send(buffer, size);
|
||||
DriveSemaphoreGive(GetDriveCode("NETCARD_DRIVE"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ uint8_t bus = 255, dev = 255, func = 255;
|
||||
|
||||
extern unsigned int PCI_ADDR_BASE;
|
||||
extern idt_ptr_t idt_ptr;
|
||||
extern uint32_t gateway, submask, dns, ip, dhcp_ip;
|
||||
|
||||
static int io_base = 0;
|
||||
static uint8_t sendBufferDescMemory[2048 + 15];
|
||||
static uint8_t sendBuffers[8][2048 + 15];
|
||||
@ -66,31 +68,23 @@ void Activate() {
|
||||
}
|
||||
|
||||
int pcnet_find_card() {
|
||||
//printk("pcnet_find:");
|
||||
PCI_GET_DEVICE(CARD_VENDOR_ID, CARD_DEVICE_ID, &bus, &dev, &func);
|
||||
if (bus == 255) {
|
||||
//printk("false\n");
|
||||
return 0;
|
||||
}
|
||||
//printk("true");
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
|
||||
static void init_Card_all() {
|
||||
currentSendBuffer = 0;
|
||||
currentRecvBuffer = 0;
|
||||
|
||||
// 获取MAC地址并保存
|
||||
mac0 = io_in8(io_base + APROM0);
|
||||
mac1 = io_in8(io_base + APROM1);
|
||||
mac2 = io_in8(io_base + APROM2);
|
||||
mac3 = io_in8(io_base + APROM3);
|
||||
mac4 = io_in8(io_base + APROM4);
|
||||
mac5 = io_in8(io_base + APROM5);
|
||||
// printk("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac0, mac1, mac2,
|
||||
// mac3,
|
||||
// mac4, mac5);
|
||||
// 这里约等于 into_16bitsRW();
|
||||
reset_card();
|
||||
clock_sleep(1);
|
||||
|
||||
@ -99,9 +93,6 @@ static void init_Card_all() {
|
||||
io_out16(io_base + RAP16, CSR0);
|
||||
io_out16(io_base + RDP16, 0x0004); // 暂时停止所有传输(用于初始化PCNET网卡
|
||||
|
||||
// initBlock传输初始化(CSR1=IB地址低16位,CSR2=IB地址高16位)
|
||||
// &
|
||||
// Send/Recv环形缓冲区的初始化
|
||||
initBlock.mode = 0;
|
||||
initBlock.reserved1numSendBuffers =
|
||||
(0 << 4) | 3; // 高4位是reserved1 低4位是numSendBuffers
|
||||
@ -165,7 +156,7 @@ static void init_Card_all() {
|
||||
// "来自Powerint DOS 386的消息:我是周志昊!!!", strlen("来自Powerint DOS
|
||||
// 386的消息:我是周志昊!!!"));
|
||||
}
|
||||
*/
|
||||
|
||||
void init_pcnet_card() {
|
||||
printf("[\035kernel\036]: Loading pcnet driver.\n");
|
||||
// 允许PCNET网卡产生中断
|
||||
@ -177,7 +168,7 @@ void init_pcnet_card() {
|
||||
conf |= 0x7; // 设置第0~2位(允许PCNET网卡产生中断
|
||||
pci_write_command_status(bus, dev, func, conf);
|
||||
io_base = pci_get_port_base(bus, dev, func);
|
||||
//init_Card_all();
|
||||
init_Card_all();
|
||||
}
|
||||
|
||||
void PCNET_IRQ(registers_t *reg) {
|
44
network/socket.c
Normal file
44
network/socket.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include "../include/socket.h"
|
||||
#include "../include/udp.h"
|
||||
#include "../include/tcp.h"
|
||||
|
||||
static struct Socket sockets[MAX_SOCKET_NUM];
|
||||
|
||||
static void socket_udp_send(struct Socket *socket, uint8_t *data,
|
||||
uint32_t size) {
|
||||
udp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, data, size);
|
||||
}
|
||||
|
||||
static void socket_tcp_send(struct Socket *socket, uint8_t *data,
|
||||
uint32_t size) {
|
||||
while(socket->state != SOCKET_TCP_ESTABLISHED);
|
||||
uint32_t s = size;
|
||||
tcp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, socket->seqNum, socket->ackNum, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, data, s);
|
||||
socket->seqNum += s;
|
||||
//io_delay();
|
||||
}
|
||||
|
||||
void socket_init() {
|
||||
for (int i = 0; i < MAX_SOCKET_NUM; i++) {
|
||||
sockets->state = SOCKET_FREE;
|
||||
}
|
||||
}
|
||||
|
||||
struct Socket *Socket_Find(uint32_t dstIP, uint16_t dstPort, uint32_t srcIP,
|
||||
uint16_t srcPort, uint8_t protocol) {
|
||||
for (int i = 0; i != MAX_SOCKET_NUM; i++) {
|
||||
if (srcIP == sockets[i].localIP && dstIP == sockets[i].remoteIP &&
|
||||
srcPort == sockets[i].localPort && dstPort == sockets[i].remotePort &&
|
||||
protocol == sockets[i].protocol && sockets[i].state != SOCKET_FREE) {
|
||||
return (struct Socket *)&sockets[i];
|
||||
} else if (srcIP == sockets[i].localIP && srcPort == sockets[i].localPort &&
|
||||
protocol == sockets[i].protocol &&
|
||||
sockets[i].state == SOCKET_TCP_LISTEN) {
|
||||
return (struct Socket *)&sockets[i];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
167
network/tcp.c
Normal file
167
network/tcp.c
Normal file
@ -0,0 +1,167 @@
|
||||
#include "../include/tcp.h"
|
||||
#include "../include/memory.h"
|
||||
#include "../include/ipv4.h"
|
||||
#include "../include/dhcp.h"
|
||||
#include "../include/socket.h"
|
||||
#include "../include/printf.h"
|
||||
#include "../include/etherframe.h"
|
||||
|
||||
static uint16_t ident = 0;
|
||||
|
||||
void tcp_provider_send(uint32_t dstIP, uint32_t srcIP, uint16_t dstPort,
|
||||
uint16_t srcPort, uint32_t Sequence, uint32_t ackNum,
|
||||
bool URG, bool ACK, bool PSH, bool RST, bool SYN, bool FIN,
|
||||
bool ECE, bool CWR, uint8_t *data, uint32_t size) {
|
||||
uint32_t s =
|
||||
SYN ? (sizeof(struct TCPPesudoHeader) + sizeof(struct TCPMessage) + size +
|
||||
4)
|
||||
: (sizeof(struct TCPPesudoHeader) + sizeof(struct TCPMessage) + size);
|
||||
uint8_t *dat = (uint8_t *)kmalloc(s);
|
||||
struct TCPPesudoHeader *phdr = (struct TCPPesudoHeader *)dat;
|
||||
struct TCPMessage *tcp =
|
||||
(struct TCPMessage *)(dat + sizeof(struct TCPPesudoHeader));
|
||||
memcpy((void *)(tcp) + (SYN ? (sizeof(struct TCPMessage) + 4)
|
||||
: sizeof(struct TCPMessage)),
|
||||
(void *)data, size);
|
||||
phdr->dstIP = swap32(dstIP);
|
||||
phdr->srcIP = swap32(srcIP);
|
||||
phdr->protocol = 0x0600;
|
||||
phdr->totalLength = swap16(sizeof(struct TCPMessage) + size);
|
||||
tcp->dstPort = swap16(dstPort);
|
||||
tcp->srcPort = swap16(srcPort);
|
||||
tcp->seqNum = swap32(Sequence);
|
||||
tcp->ackNum = swap32(ackNum);
|
||||
tcp->headerLength = sizeof(struct TCPMessage) / 4;
|
||||
tcp->reserved = 0;
|
||||
tcp->URG = URG;
|
||||
tcp->ACK = ACK;
|
||||
tcp->PSH = PSH;
|
||||
tcp->RST = RST;
|
||||
tcp->SYN = SYN;
|
||||
tcp->FIN = FIN;
|
||||
tcp->ECE = ECE;
|
||||
tcp->CWR = CWR;
|
||||
tcp->window = 0xffff;
|
||||
tcp->pointer = 0;
|
||||
if (SYN) {
|
||||
tcp->options[0] = 0xb4050402;
|
||||
phdr->totalLength = swap16(swap16(phdr->totalLength) + 4);
|
||||
tcp->headerLength += 1;
|
||||
}
|
||||
tcp->checkSum = 0;
|
||||
tcp->checkSum = CheckSum((uint16_t *)dat, s);
|
||||
IPV4ProviderSend(6, IPParseMAC(dstIP), dstIP, srcIP, (uint8_t *)tcp,
|
||||
s - sizeof(struct TCPPesudoHeader));
|
||||
kfree((void *)dat);
|
||||
return;
|
||||
}
|
||||
|
||||
void tcp_handler(void *base) {
|
||||
struct IPV4Message *ipv4 =
|
||||
(struct IPV4Message *)(base + sizeof(struct EthernetFrame_head));
|
||||
struct TCPMessage *tcp =
|
||||
(struct TCPMessage *)(base + sizeof(struct EthernetFrame_head) +
|
||||
sizeof(struct IPV4Message));
|
||||
struct Socket *socket =
|
||||
Socket_Find(swap32(ipv4->srcIP), swap16(tcp->srcPort),
|
||||
swap32(ipv4->dstIP), swap16(tcp->dstPort), TCP_PROTOCOL);
|
||||
if (socket == -1) {
|
||||
// printk("Not found %08x %d %08x %d\n",swap32(ipv4->srcIP),
|
||||
// swap16(tcp->srcPort), swap32(ipv4->dstIP), swap16(tcp->dstPort));
|
||||
return;
|
||||
}
|
||||
uint8_t flags = (tcp->ACK << 4) | (tcp->PSH << 3) | (tcp->SYN << 1) |
|
||||
tcp->FIN; // 只看ACK,PSH,SYN,FIN四个flags
|
||||
if (tcp->RST) {
|
||||
socket->state = SOCKET_TCP_CLOSED;
|
||||
}
|
||||
if (socket->state != SOCKET_TCP_CLOSED) {
|
||||
switch (flags) {
|
||||
case 0x12: // 00010010 ACK | SYN
|
||||
if (socket->state == SOCKET_TCP_SYN_SENT) {
|
||||
socket->state = SOCKET_TCP_ESTABLISHED;
|
||||
socket->ackNum = swap32(tcp->seqNum) + 1;
|
||||
if ((uint16_t)tcp->options == 0x0402) {
|
||||
uint16_t MSS_ = swap32(tcp->options[0]) & 0xffff;
|
||||
socket->MSS = (MSS_Default >= MSS_) ? MSS_ : MSS_Default;
|
||||
}
|
||||
tcp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, socket->seqNum, socket->ackNum, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 0x02: // 00000010 SYN
|
||||
if (socket->state == SOCKET_TCP_LISTEN) {
|
||||
socket->state = SOCKET_TCP_SYN_RECEIVED;
|
||||
socket->remoteIP = swap32(ipv4->srcIP);
|
||||
socket->remotePort = swap16(tcp->srcPort);
|
||||
socket->ackNum = swap32(tcp->seqNum) + 1;
|
||||
socket->seqNum = 0;
|
||||
if ((uint16_t)tcp->options == 0x0402) {
|
||||
uint16_t MSS_ = swap32(tcp->options[0]) & 0xffff;
|
||||
socket->MSS = (MSS_Default >= MSS_) ? MSS_ : MSS_Default;
|
||||
}
|
||||
tcp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, socket->seqNum, socket->ackNum, 0, 1,
|
||||
0, 0, 1, 0, 0, 0, 0, 0);
|
||||
socket->seqNum++;
|
||||
}
|
||||
break;
|
||||
case 0x10: // 00010000 ACK
|
||||
if (socket->state == SOCKET_TCP_SYN_RECEIVED) {
|
||||
socket->state = SOCKET_TCP_ESTABLISHED;
|
||||
} else if (socket->state == SOCKET_TCP_FIN_WAIT1) {
|
||||
socket->state = SOCKET_TCP_FIN_WAIT2;
|
||||
} else if (socket->state == SOCKET_TCP_CLOSE_WAIT) {
|
||||
socket->state = SOCKET_TCP_CLOSED;
|
||||
}
|
||||
if (tcp->ACK && !tcp->CWR && !tcp->ECE && !tcp->PSH &&
|
||||
!tcp->URG) { // Only ACK=1
|
||||
goto _default;
|
||||
}
|
||||
case 0x01: // 00000001 FIN
|
||||
case 0x11: // 00010001 ACK | FIN
|
||||
if (socket->state == SOCKET_TCP_ESTABLISHED) {
|
||||
socket->state = SOCKET_TCP_CLOSE_WAIT;
|
||||
socket->ackNum++;
|
||||
tcp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, socket->seqNum, socket->ackNum, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0);
|
||||
tcp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, socket->seqNum, socket->ackNum, 0, 1,
|
||||
0, 0, 0, 1, 0, 0, 0, 0);
|
||||
} else if (socket->state == SOCKET_TCP_FIN_WAIT1 ||
|
||||
socket->state == SOCKET_TCP_FIN_WAIT2) {
|
||||
socket->state = SOCKET_TCP_CLOSED;
|
||||
socket->ackNum++;
|
||||
tcp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, socket->seqNum, socket->ackNum, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0);
|
||||
} else if (socket->state == SOCKET_TCP_CLOSE_WAIT) {
|
||||
socket->state = SOCKET_TCP_CLOSED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_default:
|
||||
// TCP 传输
|
||||
if ((swap16(ipv4->totalLength) - sizeof(struct IPV4Message) -
|
||||
(tcp->headerLength * 4)) == socket->MSS) {
|
||||
printf("TCP Segment.\n");
|
||||
break;
|
||||
}
|
||||
if (socket->ackNum == swap32(tcp->seqNum) &&
|
||||
swap16(ipv4->totalLength) !=
|
||||
(sizeof(struct IPV4Message) + (tcp->headerLength * 4))) {
|
||||
if (socket->Handler != NULL) {
|
||||
socket->Handler(socket, base);
|
||||
}
|
||||
socket->ackNum += swap16(ipv4->totalLength) -
|
||||
sizeof(struct IPV4Message) - (tcp->headerLength * 4);
|
||||
}
|
||||
tcp_provider_send(socket->remoteIP, socket->localIP, socket->remotePort,
|
||||
socket->localPort, socket->seqNum, socket->ackNum, 0, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
60
network/udp.c
Normal file
60
network/udp.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "../include/udp.h"
|
||||
#include "../include/ipv4.h"
|
||||
#include "../include/memory.h"
|
||||
#include "../include/common.h"
|
||||
#include "../include/dhcp.h"
|
||||
#include "../include/socket.h"
|
||||
#include "../include/dns.h"
|
||||
#include "../include/etherframe.h"
|
||||
|
||||
uint8_t *UDP_Packet(uint16_t dest_port, uint16_t src_port, uint8_t *data, uint32_t size) {
|
||||
struct UDPMessage *res =
|
||||
(struct UDPMessage *)kmalloc(size + sizeof(struct UDPMessage));
|
||||
uint8_t *dat = (uint8_t *)res;
|
||||
memcpy(dat + sizeof(struct UDPMessage), data, size);
|
||||
res->srcPort = ((src_port & 0xff00) >> 8) | ((src_port & 0x00ff) << 8);
|
||||
res->dstPort = ((dest_port & 0xff00) >> 8) | ((dest_port & 0x00ff) << 8);
|
||||
res->length = size + sizeof(struct UDPMessage);
|
||||
res->length = ((res->length & 0xff00) >> 8) | ((res->length & 0x00ff) << 8);
|
||||
res->checkSum = 0;
|
||||
return (uint8_t *)res;
|
||||
}
|
||||
|
||||
void udp_provider_send(uint32_t destip, uint32_t srcip, uint16_t dest_port,
|
||||
uint16_t src_port, uint8_t *data, uint32_t size) {
|
||||
if (destip == 0xffffffff) {
|
||||
IPV4ProviderSend(17, 0xffffffffffff, destip, srcip,
|
||||
UDP_Packet(dest_port, src_port, data, size),
|
||||
size + sizeof(struct UDPMessage));
|
||||
return;
|
||||
}
|
||||
IPV4ProviderSend(17, IPParseMAC(destip), destip, srcip,
|
||||
UDP_Packet(dest_port, src_port, data, size),
|
||||
size + sizeof(struct UDPMessage));
|
||||
}
|
||||
|
||||
void udp_handler(void *base) {
|
||||
// printk("UDP Packet:\n");
|
||||
struct IPV4Message *ipv4 =
|
||||
(struct IPV4Message *)(base + sizeof(struct EthernetFrame_head));
|
||||
struct UDPMessage *udp =
|
||||
(struct UDPMessage *)(base + sizeof(struct EthernetFrame_head) +
|
||||
sizeof(struct IPV4Message));
|
||||
if (swap16(udp->srcPort) == DHCP_SERVER_PORT) { // DHCP给我们分配IP
|
||||
dhcp_handler(base);
|
||||
} else if (swap32(ipv4->srcIP) == DNS_SERVER_IP &&
|
||||
swap16(udp->srcPort) == DNS_PORT) {
|
||||
dns_handler(base);
|
||||
} else {
|
||||
// Socket
|
||||
struct Socket *socket =
|
||||
Socket_Find(swap32(ipv4->srcIP), swap16(udp->srcPort),
|
||||
swap32(ipv4->dstIP), swap16(udp->dstPort), UDP_PROTOCOL);
|
||||
if (socket == -1) {
|
||||
return;
|
||||
}
|
||||
if (socket->Handler != NULL) {
|
||||
socket->Handler(socket, base);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user