1 #include <geekos/socket.h>
2 #include <geekos/malloc.h>
3 #include <palacios/vmm_types.h>
4 #include <geekos/ne2k.h>
6 #include <uip/uip_arp.h>
7 #include <geekos/vmm_stubs.h>
12 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
14 #define MAX_SOCKS 1024
17 struct socket sockets[MAX_SOCKS];
19 extern void* memcpy(void *dst, const void* src, int n);
22 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt);
27 for (i = 0; i < MAX_SOCKS; i++) {
28 sockets[i].in_use = 0;
29 sockets[i].send_buf = NULL;
30 sockets[i].recv_buf = NULL;
39 Init_Ne2k(&Packet_Received);
45 static int allocate_socket_fd() {
48 for (i = 0; i < MAX_SOCKS; i++) {
49 if (sockets[i].in_use == 0) {
50 sockets[i].in_use = 1;
51 sockets[i].send_buf = create_ring_buffer(BUF_SIZE);
52 if (sockets[i].send_buf == NULL)
54 sockets[i].recv_buf = create_ring_buffer(BUF_SIZE);
55 if (sockets[i].recv_buf == NULL){
56 free_ring_buffer(sockets[i].send_buf);
66 static int release_socket_fd(int sockfd){
67 if (sockfd >= 0 && sockfd < MAX_SOCKS){
68 sockets[sockfd].in_use = 0;
69 free_ring_buffer(sockets[sockfd].send_buf);
70 free_ring_buffer(sockets[sockfd].recv_buf);
71 sockets[sockfd].send_buf = NULL;
72 sockets[sockfd].recv_buf = NULL;
79 struct socket * get_socket_from_fd(int fd) {
80 return &(sockets[fd]);
84 int connect(const uchar_t ip_addr[4], ushort_t port) {
86 sockfd = allocate_socket_fd();
93 uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
95 sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port));
98 if (sockets[sockfd].con == NULL){
99 release_socket_fd(sockfd);
106 int recv(int sockfd, void * buf, uint_t len){
109 struct socket *sock = get_socket_from_fd(sockfd);
112 // here we need some lock mechnism, just disable interrupt may not work properly because recv() will be run as a kernel thread
114 recvlen = rb_read(sock->recv_buf, buf, len);
117 Wait(&(sock->recv_wait_queue));
124 void timer_int_Handler(struct Interrupt_State * state){
126 //handle the periodic calls of uIP
127 for(i = 0; i < UIP_CONNS; ++i) {
130 //devicedriver_send();
131 NE2K_Transmit(uip_len);
134 for(i = 0; i < UIP_UDP_CONNS; i++) {
137 //devicedriver_send();
138 NE2K_Transmit(uip_len);
143 // a series of utilities to handle conncetion states
144 static void connected(int sockfd){
148 static void closed(int sockfd){
152 static void acked(int sockfd){
156 static void newdata(int sockfd){
163 dataptr = (char *)uip_appdata;
168 sock = get_socket_from_fd(sockfd);
170 wrlen = rb_write(sock->recv_buf, dataptr, len);
172 if (wrlen < len){ //write error, what should I do?
176 Wake_Up(&(sock->recv_wait_queue));
184 senddata(int sockfd){
185 struct socket * sock = get_socket_from_fd(sockfd);
187 int pending_bytes = rb_data_len(sock->send_buf);
188 int len = (mss < pending_bytes) ? mss: pending_bytes;
190 uchar_t * send_buf = uip_appdata;
192 bytes_read = rb_peek(sock->send_buf, send_buf, len);
194 if (bytes_read == 0) {
195 // no packet for send
199 uip_send(send_buf, len);
204 //get the socket id by the local tcp port
205 static int get_socket_from_port(ushort_t lport) {
209 for (i = 0; i < MAX_SOCKS; i++){
210 if (sockets[i].con->lport == lport) {
220 void socket_appcall(void) {
224 sockfd = get_socket_from_port(uip_conn->lport);
231 if (uip_connected()) {
236 if (uip_closed() ||uip_aborted() ||uip_timedout()) {
261 int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) {
264 uip_len = info->size;
266 // for (i = 0; i < info->size; i++) {
267 // uip_buf[i] = *(pkt + i);
270 memcpy(uip_buf, pkt, uip_len);
275 if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
279 NE2K_Transmit(uip_len);
289 NE2K_Transmit(uip_len);