IRC Bot, Simple Webserver and Networking Improvements
This commit is contained in:
parent
4d9aee2dd6
commit
a0ca7c55ac
6
ether.c
6
ether.c
@ -24,14 +24,14 @@ int ether_send(struct ether_t *card, char *packet, int len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ether_receive(struct ether_t *ether, char *packet, int len) {
|
int ether_receive(struct ether_t *ether, unsigned char *packet, int len) {
|
||||||
struct ether_packet_t *p = (struct ether_packet_t *)packet;
|
struct ether_packet_t *p = (struct ether_packet_t *)packet;
|
||||||
|
|
||||||
if (htons(p->ethertype) == 0x806) {
|
if (htons(p->ethertype) == 0x806) {
|
||||||
if (!(len - 14 < sizeof(struct arp_packet_t))) {
|
if (!(len - 14 < sizeof(struct arp_packet_t))) {
|
||||||
arp_process_packet(ether, (struct arp_packet_t *)(p->payload));
|
arp_process_packet(ether, (struct arp_packet_t *)(p->payload));
|
||||||
}
|
}
|
||||||
} else if (htons(p->ethertype = 0x800)) {
|
} else if (htons(p->ethertype) == 0x800) {
|
||||||
ipv4_process_packet(ether, (char *)(p->payload), len - sizeof(struct ether_packet_t));
|
ipv4_process_packet(ether, (char *)(p->payload), len - sizeof(struct ether_packet_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,4 +77,4 @@ void init_ether() {
|
|||||||
count++;
|
count++;
|
||||||
ether = init_i825xx(count);
|
ether = init_i825xx(count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
ether.h
2
ether.h
@ -32,7 +32,7 @@ struct ether_packet_t {
|
|||||||
|
|
||||||
extern void init_ether();
|
extern void init_ether();
|
||||||
extern int ether_send(struct ether_t *card, char *packet, int len);
|
extern int ether_send(struct ether_t *card, char *packet, int len);
|
||||||
extern int ether_receive(struct ether_t *ether, char *packet, int len);
|
extern int ether_receive(struct ether_t *ether, unsigned char *packet, int len);
|
||||||
extern int ether_enable(int ether, unsigned int ipv4, unsigned int mask);
|
extern int ether_enable(int ether, unsigned int ipv4, unsigned int mask);
|
||||||
extern struct ether_t *ether_find_from_ipv4(unsigned int ipv4);
|
extern struct ether_t *ether_find_from_ipv4(unsigned int ipv4);
|
||||||
#endif
|
#endif
|
||||||
|
118
i825xx.c
118
i825xx.c
@ -10,9 +10,6 @@
|
|||||||
extern struct ether_t **etherdevs;
|
extern struct ether_t **etherdevs;
|
||||||
extern unsigned int etherdev_count;
|
extern unsigned int etherdev_count;
|
||||||
|
|
||||||
#define NUM_RX_DESCS 128
|
|
||||||
#define NUM_TX_DESCS 128
|
|
||||||
|
|
||||||
//Registers
|
//Registers
|
||||||
#define REG_CTRL 0x00000 //Control Register
|
#define REG_CTRL 0x00000 //Control Register
|
||||||
#define REG_STATUS 0x00008 //Status Register
|
#define REG_STATUS 0x00008 //Status Register
|
||||||
@ -154,16 +151,19 @@ static unsigned short net_eeprom_read(struct i825xx_device_t *net_device, unsign
|
|||||||
|
|
||||||
static void i825xx_poll(struct i825xx_device_t *i825xx_device) {
|
static void i825xx_poll(struct i825xx_device_t *i825xx_device) {
|
||||||
while(i825xx_device->rx_desc[i825xx_device->rx_front].status & RX_DESC_STATUS_DD) {
|
while(i825xx_device->rx_desc[i825xx_device->rx_front].status & RX_DESC_STATUS_DD) {
|
||||||
|
unsigned char *pkt = (unsigned char *)i825xx_device->rx_buff[i825xx_device->rx_front];
|
||||||
|
unsigned short pktlen = i825xx_device->rx_desc[i825xx_device->rx_front].length;
|
||||||
|
|
||||||
if(!(i825xx_device->rx_desc[i825xx_device->rx_front].status & RX_DESC_STATUS_EOP)) {
|
if(!(i825xx_device->rx_desc[i825xx_device->rx_front].status & RX_DESC_STATUS_EOP)) {
|
||||||
kprintf("825xx - rx: no EOP support, dropping");
|
kprintf("825xx - rx: no EOP support, dropping");
|
||||||
} else if(i825xx_device->rx_desc[i825xx_device->rx_front].length < 60) {
|
} else if(i825xx_device->rx_desc[i825xx_device->rx_front].length < 60) {
|
||||||
kprintf("825xx - rx: short packet (%d bytes)", i825xx_device->rx_desc[i825xx_device->rx_front].length);
|
kprintf("825xx - rx: short packet (%d bytes)", i825xx_device->rx_desc[i825xx_device->rx_front].length);
|
||||||
} else {
|
} else {
|
||||||
ether_receive(i825xx_device->ether, i825xx_device->rx_buff[i825xx_device->rx_front], i825xx_device->rx_desc[i825xx_device->rx_front].length);
|
ether_receive(i825xx_device->ether, pkt, pktlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
i825xx_device->rx_desc[i825xx_device->rx_front].status = 0;
|
i825xx_device->rx_desc[i825xx_device->rx_front].status = 0;
|
||||||
i825xx_device->rx_front = (i825xx_device->rx_front + 1) % NUM_RX_DESCS;
|
i825xx_device->rx_front = (i825xx_device->rx_front + 1) % NUM_RX_DESCRIPTORS;
|
||||||
mmio_write(i825xx_device, REG_RDT, i825xx_device->rx_front);
|
mmio_write(i825xx_device, REG_RDT, i825xx_device->rx_front);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,19 +193,13 @@ static void i825xx_isr(struct regs *r) {
|
|||||||
|
|
||||||
|
|
||||||
int i825xx_send(struct i825xx_device_t *i825xx_device, char *packet, int len) {
|
int i825xx_send(struct i825xx_device_t *i825xx_device, char *packet, int len) {
|
||||||
//i825xx_device->tx_desc[i825xx_device->tx_front]->address = (unsigned long long)packet;
|
memset(i825xx_device->tx_buff[i825xx_device->tx_front], 0, 8192);
|
||||||
memcpy(i825xx_device->tx_buff[i825xx_device->tx_front], packet, len);
|
memcpy(i825xx_device->tx_buff[i825xx_device->tx_front], packet, len);
|
||||||
|
i825xx_device->tx_desc[i825xx_device->tx_front].length = len;
|
||||||
if (len < 60) {
|
|
||||||
memset(&i825xx_device->tx_buff[i825xx_device->tx_front][len], 0, 60 - len);
|
|
||||||
len = 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
i825xx_device->tx_desc[i825xx_device->tx_front].length = len;
|
|
||||||
i825xx_device->tx_desc[i825xx_device->tx_front].cmd = ((1 << 3) | (3));
|
i825xx_device->tx_desc[i825xx_device->tx_front].cmd = ((1 << 3) | (3));
|
||||||
|
|
||||||
unsigned int old_tx_front = i825xx_device->tx_front;
|
unsigned int old_tx_front = i825xx_device->tx_front;
|
||||||
i825xx_device->tx_front = (i825xx_device->tx_front + 1) % NUM_TX_DESCS;
|
i825xx_device->tx_front = (i825xx_device->tx_front + 1) % NUM_TX_DESCRIPTORS;
|
||||||
mmio_write(i825xx_device, REG_TDT, i825xx_device->tx_front);
|
mmio_write(i825xx_device, REG_TDT, i825xx_device->tx_front);
|
||||||
|
|
||||||
while(!(i825xx_device->tx_desc[old_tx_front].sta & 0xF))
|
while(!(i825xx_device->tx_desc[old_tx_front].sta & 0xF))
|
||||||
@ -274,60 +268,82 @@ struct ether_t *init_i825xx(int count) {
|
|||||||
//init RX
|
//init RX
|
||||||
i825xx_dev->rx_front = 0;
|
i825xx_dev->rx_front = 0;
|
||||||
|
|
||||||
//unsigned long long tmpbase = (unsigned long long)malloc((sizeof(struct i825xx_rx_desc_t) * NUM_RX_DESCS) + 16);
|
|
||||||
|
|
||||||
i825xx_dev->rx_desc_base = mem_alloc(); //(tmpbase % 16) ? (unsigned char *)((tmpbase) + 16 - (tmpbase % 16)) : (unsigned char *)tmpbase;
|
|
||||||
i825xx_dev->rx_desc = (struct i825xx_rx_desc_t *)mem_pci_sbrk(PAGE_SIZE);
|
|
||||||
mem_map_page(i825xx_dev->rx_desc_base, i825xx_dev->rx_desc, 3);
|
|
||||||
|
|
||||||
for(i = 0; i < NUM_RX_DESCS; i++) {
|
char *pagesrx = mem_alloc_pages(NUM_RX_DESCRIPTORS * 16 / PAGE_SIZE);
|
||||||
char *page = mem_alloc();
|
|
||||||
i825xx_dev->rx_desc[i].address = (unsigned long long)page;
|
|
||||||
i825xx_dev->rx_desc[i].status = 0;
|
i825xx_dev->rx_desc = mem_pci_sbrk(NUM_RX_DESCRIPTORS * 16);
|
||||||
i825xx_dev->rx_desc[i].error = 0;
|
|
||||||
i825xx_dev->rx_buff[i] = mem_pci_sbrk(PAGE_SIZE);
|
|
||||||
mem_map_page(page, i825xx_dev->rx_buff[i], 3);
|
|
||||||
}
|
for (i=0;i<(NUM_RX_DESCRIPTORS * 16 / PAGE_SIZE);i++) {
|
||||||
|
mem_map_page(pagesrx + (i * PAGE_SIZE), (char *)i825xx_dev->rx_desc + (i * PAGE_SIZE), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// aligned base address
|
||||||
|
i825xx_dev->rx_desc_base = pagesrx;
|
||||||
|
|
||||||
|
for( i = 0; i < NUM_RX_DESCRIPTORS; i++ )
|
||||||
|
{
|
||||||
|
unsigned int packet_buff = mem_pci_sbrk(8192);
|
||||||
|
unsigned char *loc = mem_alloc_pages(2);
|
||||||
|
|
||||||
|
mem_map_page(loc, packet_buff, 3);
|
||||||
|
mem_map_page(loc + PAGE_SIZE, packet_buff + PAGE_SIZE, 3);
|
||||||
|
|
||||||
|
i825xx_dev->rx_desc[i].address = (unsigned long long)loc;
|
||||||
|
i825xx_dev->rx_buff[i] = (char *)packet_buff;
|
||||||
|
i825xx_dev->rx_desc[i].status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
mmio_write(i825xx_dev, REG_RDBAL, i825xx_dev->rx_desc_base);
|
mmio_write(i825xx_dev, REG_RDBAL, i825xx_dev->rx_desc_base);
|
||||||
mmio_write(i825xx_dev, REG_RDBAH, 0);
|
mmio_write(i825xx_dev, REG_RDBAH, 0);
|
||||||
mmio_write(i825xx_dev, REG_RDLEN, NUM_RX_DESCS * 16);
|
mmio_write(i825xx_dev, REG_RDLEN, NUM_RX_DESCRIPTORS * 16);
|
||||||
|
|
||||||
mmio_write(i825xx_dev, REG_RDH, 0);
|
mmio_write(i825xx_dev, REG_RDH, 0);
|
||||||
mmio_write(i825xx_dev, REG_RDT, NUM_RX_DESCS);
|
mmio_write(i825xx_dev, REG_RDT, NUM_RX_DESCRIPTORS);
|
||||||
|
|
||||||
|
|
||||||
mmio_write(i825xx_dev, REG_RCTL,
|
mmio_write(i825xx_dev, REG_RCTL,
|
||||||
RCTL_BAM |
|
(RCTL_SBP | RCTL_UPE | RCTL_MPE | RCTL_RDMTS_HALF | RCTL_SECRC |
|
||||||
RCTL_BSEX |
|
RCTL_LPE | RCTL_BAM | RCTL_BSIZE_8192) );
|
||||||
RCTL_SECRC |
|
|
||||||
RCTL_LPE |
|
|
||||||
RCTL_LBM_OFF |
|
|
||||||
RCTL_RDMTS_HALF |
|
|
||||||
RCTL_MO_SHIFT_ZERO);
|
|
||||||
|
|
||||||
|
|
||||||
//init TX
|
|
||||||
i825xx_dev->tx_desc_base = mem_alloc();
|
|
||||||
i825xx_dev->tx_desc = (struct i825xx_tx_desc_t *)mem_pci_sbrk(PAGE_SIZE);
|
|
||||||
mem_map_page(i825xx_dev->tx_desc_base, i825xx_dev->tx_desc, 3);
|
|
||||||
|
|
||||||
i825xx_dev->tx_front = 0;
|
i825xx_dev->tx_front = 0;
|
||||||
|
|
||||||
|
char *pagestx = mem_alloc_pages(NUM_TX_DESCRIPTORS * 16 / PAGE_SIZE);
|
||||||
|
|
||||||
|
i825xx_dev->tx_desc = mem_pci_sbrk(NUM_TX_DESCRIPTORS * 16);
|
||||||
|
|
||||||
for(i = 0; i < NUM_TX_DESCS; i++) {
|
for (i=0;i<(NUM_TX_DESCRIPTORS * 16 / PAGE_SIZE);i++) {
|
||||||
char *page = mem_alloc();
|
mem_map_page(pagestx + (i * PAGE_SIZE), (char *)i825xx_dev->tx_desc + (i * PAGE_SIZE), 3);
|
||||||
i825xx_dev->tx_desc[i].address = page;
|
}
|
||||||
i825xx_dev->tx_desc[i].cmd = 0;
|
|
||||||
i825xx_dev->tx_buff[i] = mem_pci_sbrk(PAGE_SIZE);
|
i825xx_dev->tx_desc_base = pagestx;
|
||||||
mem_map_page(page, i825xx_dev->tx_buff[i], 3);
|
|
||||||
}
|
for (i=0;i<NUM_TX_DESCRIPTORS;i++) {
|
||||||
|
unsigned int packet_buff = mem_pci_sbrk(8192);
|
||||||
|
unsigned char *loc = mem_alloc_pages(2);
|
||||||
|
|
||||||
|
mem_map_page(loc, packet_buff, 3);
|
||||||
|
mem_map_page(loc + PAGE_SIZE, packet_buff + PAGE_SIZE, 3);
|
||||||
|
|
||||||
|
i825xx_dev->tx_desc[i].address = (unsigned long long)loc;
|
||||||
|
i825xx_dev->tx_buff[i] = packet_buff;
|
||||||
|
i825xx_dev->tx_desc[i].cmd = 0;
|
||||||
|
i825xx_dev->tx_desc[i].length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
mmio_write(i825xx_dev, REG_TDBAL, i825xx_dev->tx_desc_base);
|
mmio_write(i825xx_dev, REG_TDBAL, i825xx_dev->tx_desc_base);
|
||||||
mmio_write(i825xx_dev, REG_TDBAH, 0);
|
mmio_write(i825xx_dev, REG_TDBAH, 0);
|
||||||
mmio_write(i825xx_dev, REG_TDLEN, NUM_TX_DESCS * 16);
|
mmio_write(i825xx_dev, REG_TDLEN, NUM_TX_DESCRIPTORS * 16);
|
||||||
|
|
||||||
mmio_write(i825xx_dev, REG_TDH, 0);
|
mmio_write(i825xx_dev, REG_TDH, 0);
|
||||||
mmio_write(i825xx_dev, REG_TDT, 0);
|
mmio_write(i825xx_dev, REG_TDT, NUM_TX_DESCRIPTORS);
|
||||||
|
|
||||||
ether_dev->data = (char *)i825xx_dev;
|
ether_dev->data = (char *)i825xx_dev;
|
||||||
ether_dev->type = 1;
|
ether_dev->type = 1;
|
||||||
@ -355,4 +371,4 @@ void i825xx_disable(struct ether_t *ether) {
|
|||||||
mmio_write(i825xx_device, REG_RCTL, mmio_read(i825xx_device, REG_RCTL) & ~(RCTL_EN));
|
mmio_write(i825xx_device, REG_RCTL, mmio_read(i825xx_device, REG_RCTL) & ~(RCTL_EN));
|
||||||
|
|
||||||
ether->state = 0;
|
ether->state = 0;
|
||||||
}
|
}
|
||||||
|
10
i825xx.h
10
i825xx.h
@ -38,11 +38,11 @@ struct i825xx_device_t
|
|||||||
unsigned int mmio_address;
|
unsigned int mmio_address;
|
||||||
//unsigned int io_address;
|
//unsigned int io_address;
|
||||||
unsigned int rx_front;
|
unsigned int rx_front;
|
||||||
char *rx_buff[NUM_RX_DESCRIPTORS]; // receive descriptor buffer
|
unsigned int tx_front;
|
||||||
unsigned int tx_front;
|
struct i825xx_rx_desc_t *rx_desc; // receive descriptor buffe
|
||||||
char *tx_buff[NUM_TX_DESCRIPTORS]; // transmit descriptor buffer
|
struct i825xx_tx_desc_t *tx_desc; // transmit descriptor buffer
|
||||||
struct i825xx_rx_desc_t *rx_desc;//[NUM_RX_DESCRIPTORS];
|
char *rx_buff[NUM_RX_DESCRIPTORS];
|
||||||
struct i825xx_tx_desc_t *tx_desc;//[NUM_TX_DESCRIPTORS];
|
char *tx_buff[NUM_TX_DESCRIPTORS];
|
||||||
unsigned char *rx_desc_base, *tx_desc_base;
|
unsigned char *rx_desc_base, *tx_desc_base;
|
||||||
struct ether_t *ether;
|
struct ether_t *ether;
|
||||||
};
|
};
|
||||||
|
8
ipv4.c
8
ipv4.c
@ -110,7 +110,7 @@ void ipv4_send(struct ether_t *ether, int type, unsigned int dest, char *packet,
|
|||||||
iph->tos = 0;
|
iph->tos = 0;
|
||||||
iph->len = htons(sizeof(struct ipv4_header_t) + len);
|
iph->len = htons(sizeof(struct ipv4_header_t) + len);
|
||||||
iph->ipid = 0;
|
iph->ipid = 0;
|
||||||
iph->ipoffset = 0;//(1 << 6); // Dont fragment
|
iph->ipoffset = (1 << 6); // Dont fragment
|
||||||
iph->ttl = 0x40;
|
iph->ttl = 0x40;
|
||||||
iph->protocol = type;
|
iph->protocol = type;
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ void ipv4_reassemble_packet(struct ether_t *ether, struct ipv4_header_t *iph) {
|
|||||||
icmp_process_packet(ether, frag->first_packet->src_addr, data, dlen);
|
icmp_process_packet(ether, frag->first_packet->src_addr, data, dlen);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
tcp_process_packet(ether, frag->first_packet->src_addr, data, dlen);
|
tcp_process_packet(ether, frag->first_packet->src_addr, frag->first_packet->dest_addr, data, dlen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ void ipv4_process_packet(struct ether_t *ether, char *packet, int len) {
|
|||||||
icmp_process_packet(ether, iph->src_addr, iph->payload, htons(iph->len) - sizeof(struct ipv4_header_t));
|
icmp_process_packet(ether, iph->src_addr, iph->payload, htons(iph->len) - sizeof(struct ipv4_header_t));
|
||||||
break;
|
break;
|
||||||
case 6: //TCP
|
case 6: //TCP
|
||||||
tcp_process_packet(ether, iph->dest_addr, iph->payload, htons(iph->len) - sizeof(struct ipv4_header_t));
|
tcp_process_packet(ether, iph->dest_addr, iph->src_addr, iph->payload, htons(iph->len) - sizeof(struct ipv4_header_t));
|
||||||
break;
|
break;
|
||||||
case 17: //UDP
|
case 17: //UDP
|
||||||
break;
|
break;
|
||||||
@ -323,4 +323,4 @@ void init_ipv4() {
|
|||||||
first_packet = (void *)0;
|
first_packet = (void *)0;
|
||||||
ipv4_frag_map = hashmap_new();
|
ipv4_frag_map = hashmap_new();
|
||||||
init_sockets();
|
init_sockets();
|
||||||
}
|
}
|
||||||
|
24
memory.c
24
memory.c
@ -302,10 +302,16 @@ void mem_reserve(char *blk, int pages) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocates a single physical page
|
|
||||||
char *mem_alloc(void) {
|
char *mem_alloc(void) {
|
||||||
|
return mem_alloc_pages(1);
|
||||||
|
}
|
||||||
|
// allocates a single physical page
|
||||||
|
char *mem_alloc_pages(int count) {
|
||||||
char * blk;
|
char * blk;
|
||||||
unsigned long mask, offset, index, i;
|
unsigned long mask, offset, index, i, j;
|
||||||
|
int consecutive = 0;
|
||||||
|
|
||||||
|
unsigned long start;
|
||||||
|
|
||||||
for (i=0;i<free_page_count;i++) {
|
for (i=0;i<free_page_count;i++) {
|
||||||
mask = 1;
|
mask = 1;
|
||||||
@ -314,9 +320,19 @@ char *mem_alloc(void) {
|
|||||||
|
|
||||||
if (!(mem_bitmap[index] & (mask << offset))) {
|
if (!(mem_bitmap[index] & (mask << offset))) {
|
||||||
mem_bitmap[index] |= (mask << offset);
|
mem_bitmap[index] |= (mask << offset);
|
||||||
|
if (consecutive == 0) {
|
||||||
|
start = (unsigned long)start_free_mem + (i * PAGE_SIZE);
|
||||||
|
}
|
||||||
|
consecutive++;
|
||||||
|
|
||||||
blk = (char *)((unsigned long)start_free_mem + (i * PAGE_SIZE));
|
if (consecutive == count) {
|
||||||
return blk;
|
return (char *)start;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (j=0;j<consecutive;j++) {
|
||||||
|
mem_free(start + (i * PAGE_SIZE), "mem_alloc");
|
||||||
|
}
|
||||||
|
consecutive = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
memory.h
2
memory.h
@ -8,7 +8,7 @@ struct mem_info {
|
|||||||
unsigned int used;
|
unsigned int used;
|
||||||
unsigned int total;
|
unsigned int total;
|
||||||
};
|
};
|
||||||
|
extern char *mem_alloc_pages(int count);
|
||||||
extern void init_mem(multiboot_info_t *mbd);
|
extern void init_mem(multiboot_info_t *mbd);
|
||||||
extern void init_paging();
|
extern void init_paging();
|
||||||
extern unsigned int mem_usr_sbrk(int amount);
|
extern unsigned int mem_usr_sbrk(int amount);
|
||||||
|
97
programs/network/quinn_net/ircbot.c
Normal file
97
programs/network/quinn_net/ircbot.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "quinn_net.h"
|
||||||
|
|
||||||
|
unsigned int socket;
|
||||||
|
char sbuf[512];
|
||||||
|
|
||||||
|
void raw(char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(sbuf, 512, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
printf("<< %s", sbuf);
|
||||||
|
socket_write(socket, sbuf, strlen(sbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
char nick[] = "QuinnBOT";
|
||||||
|
char channel[] = "#quinn";
|
||||||
|
|
||||||
|
char *user, *command, *where, *message, *sep, *target;
|
||||||
|
int i, j, l, sl, o = -1, start, wordcount;
|
||||||
|
char buf[513];
|
||||||
|
|
||||||
|
socket = socket_open(SOCK_TYPE_TCP);
|
||||||
|
if (socket_connect(socket, ipv4_aton("192.168.56.1"), 6667) == 0) {
|
||||||
|
raw("USER %s 0 0 :%s\r\n", nick, nick);
|
||||||
|
raw("NICK %s\r\n", nick);
|
||||||
|
|
||||||
|
while ((sl = socket_read(socket, sbuf, 512)) > 0) {
|
||||||
|
|
||||||
|
for (i = 0; i < sl; i++) {
|
||||||
|
o++;
|
||||||
|
buf[o] = sbuf[i];
|
||||||
|
if ((i > 0 && sbuf[i] == '\n' && sbuf[i - 1] == '\r') || o == 512) {
|
||||||
|
buf[o + 1] = '\0';
|
||||||
|
l = o;
|
||||||
|
o = -1;
|
||||||
|
|
||||||
|
printf(">> %s", buf);
|
||||||
|
|
||||||
|
if (!strncmp(buf, "PING", 4)) {
|
||||||
|
buf[1] = 'O';
|
||||||
|
raw(buf);
|
||||||
|
} else if (buf[0] == ':') {
|
||||||
|
wordcount = 0;
|
||||||
|
user = command = where = message = NULL;
|
||||||
|
for (j = 1; j < l; j++) {
|
||||||
|
if (buf[j] == ' ') {
|
||||||
|
buf[j] = '\0';
|
||||||
|
wordcount++;
|
||||||
|
switch(wordcount) {
|
||||||
|
case 1: user = buf + 1; break;
|
||||||
|
case 2: command = buf + start; break;
|
||||||
|
case 3: where = buf + start; break;
|
||||||
|
}
|
||||||
|
if (j == l - 1) continue;
|
||||||
|
start = j + 1;
|
||||||
|
} else if (buf[j] == ':' && wordcount == 3) {
|
||||||
|
if (j < l - 1) message = buf + j + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wordcount < 2) continue;
|
||||||
|
|
||||||
|
if (!strncmp(command, "001", 3) && channel != NULL) {
|
||||||
|
raw("JOIN %s\r\n", channel);
|
||||||
|
} else if (!strncmp(command, "PRIVMSG", 7) || !strncmp(command, "NOTICE", 6)) {
|
||||||
|
if (where == NULL || message == NULL) continue;
|
||||||
|
if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '\0';
|
||||||
|
if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
|
||||||
|
|
||||||
|
// printf("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s", user, command, where, target, message);
|
||||||
|
|
||||||
|
if (strncmp(user, "andrew", 6) == 0 && strncmp(message, "QuinnBOT: QUIT", 14) == 0) {
|
||||||
|
raw("PART #quinn\r\n");
|
||||||
|
raw("QUIT\r\n");
|
||||||
|
socket_close(socket);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//raw("%s %s :%s", command, target, message); // If you enable this the IRCd will get its "*** Looking up your hostname..." messages thrown back at it but it works...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket_close(socket);
|
||||||
|
} else {
|
||||||
|
printf("Unable to connect!\n");
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,26 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "quinn_net.h"
|
||||||
|
|
||||||
|
#define SYS_SOCK_LISTEN 39
|
||||||
|
#define SYS_SOCK_ACCEPT 40
|
||||||
|
|
||||||
|
int socket_listen(unsigned int socket, unsigned int addr, unsigned short port) {
|
||||||
|
int ret;
|
||||||
|
__asm__ volatile ("int $0x30" : "=a" (ret) : "0" (39), "b" (socket), "c" (addr), "d" (port));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int socket_accept(unsigned int socket, struct inet_addr *clientaddr) {
|
||||||
|
unsigned int ret;
|
||||||
|
__asm__ volatile ("int $0x30" : "=a" (ret) : "0" (40), "b" (socket), "c" (clientaddr));
|
||||||
|
while (ret == 0) {
|
||||||
|
__asm__ volatile ("int $0x30" : "=a" (ret) : "0" (23)); // yield
|
||||||
|
__asm__ volatile ("int $0x30" : "=a" (ret) : "0" (40), "b" (socket), "c" (clientaddr));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int socket_open(unsigned char type) {
|
unsigned int socket_open(unsigned char type) {
|
||||||
unsigned int ret;
|
unsigned int ret;
|
||||||
@ -84,4 +106,9 @@ unsigned int ipv4_aton(char* ipAddress) {
|
|||||||
theip = 0;
|
theip = 0;
|
||||||
theip = (ip[0] << 24) | (ip[1] << 16) | (ip [2] << 8) | ip[3];
|
theip = (ip[0] << 24) | (ip[1] << 16) | (ip [2] << 8) | ip[3];
|
||||||
return theip;
|
return theip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ipv4_ntoa(unsigned int ipAddress, char *buffer) {
|
||||||
|
sprintf(buffer, "%d.%d.%d.%d", (ipAddress >> 24) & 0xff, (ipAddress >> 16) & 0xff, (ipAddress >> 8) & 0xff, ipAddress & 0xff);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
#ifndef __QUINN_NET_H
|
#ifndef __QUINN_NET_H
|
||||||
#define __QUINN_NET_H
|
#define __QUINN_NET_H
|
||||||
|
|
||||||
|
#define SOCK_TYPE_TCP 1
|
||||||
|
|
||||||
|
struct inet_addr {
|
||||||
|
unsigned int type;
|
||||||
|
unsigned int addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern unsigned int socket_accept(unsigned int socket, struct inet_addr *clientaddr);
|
||||||
|
extern int socket_listen(unsigned int socket, unsigned int addr, unsigned short port);
|
||||||
extern unsigned int socket_open(unsigned char type);
|
extern unsigned int socket_open(unsigned char type);
|
||||||
extern unsigned int socket_connect(unsigned int socket, unsigned int addr, unsigned short port);
|
extern unsigned int socket_connect(unsigned int socket, unsigned int addr, unsigned short port);
|
||||||
extern void socket_close(unsigned int socket);
|
extern void socket_close(unsigned int socket);
|
||||||
extern int socket_read(unsigned int socket, char *buffer, int len);
|
extern int socket_read(unsigned int socket, char *buffer, int len);
|
||||||
extern int socket_write(unsigned int socket, char *buffer, unsigned int len);
|
extern int socket_write(unsigned int socket, char *buffer, unsigned int len);
|
||||||
extern unsigned int ipv4_aton(char* ipAddress);
|
extern unsigned int ipv4_aton(char* ipAddress);
|
||||||
#endif
|
extern char *ipv4_ntoa(unsigned int ipAddress, char *buffer);
|
||||||
|
#endif
|
||||||
|
25
programs/network/quinn_net/quinn_testserver.c
Normal file
25
programs/network/quinn_net/quinn_testserver.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "quinn_net.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
unsigned int socket;
|
||||||
|
unsigned int new_socket;
|
||||||
|
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
int read;
|
||||||
|
|
||||||
|
socket = socket_open(1);
|
||||||
|
if (socket_listen(socket, ipv4_aton("192.168.56.2"), 6666) != 0) {
|
||||||
|
printf("Error listening!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_socket = socket_accept(socket);
|
||||||
|
socket_close(socket);
|
||||||
|
|
||||||
|
while ((read = socket_read(new_socket, buffer, 512)) > 0) {
|
||||||
|
socket_write(new_socket, buffer, read);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
466
programs/network/www/wwwserver.c
Normal file
466
programs/network/www/wwwserver.c
Normal file
@ -0,0 +1,466 @@
|
|||||||
|
#include "quinn_net.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define PROGRAM_VERSION "0.4-QUINN"
|
||||||
|
|
||||||
|
#define HTML_BASE "disk0:/www"
|
||||||
|
|
||||||
|
#define HTTP_VERSION_1_0 1
|
||||||
|
#define HTTP_VERSION_1_1 2
|
||||||
|
|
||||||
|
#define HTTP_TYPE_GET 1
|
||||||
|
#define HTTP_TYPE_POST 2
|
||||||
|
#define HTTP_TYPE_HEAD 3
|
||||||
|
|
||||||
|
|
||||||
|
struct dllist_t {
|
||||||
|
char *data;
|
||||||
|
struct dllist_t *next;
|
||||||
|
struct dllist_t *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct request_t {
|
||||||
|
int type;
|
||||||
|
unsigned int addr;
|
||||||
|
char *path;
|
||||||
|
char *fspath;
|
||||||
|
char *fsdirname;
|
||||||
|
char *fsbasename;
|
||||||
|
unsigned int size;
|
||||||
|
int version;
|
||||||
|
char **headers;
|
||||||
|
int header_count;
|
||||||
|
int dlen;
|
||||||
|
unsigned char *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
char *basename(char *dir) {
|
||||||
|
char *ptr = &dir[strlen(dir) - 1];
|
||||||
|
|
||||||
|
while (*ptr != '/' && ptr != dir) {
|
||||||
|
ptr--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ++ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *dirname(char *dir) {
|
||||||
|
char *ptr = &dir[strlen(dir) - 1];
|
||||||
|
|
||||||
|
while (*ptr != '/' && ptr != dir) {
|
||||||
|
*ptr = '\0';
|
||||||
|
ptr--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dolog(int retcode, char *path, unsigned int client_address) {
|
||||||
|
time_t atime;
|
||||||
|
struct tm *atime_struct;
|
||||||
|
char buffer[16];
|
||||||
|
|
||||||
|
atime = time(NULL);
|
||||||
|
atime_struct = localtime(&atime);
|
||||||
|
|
||||||
|
printf("\e[1;30m[\e[1;37m%.2d\e[0;37m:\e[1;37m%.2d\e[1;30m][\e[1;36m%s\e[1;30m][%s%3d\e[1;30m] \e[0;37m%s\n\e[0m", atime_struct->tm_hour, atime_struct->tm_min, ipv4_ntoa(client_address, buffer), (retcode >= 400 ? "\e[1;31m" : "\e[1;32m"), retcode, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *urldecode(char *str)
|
||||||
|
{
|
||||||
|
char *translated_str;
|
||||||
|
char *pptr;
|
||||||
|
char *pptr2;
|
||||||
|
int code;
|
||||||
|
|
||||||
|
pptr = str;
|
||||||
|
translated_str = (char *)malloc(strlen(str) + 1);
|
||||||
|
|
||||||
|
if (!translated_str) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pptr2 = translated_str;
|
||||||
|
|
||||||
|
while (*pptr != '\0') {
|
||||||
|
if (*pptr == '%') {
|
||||||
|
pptr++;
|
||||||
|
if (*pptr == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (*pptr >= '0' && *pptr <= '9') {
|
||||||
|
code = ((int)*pptr - 48) * 16;
|
||||||
|
} else {
|
||||||
|
switch (*pptr) {
|
||||||
|
case 'A':
|
||||||
|
case 'a':
|
||||||
|
code = 10 * 16;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
code = 11 * 16;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
case 'c':
|
||||||
|
code = 12 * 16;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
case 'd':
|
||||||
|
code = 13 * 16;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
case 'e':
|
||||||
|
code = 14 * 16;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
case 'f':
|
||||||
|
code = 15 * 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pptr++;
|
||||||
|
|
||||||
|
if (*pptr == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (*pptr >= '0' && *pptr <= '9') {
|
||||||
|
code += ((int)*pptr - 48);
|
||||||
|
} else {
|
||||||
|
switch (*pptr) {
|
||||||
|
case 'A':
|
||||||
|
case 'a':
|
||||||
|
code += 10;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
code += 11;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
case 'c':
|
||||||
|
code += 12;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
case 'd':
|
||||||
|
code += 13;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
case 'e':
|
||||||
|
code += 14;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
case 'f':
|
||||||
|
code += 15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code >= 0x20 && code <= 0xFF) {
|
||||||
|
*pptr2 = (char)code;
|
||||||
|
pptr2++;
|
||||||
|
*pptr2 = '\0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*pptr2 = *pptr;
|
||||||
|
pptr2++;
|
||||||
|
*pptr2 = '\0';
|
||||||
|
}
|
||||||
|
pptr++;
|
||||||
|
}
|
||||||
|
return translated_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int read_line(unsigned int s, char *buffer, int max_len) {
|
||||||
|
int br = 0;
|
||||||
|
int bcount = 0;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while (bcount < max_len - 1) {
|
||||||
|
br = socket_read(s, &c, 1);
|
||||||
|
if (br < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (br == 1) {
|
||||||
|
if (c == '\r') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == '\n') {
|
||||||
|
buffer[bcount] = '\0';
|
||||||
|
return bcount;
|
||||||
|
}
|
||||||
|
buffer[bcount] = c;
|
||||||
|
bcount++;
|
||||||
|
}
|
||||||
|
if (br == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer[bcount] = '\0';
|
||||||
|
return bcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_notfound(unsigned int s, struct request_t *req) {
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
char html404[] = "<html><head>\r\n"
|
||||||
|
"<title>404 Not Found</title>\r\n"
|
||||||
|
"</head><body>\r\n"
|
||||||
|
"<h1>Not Found</h1>\r\n"
|
||||||
|
"The requested resource was not found.\r\n"
|
||||||
|
"</body></html>\r\n";
|
||||||
|
|
||||||
|
|
||||||
|
sprintf(buffer, "%s 404 Not Found\r\n", (req->version == HTTP_VERSION_1_0 ? "HTTP/1.0" : "HTTP/1.1"));
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
sprintf(buffer, "Server: Mite/%s\r\n", PROGRAM_VERSION);
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
sprintf(buffer, "Content-Type: text/html\r\n");
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
sprintf(buffer, "Content-Length: %lu\r\n", (unsigned long)strlen(html404));
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
sprintf(buffer, "\r\n");
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
if (req->type == HTTP_TYPE_GET) {
|
||||||
|
sprintf(buffer, "%s", html404);
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
socket_close(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_get(unsigned int s, struct request_t *req) {
|
||||||
|
char buffer[512];
|
||||||
|
int br;
|
||||||
|
FILE *fptr;
|
||||||
|
|
||||||
|
sprintf(buffer, "%s 200 OK\r\n", (req->version == HTTP_VERSION_1_0 ? "HTTP/1.0" : "HTTP/1.1"));
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
sprintf(buffer, "Server: Mite/%s\r\n", PROGRAM_VERSION);
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
|
||||||
|
if (strcasecmp(&req->path[strlen(req->path) - 5], "html") == 0) {
|
||||||
|
sprintf(buffer, "Content-Type: text/html\r\n");
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
} else if (strcasecmp(&req->path[strlen(req->path) - 4], "htm") == 0) {
|
||||||
|
sprintf(buffer, "Content-Type: text/html\r\n");
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
} else if (strcasecmp(&req->path[strlen(req->path) - 4], "png") == 0) {
|
||||||
|
sprintf(buffer, "Content-Type: image/png\r\n");
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
} else {
|
||||||
|
sprintf(buffer, "Content-Type: text/plain\r\n");
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
}
|
||||||
|
sprintf(buffer, "Content-Length: %lu\r\n", (unsigned long)req->size);
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
sprintf(buffer, "\r\n");
|
||||||
|
socket_write(s, buffer, strlen(buffer));
|
||||||
|
|
||||||
|
fptr = fopen(req->fspath, "r");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
br = fread(buffer, 1, 512, fptr);
|
||||||
|
socket_write(s, buffer, br);
|
||||||
|
if (br < 256) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fptr);
|
||||||
|
dolog(200, req->path, req->addr);
|
||||||
|
|
||||||
|
socket_close(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_www(unsigned int csock, char *clientIP) {
|
||||||
|
char buffer[1024];
|
||||||
|
char *arg[3];
|
||||||
|
struct dllist_t *path_root;
|
||||||
|
struct dllist_t *plptr;
|
||||||
|
char *rescpy;
|
||||||
|
char *filename;
|
||||||
|
char *query;
|
||||||
|
char *pptr;
|
||||||
|
|
||||||
|
struct request_t req;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
req.addr = ipv4_aton(clientIP);
|
||||||
|
|
||||||
|
|
||||||
|
if (read_line(csock, buffer, 1024) == -1) {
|
||||||
|
// Socket error
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
arg[0] = strtok(buffer, " \t");
|
||||||
|
arg[1] = strtok(NULL, " \t");
|
||||||
|
arg[2] = strtok(NULL, " \t");
|
||||||
|
|
||||||
|
req.path = (char *)malloc(strlen(arg[1]) + 1);
|
||||||
|
if (!req.path) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(req.path, arg[1]);
|
||||||
|
|
||||||
|
path_root = (struct dllist_t *)malloc(sizeof(struct dllist_t));
|
||||||
|
if (!path_root) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
path_root->prev = NULL;
|
||||||
|
path_root->next = NULL;
|
||||||
|
path_root->data = NULL;
|
||||||
|
|
||||||
|
plptr = path_root;
|
||||||
|
|
||||||
|
rescpy = (char *)malloc(strlen(req.path) + 1);
|
||||||
|
if (!rescpy) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(rescpy, req.path);
|
||||||
|
|
||||||
|
filename = strtok(rescpy, "?");
|
||||||
|
query = strtok(NULL, "?");
|
||||||
|
|
||||||
|
pptr = strtok(filename, "/");
|
||||||
|
|
||||||
|
while (pptr != NULL) {
|
||||||
|
if (!strcmp(pptr, "..")) {
|
||||||
|
if (plptr->prev != NULL) {
|
||||||
|
plptr = plptr->prev;
|
||||||
|
free(plptr->next);
|
||||||
|
plptr->next = NULL;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (!strcmp(pptr, ".")) {
|
||||||
|
// do nothing
|
||||||
|
} else {
|
||||||
|
plptr->next = (struct dllist_t *)malloc(sizeof(struct dllist_t));
|
||||||
|
if (!plptr->next) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
plptr->data = pptr;
|
||||||
|
plptr->next->data = NULL;
|
||||||
|
plptr->next->prev = plptr;
|
||||||
|
plptr->next->next = NULL;
|
||||||
|
plptr = plptr->next;
|
||||||
|
}
|
||||||
|
pptr = strtok(NULL, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
req.fspath = (char *)malloc(strlen(HTML_BASE) + 1);
|
||||||
|
|
||||||
|
if (!req.fspath) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(req.fspath, HTML_BASE);
|
||||||
|
|
||||||
|
plptr = path_root;
|
||||||
|
|
||||||
|
while (plptr != NULL && plptr->data != NULL) {
|
||||||
|
req.fspath = (char *)realloc(req.fspath, strlen(req.fspath) + strlen(plptr->data) + 2);
|
||||||
|
if (!req.fspath) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(req.fspath, "%s/%s", req.fspath, plptr->data);
|
||||||
|
plptr = plptr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arg[2], "HTTP/1.0")) {
|
||||||
|
req.version = HTTP_VERSION_1_0;
|
||||||
|
} else
|
||||||
|
if (!strcmp(arg[2], "HTTP/1.1")) {
|
||||||
|
req.version = HTTP_VERSION_1_1;
|
||||||
|
} else {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!strcmp(arg[0], "GET")) {
|
||||||
|
req.type = HTTP_TYPE_GET;
|
||||||
|
} else
|
||||||
|
if (!strcmp(arg[0], "POST")) {
|
||||||
|
req.type = HTTP_TYPE_POST;
|
||||||
|
} else
|
||||||
|
if (!strcmp(arg[0], "HEAD")) {
|
||||||
|
req.type = HTTP_TYPE_HEAD;
|
||||||
|
} else {
|
||||||
|
req.type = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
req.fspath = urldecode(req.fspath);
|
||||||
|
|
||||||
|
again:
|
||||||
|
|
||||||
|
if (stat(req.fspath, &st) != 0) {
|
||||||
|
// file opening error
|
||||||
|
do_notfound(csock, &req);
|
||||||
|
dolog(404, req.path, req.addr);
|
||||||
|
} else {
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
req.fspath = (char *)realloc(req.fspath, strlen(req.fspath) + 12);
|
||||||
|
strcat(req.fspath, "/index.html");
|
||||||
|
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
req.fsdirname = strdup(req.fspath);
|
||||||
|
req.fsbasename = strdup(req.fspath);
|
||||||
|
|
||||||
|
req.fsdirname = dirname(req.fsdirname);
|
||||||
|
req.fsbasename = basename(req.fsbasename);
|
||||||
|
|
||||||
|
req.size = (unsigned int)st.st_size;
|
||||||
|
do_get(csock, &req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(clientIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
unsigned int socket = socket_open(1);
|
||||||
|
unsigned int csock;
|
||||||
|
struct inet_addr caddr;
|
||||||
|
char clientIP[16];
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("USAGE wwwserver.exe [ip to listen on]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socket_listen(socket, ipv4_aton(argv[1]), 80) != 0) {
|
||||||
|
printf("Unable to listen..\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
csock = socket_accept(socket, &caddr);
|
||||||
|
|
||||||
|
ipv4_ntoa(caddr.addr, clientIP);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
switch (pid) {
|
||||||
|
case -1:
|
||||||
|
printf("Error forking!\n");
|
||||||
|
exit(-1);
|
||||||
|
case 0:
|
||||||
|
handle_www(csock, strdup(clientIP));
|
||||||
|
exit(0);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -122,6 +122,7 @@ void init_scheduler(void) {
|
|||||||
current_task->sem_wait = 0;
|
current_task->sem_wait = 0;
|
||||||
current_task->sem_timeout = 0;
|
current_task->sem_timeout = 0;
|
||||||
current_task->sem_time_waiting = 0;
|
current_task->sem_time_waiting = 0;
|
||||||
|
current_task->waiting_socket_count = 0;
|
||||||
for (i=0;i<64;i++) {
|
for (i=0;i<64;i++) {
|
||||||
current_task->user_env_pages[i] = 0;
|
current_task->user_env_pages[i] = 0;
|
||||||
}
|
}
|
||||||
@ -172,6 +173,10 @@ void sched_free_task(struct task_t *this_task) {
|
|||||||
|
|
||||||
dbfree(this_task->user_pages, "user pages");
|
dbfree(this_task->user_pages, "user pages");
|
||||||
|
|
||||||
|
for (i=0;i<this_task->waiting_socket_count;i++) {
|
||||||
|
free(this_task->waiting_sockets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// free page directory
|
// free page directory
|
||||||
|
|
||||||
|
|
||||||
@ -290,6 +295,7 @@ struct task_t *sched_new_task() {
|
|||||||
new_task->sem_wait = 0;
|
new_task->sem_wait = 0;
|
||||||
new_task->sem_timeout = 0;
|
new_task->sem_timeout = 0;
|
||||||
new_task->sem_time_waiting = 0;
|
new_task->sem_time_waiting = 0;
|
||||||
|
new_task->waiting_socket_count = 0;
|
||||||
strcpy(new_task->name, current_task->name);
|
strcpy(new_task->name, current_task->name);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
#define TASK_RUNNING 1
|
#define TASK_RUNNING 1
|
||||||
#define TASK_NOTRUNNING 2
|
#define TASK_NOTRUNNING 2
|
||||||
@ -61,6 +62,8 @@ struct task_t {
|
|||||||
int sem_time_waiting;
|
int sem_time_waiting;
|
||||||
char *mail;
|
char *mail;
|
||||||
int mail_len;
|
int mail_len;
|
||||||
|
struct socket_t *waiting_sockets[5];
|
||||||
|
int waiting_socket_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tss_t {
|
struct tss_t {
|
||||||
|
146
socket.c
146
socket.c
@ -10,18 +10,57 @@ unsigned int socket_count;
|
|||||||
|
|
||||||
extern void tcp_send(struct ether_t *ether, struct socket_t *sock, unsigned short flags, unsigned char *packet, unsigned int len);
|
extern void tcp_send(struct ether_t *ether, struct socket_t *sock, unsigned short flags, unsigned char *packet, unsigned int len);
|
||||||
|
|
||||||
struct socket_t *socket_find(unsigned int dport) {
|
struct socket_t *socket_find(unsigned int dport, unsigned int sport, unsigned int src_ip, unsigned int seq) {
|
||||||
int i;
|
int i;
|
||||||
|
struct socket_t *new_socket;
|
||||||
|
|
||||||
for (i=0;i<socket_count;i++) {
|
for (i=0;i<socket_count;i++) {
|
||||||
if (sockets[i]->port_recv == dport) {
|
if (sockets[i]->port_recv == dport && sockets[i]->port_dest == sport && sockets[i]->addr == src_ip) {
|
||||||
if (sockets[i]->status != 1) {
|
if (sockets[i]->status == 0 || sockets[i]->status == 2) {
|
||||||
return sockets[i];
|
return sockets[i];
|
||||||
} else {
|
} else {
|
||||||
return (void *)0;
|
return (void *)0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i=0;i<socket_count;i++) {
|
||||||
|
if (sockets[i]->port_recv == dport && sockets[i]->addr == 0) {
|
||||||
|
if (sockets[i]->status == 3) {
|
||||||
|
struct task_t *task = (struct task_t *)sockets[i]->data;
|
||||||
|
|
||||||
|
if (task->waiting_socket_count < 4) {
|
||||||
|
|
||||||
|
|
||||||
|
new_socket = (struct socket_t *)malloc(sizeof(struct socket_t));
|
||||||
|
if (new_socket) {
|
||||||
|
memset(new_socket, 0, sizeof(struct socket_t));
|
||||||
|
new_socket->socket_type = 1;
|
||||||
|
|
||||||
|
new_socket->port_recv = dport;
|
||||||
|
new_socket->tcp_sock.seq_number = 0;
|
||||||
|
new_socket->tcp_sock.ack_number = seq + 1;
|
||||||
|
|
||||||
|
new_socket->tcp_packets = (void *)0;
|
||||||
|
new_socket->tcp_packet_count = 0;
|
||||||
|
|
||||||
|
new_socket->addr = src_ip;
|
||||||
|
new_socket->bytes_available = 0;
|
||||||
|
new_socket->bytes_read = 0;
|
||||||
|
new_socket->port_dest = sport;
|
||||||
|
new_socket->offset = 0;
|
||||||
|
new_socket->ether = sockets[i]->ether;
|
||||||
|
|
||||||
|
new_socket->status = 0;
|
||||||
|
task->waiting_sockets[task->waiting_socket_count++] = new_socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (void *)0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (void *)0;
|
return (void *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +69,7 @@ struct tcp_data_t *socket_get_packet(struct socket_t *sock) {
|
|||||||
struct tcp_data_t *packet;
|
struct tcp_data_t *packet;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
if (sock->tcp_packet_count == 0) {
|
if (sock->tcp_packet_count == 0) {
|
||||||
return (void *)0;
|
return (void *)0;
|
||||||
}
|
}
|
||||||
@ -92,7 +132,7 @@ int socket_read(struct socket_t *sock, char *buffer, int len) {
|
|||||||
|
|
||||||
if (size_to_read < sock->bytes_available) {
|
if (size_to_read < sock->bytes_available) {
|
||||||
sock->bytes_available = sock->bytes_available - size_to_read;
|
sock->bytes_available = sock->bytes_available - size_to_read;
|
||||||
sock->bytes_read = size_to_read;
|
sock->bytes_read += size_to_read;
|
||||||
sock->tcp_curr_packet = data;
|
sock->tcp_curr_packet = data;
|
||||||
} else {
|
} else {
|
||||||
sock->bytes_available = 0;
|
sock->bytes_available = 0;
|
||||||
@ -142,6 +182,29 @@ int socket_connect(struct socket_t* sock, unsigned int dest_ip, unsigned short d
|
|||||||
|
|
||||||
void socket_close(struct socket_t *sock) {
|
void socket_close(struct socket_t *sock) {
|
||||||
sock->status = 1;
|
sock->status = 1;
|
||||||
|
tcp_send(sock->ether, sock, TCP_FLAGS_FIN, (void *)0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void socket_doclose(struct socket_t *sock) {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (i=0;i<socket_count;i++) {
|
||||||
|
if (sockets[i] == sock) {
|
||||||
|
for (j=0;j<sock->tcp_packet_count;j++) {
|
||||||
|
free(sock->tcp_packets[j]->data);
|
||||||
|
free(sock->tcp_packets[j]);
|
||||||
|
}
|
||||||
|
free(sock->tcp_packets);
|
||||||
|
free(sock);
|
||||||
|
|
||||||
|
for (j=i+1;j<socket_count;j++) {
|
||||||
|
sockets[j-1] = sockets[j];
|
||||||
|
}
|
||||||
|
socket_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct socket_t *socket_open(unsigned char type) {
|
struct socket_t *socket_open(unsigned char type) {
|
||||||
@ -155,7 +218,10 @@ struct socket_t *socket_open(unsigned char type) {
|
|||||||
} else {
|
} else {
|
||||||
sockets = (struct socket_t **)realloc(sockets, sizeof(struct socket_t *) * (socket_count + 1));
|
sockets = (struct socket_t **)realloc(sockets, sizeof(struct socket_t *) * (socket_count + 1));
|
||||||
}
|
}
|
||||||
|
sock->status = 0;
|
||||||
sock->socket_type = type;
|
sock->socket_type = type;
|
||||||
|
sock->bytes_available = 0;
|
||||||
|
sock->bytes_read = 0;
|
||||||
sockets[socket_count] = sock;
|
sockets[socket_count] = sock;
|
||||||
socket_count++;
|
socket_count++;
|
||||||
} else {
|
} else {
|
||||||
@ -165,6 +231,78 @@ struct socket_t *socket_open(unsigned char type) {
|
|||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void *current_task;
|
||||||
|
|
||||||
|
int socket_listen(struct socket_t *sock, unsigned int listenip, unsigned short port) {
|
||||||
|
if (sock->socket_type != 1) {
|
||||||
|
kprintf("Wrong socket Type\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock->port_recv = port;
|
||||||
|
sock->tcp_sock.seq_number = 0;
|
||||||
|
sock->tcp_sock.ack_number = 0;
|
||||||
|
|
||||||
|
sock->tcp_packets = (void *)0;
|
||||||
|
sock->tcp_packet_count = 0;
|
||||||
|
|
||||||
|
sock->addr = 0;
|
||||||
|
sock->port_dest = 0;
|
||||||
|
|
||||||
|
sock->ether = ether_find_from_ipv4(listenip);
|
||||||
|
|
||||||
|
sock->status = 3;
|
||||||
|
|
||||||
|
sock->data = (void *)current_task;
|
||||||
|
|
||||||
|
if (!sock->ether) {
|
||||||
|
kprintf("Cant find ether\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct socket_t *socket_accept(struct socket_t *socket, struct inet_addr *client_addr) {
|
||||||
|
struct task_t *task = (struct task_t *)socket->data;
|
||||||
|
struct socket_t *new_socket;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (task->waiting_socket_count > 0) {
|
||||||
|
new_socket = task->waiting_sockets[0];
|
||||||
|
|
||||||
|
for (i=1;i<task->waiting_socket_count;i++) {
|
||||||
|
task->waiting_sockets[i-1] = task->waiting_sockets[i];
|
||||||
|
}
|
||||||
|
task->waiting_socket_count--;
|
||||||
|
|
||||||
|
if (socket_count == 0) {
|
||||||
|
sockets = (struct socket_t **)malloc(sizeof(struct socket_t *));
|
||||||
|
} else {
|
||||||
|
sockets = (struct socket_t **)realloc(sockets, sizeof(struct socket_t *) * (socket_count + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
sockets[socket_count] = new_socket;
|
||||||
|
|
||||||
|
socket_count++;
|
||||||
|
|
||||||
|
// send SYN ACK
|
||||||
|
if (new_socket->socket_type == 1) {
|
||||||
|
|
||||||
|
tcp_send(new_socket->ether, new_socket, TCP_FLAGS_SYN | TCP_FLAGS_ACK, (void *)0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_addr != (void *)0) {
|
||||||
|
client_addr->type = new_socket->socket_type;
|
||||||
|
client_addr->addr = new_socket->addr;
|
||||||
|
}
|
||||||
|
return new_socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *)0;
|
||||||
|
}
|
||||||
|
|
||||||
int socket_write(struct socket_t* sock, unsigned char* payload, unsigned int len) {
|
int socket_write(struct socket_t* sock, unsigned char* payload, unsigned int len) {
|
||||||
tcp_send(sock->ether, sock, (1 << 4) | (1 << 3), payload, len);
|
tcp_send(sock->ether, sock, (1 << 4) | (1 << 3), payload, len);
|
||||||
return 0;
|
return 0;
|
||||||
|
11
socket.h
11
socket.h
@ -18,9 +18,18 @@ struct socket_t {
|
|||||||
struct tcp_data_t *tcp_curr_packet;
|
struct tcp_data_t *tcp_curr_packet;
|
||||||
struct tcp_data_t **tcp_packets;
|
struct tcp_data_t **tcp_packets;
|
||||||
unsigned int tcp_packet_count;
|
unsigned int tcp_packet_count;
|
||||||
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct socket_t *socket_find(unsigned int dport);
|
struct inet_addr {
|
||||||
|
unsigned int type;
|
||||||
|
unsigned int addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void socket_doclose(struct socket_t *sock);
|
||||||
|
extern int socket_listen(struct socket_t *sock, unsigned int listenip, unsigned short port);
|
||||||
|
extern struct socket_t *socket_accept(struct socket_t *socket, struct inet_addr *client_addr);
|
||||||
|
extern struct socket_t *socket_find(unsigned int dport, unsigned int sport, unsigned int src_ip, unsigned int seq);
|
||||||
extern void socket_close(struct socket_t *sock);
|
extern void socket_close(struct socket_t *sock);
|
||||||
extern struct socket_t *socket_open(unsigned char type);
|
extern struct socket_t *socket_open(unsigned char type);
|
||||||
extern int socket_write(struct socket_t* sock, unsigned char* payload, unsigned int len);
|
extern int socket_write(struct socket_t* sock, unsigned char* payload, unsigned int len);
|
||||||
|
@ -210,6 +210,12 @@ void syscall_isr(struct regs *r) {
|
|||||||
case SYS_SOCK_WRITE:
|
case SYS_SOCK_WRITE:
|
||||||
r->eax = socket_write((struct socket_t*)r->ebx, (unsigned char*)r->ecx, r->edx);
|
r->eax = socket_write((struct socket_t*)r->ebx, (unsigned char*)r->ecx, r->edx);
|
||||||
break;
|
break;
|
||||||
|
case SYS_SOCK_LISTEN:
|
||||||
|
r->eax = socket_listen((struct socket_t *)r->ebx, (unsigned int)r->ecx, (unsigned short)r->edx);
|
||||||
|
break;
|
||||||
|
case SYS_SOCK_ACCEPT:
|
||||||
|
r->eax = (unsigned int)socket_accept((struct socket_t *)r->ebx, (struct inet_addr *)r->ecx);
|
||||||
|
break;
|
||||||
case SYS_MEM_INFO:
|
case SYS_MEM_INFO:
|
||||||
r->eax = mem_get_info((struct mem_info *)r->ebx);
|
r->eax = mem_get_info((struct mem_info *)r->ebx);
|
||||||
break;
|
break;
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
#define SYS_MEM_INFO 36
|
#define SYS_MEM_INFO 36
|
||||||
#define SYS_WINDOW_DESTROY 37
|
#define SYS_WINDOW_DESTROY 37
|
||||||
#define SYS_UNLINK 38
|
#define SYS_UNLINK 38
|
||||||
|
#define SYS_SOCK_LISTEN 39
|
||||||
|
#define SYS_SOCK_ACCEPT 40
|
||||||
|
|
||||||
extern void init_syscalls();
|
extern void init_syscalls();
|
||||||
|
|
||||||
|
20
tcp.c
20
tcp.c
@ -37,12 +37,12 @@ void tcp_send(struct ether_t *ether, struct socket_t *sock, unsigned short flags
|
|||||||
header->checksum = 0; // Fill in later
|
header->checksum = 0; // Fill in later
|
||||||
header->urgent = 0;
|
header->urgent = 0;
|
||||||
|
|
||||||
if ((flags & 0xff) == TCP_FLAGS_SYN) {
|
if ((flags & 0xff) == TCP_FLAGS_SYN || (flags & 0xff) == (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) {
|
||||||
sock->tcp_sock.seq_number += 1;
|
sock->tcp_sock.seq_number += 1;
|
||||||
} else {
|
} else {
|
||||||
sock->tcp_sock.seq_number += len;
|
sock->tcp_sock.seq_number += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet != (void *)0 && len != 0) {
|
if (packet != (void *)0 && len != 0) {
|
||||||
memcpy(header->payload, packet, len);
|
memcpy(header->payload, packet, len);
|
||||||
}
|
}
|
||||||
@ -75,11 +75,17 @@ void tcp_send(struct ether_t *ether, struct socket_t *sock, unsigned short flags
|
|||||||
ipv4_send(ether, 0x06, htonl(sock->addr), header, len + sizeof(struct tcp_header_t));
|
ipv4_send(ether, 0x06, htonl(sock->addr), header, len + sizeof(struct tcp_header_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcp_process_packet(struct ether_t *ether, unsigned int dest, struct tcp_header_t *packet, unsigned int len) {
|
void tcp_process_packet(struct ether_t *ether, unsigned int dest, unsigned int src, struct tcp_header_t *packet, unsigned int len) {
|
||||||
// find socket
|
// find socket
|
||||||
struct tcp_data_t *data;
|
struct tcp_data_t *data;
|
||||||
unsigned int dlen = len - ((htons(packet->flags) >> 12) * 4);
|
unsigned int dlen = len - ((htons(packet->flags) >> 12) * 4);
|
||||||
struct socket_t *sock = socket_find(htons(packet->dest_port));
|
struct socket_t *sock = socket_find(htons(packet->dest_port), htons(packet->source_port), htonl(src), htonl(packet->seq_number));
|
||||||
|
|
||||||
|
if ((htons(packet->flags) & TCP_FLAGS_FIN) && (htons(packet->flags) & TCP_FLAGS_ACK)) {
|
||||||
|
socket_doclose(sock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (sock != (void *)0) {
|
if (sock != (void *)0) {
|
||||||
if (sock->tcp_sock.seq_number != htonl(packet->ack_number)) {
|
if (sock->tcp_sock.seq_number != htonl(packet->ack_number)) {
|
||||||
kprintf("Warning, dropping packet, Wrong Ack Expecting %d Got %d\n", sock->tcp_sock.seq_number, htonl(packet->ack_number));
|
kprintf("Warning, dropping packet, Wrong Ack Expecting %d Got %d\n", sock->tcp_sock.seq_number, htonl(packet->ack_number));
|
||||||
@ -97,7 +103,7 @@ void tcp_process_packet(struct ether_t *ether, unsigned int dest, struct tcp_hea
|
|||||||
if (htons(packet->flags) & TCP_FLAGS_FIN) {
|
if (htons(packet->flags) & TCP_FLAGS_FIN) {
|
||||||
sock->tcp_sock.ack_number = htonl(packet->seq_number) + dlen + 1;
|
sock->tcp_sock.ack_number = htonl(packet->seq_number) + dlen + 1;
|
||||||
tcp_send(ether, sock, TCP_FLAGS_ACK | TCP_FLAGS_FIN, (void *)0, 0);
|
tcp_send(ether, sock, TCP_FLAGS_ACK | TCP_FLAGS_FIN, (void *)0, 0);
|
||||||
socket_close(sock);
|
socket_doclose(sock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -129,7 +135,7 @@ void tcp_process_packet(struct ether_t *ether, unsigned int dest, struct tcp_hea
|
|||||||
if (htons(packet->flags) & TCP_FLAGS_FIN) {
|
if (htons(packet->flags) & TCP_FLAGS_FIN) {
|
||||||
sock->tcp_sock.ack_number = htonl(packet->seq_number) + dlen + 1;
|
sock->tcp_sock.ack_number = htonl(packet->seq_number) + dlen + 1;
|
||||||
tcp_send(ether, sock, TCP_FLAGS_ACK | TCP_FLAGS_FIN, (void *)0, 0);
|
tcp_send(ether, sock, TCP_FLAGS_ACK | TCP_FLAGS_FIN, (void *)0, 0);
|
||||||
socket_close(sock);
|
socket_doclose(sock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user