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;
38 Init_Ne2k(&Packet_Received);
43 static int allocate_socket_fd() {
46 for (i = 0; i < MAX_SOCKS; i++) {
47 if (sockets[i].in_use == 0) {
48 sockets[i].in_use = 1;
49 sockets[i].send_buf = create_ring_buffer(BUF_SIZE);
50 if (sockets[i].send_buf == NULL)
52 sockets[i].recv_buf = create_ring_buffer(BUF_SIZE);
53 if (sockets[i].recv_buf == NULL){
54 free_ring_buffer(sockets[i].send_buf);
64 static int release_socket_fd(int sockfd){
65 if (sockfd >= 0 && sockfd < MAX_SOCKS){
66 sockets[sockfd].in_use = 0;
67 free_ring_buffer(sockets[sockfd].send_buf);
68 free_ring_buffer(sockets[sockfd].recv_buf);
69 sockets[sockfd].send_buf = NULL;
70 sockets[sockfd].recv_buf = NULL;
77 struct socket * get_socket_from_fd(int fd) {
78 return &(sockets[fd]);
82 int connect(const uchar_t ip_addr[4], ushort_t port) {
84 sockfd = allocate_socket_fd();
91 uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
93 sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port));
95 if (sockets[sockfd].con == NULL){
96 release_socket_fd(sockfd);
103 int recv(int sockfd, void * buf, uint_t len){
106 struct socket *sock = get_socket_from_fd(sockfd);
108 // here we need some lock mechnism, just disable interrupt may not work properly because recv() will be run as a kernel thread
110 recvlen = rb_read(sock->recv_buf, buf, len);
113 Wait(&(sock->recv_wait_queue));
120 void timer_int_Handler(struct Interrupt_State * state){
122 //handle the periodic calls of uIP
123 for(i = 0; i < UIP_CONNS; ++i) {
126 //devicedriver_send();
127 NE2K_Transmit(uip_len);
130 for(i = 0; i < UIP_UDP_CONNS; i++) {
133 //devicedriver_send();
134 NE2K_Transmit(uip_len);
139 // a series of utilities to handle conncetion states
140 static void connected(int sockfd){
144 static void closed(int sockfd){
148 static void acked(int sockfd){
152 static void newdata(int sockfd){
159 dataptr = (char *)uip_appdata;
164 sock = get_socket_from_fd(sockfd);
166 wrlen = rb_write(sock->recv_buf, dataptr, len);
168 if (wrlen < len){ //write error, what should I do?
172 Wake_Up(&(sock->recv_wait_queue));
180 senddata(int sockfd){
181 struct socket * sock = get_socket_from_fd(sockfd);
183 int pending_bytes = rb_data_len(sock->send_buf);
184 int len = (mss < pending_bytes) ? mss: pending_bytes;
186 uchar_t * send_buf = uip_appdata;
188 bytes_read = rb_peek(sock->send_buf, send_buf, len);
190 if (bytes_read == 0) {
191 // no packet for send
195 uip_send(send_buf, len);
200 //get the socket id by the local tcp port
201 static int get_socket_from_port(ushort_t lport) {
204 for (i = 0; i<MAX_SOCKS; i++){
205 if (sockets[i].con->lport == lport)
218 sockfd = get_socket_from_port(uip_conn->lport);
220 if (sockfd == -1) return;
222 if(uip_connected()) {
226 if(uip_closed() ||uip_aborted() ||uip_timedout()) {
250 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt)
252 uip_len = info->size;
254 // for (i = 0; i < info->size; i++) {
255 // uip_buf[i] = *(pkt + i);
258 memcpy(uip_buf, pkt, uip_len);
260 if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
263 //ethernet_devicedriver_send();
264 NE2K_Transmit(uip_len);
271 //ethernet_devicedriver_send();
272 NE2K_Transmit(uip_len);