Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


*** empty log message ***
[palacios.git] / palacios / src / geekos / socket.c
1 #include <geekos/socket.h>
2 #include <geekos/malloc.h>
3 #include <palacios/vmm_types.h>
4 #include <geekos/ne2k.h>
5 #include <uip/uip.h>
6 #include <uip/uip_arp.h>
7 #include <geekos/int.h>
8 #include <geekos/vmm_stubs.h>
9 #include <geekos/queue.h>
10
11 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
12
13 #define MAX_SOCKS 1024
14
15 struct socket sockets[MAX_SOCKS];
16
17
18 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) ;
19
20 void init_network() {
21    int i = 0;
22    
23    for (i = 0; i < MAX_SOCKS; i++) {
24      sockets[i].in_use = 0;
25      init_queue(&(sockets[i].send_queue));
26      init_queue(&(sockets[i].recv_queue));
27    }
28    
29    //initiate uIP
30    uip_init();
31    uip_arp_init();
32    
33    // set up interrupt handler
34    // set up device driver
35    
36    Init_Ne2k(&Packet_Received);
37    
38    
39 }
40
41 static int allocate_socket_fd() {
42   int i = 0;
43   
44   for (i = 0; i < MAX_SOCKS; i++) {
45     if (sockets[i].in_use == 0) {
46       sockets[i].in_use = 1;
47       return i;
48     }
49   }
50
51   return -1;
52 }
53
54 static int release_socket_fd(int sockfd){
55   if ((sockfd >= 0) && (sockfd < MAX_SOCKS)) {
56     sockets[sockfd].in_use = 0;
57   }
58   
59   return 0;
60 }
61
62
63 struct socket * get_socket_from_fd(int fd) {
64   return &(sockets[fd]);
65 }
66
67
68 int connect(const uchar_t ip_addr[4], ushort_t port) {
69   int sockfd = -1;
70   sockfd = allocate_socket_fd();
71   uip_ipaddr_t ipaddr;
72   
73   if (sockfd == -1) {
74     return -1;
75   }
76
77   uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);  
78   
79   sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port));
80
81   if (sockets[sockfd].con == NULL){
82     release_socket_fd(sockfd);
83     return -1;
84   }
85
86   return sockfd;
87 }
88
89
90 void timer_int_Handler(struct Interrupt_State * state){
91   int i;
92   //handle the periodic calls of uIP
93   for(i = 0; i < UIP_CONNS; ++i) {
94     uip_periodic(i);
95     if(uip_len > 0) {
96       //devicedriver_send();
97       NE2K_Transmit(uip_len);
98     }
99   }
100   for(i = 0; i < UIP_UDP_CONNS; i++) {
101     uip_udp_periodic(i);
102     if(uip_len > 0) {
103       //devicedriver_send();
104       NE2K_Transmit(uip_len);
105     }
106   }
107 }
108
109 // a series of utilities to handle conncetion states
110 static void connected(int sockfd){
111
112 }
113
114 static void closed(int sockfd){
115
116 }
117
118 static void acked(int sockfd){
119
120 }
121
122 static void newdata(int sockfd){
123
124 }
125
126 // not finished yet
127 static void
128 senddata(int sockfd){
129   /*uchar_t *bufptr;
130     int len = 0;
131     addr_t pkt;
132     
133     struct sockets *sock = get_socket_from_fd(sockfd);
134     
135     pkt = dequeue(sock->send_queue);
136     if (pkt == 0)  // no packet for send
137     return;
138     
139     bufptr = uip_appdata;
140     
141     if(len < uip_mss()) {
142     // memcpy(bufptr, data, len);
143     } else {
144     
145     }*/
146   //uip_send(uip_appdata,len);
147 }
148
149
150
151 //get the socket id by the local tcp port
152 static int  get_socket_from_port(ushort_t lport) {
153   int i;
154   
155   for (i = 0; i<MAX_SOCKS; i++){
156     if (sockets[i].con->lport == lport) 
157       return i;
158   }
159   
160   return -1;
161 }
162
163
164
165
166 void
167 socket_appcall(void)
168 {
169   int sockfd; 
170
171   sockfd = get_socket_from_port(uip_conn->lport);
172
173   if (sockfd == -1) return;
174     
175   if(uip_connected()) {
176         connected(sockfd);
177   }
178   
179   if(uip_closed() ||uip_aborted() ||uip_timedout()) {
180      closed(sockfd);
181      return;
182   }
183   
184   if(uip_acked()) {
185      acked(sockfd);
186   }
187   
188   if(uip_newdata()) {
189      newdata(sockfd);
190   }
191   
192   if(uip_rexmit() ||
193      uip_newdata() ||
194      uip_acked() ||
195      uip_connected() ||
196      uip_poll()) {
197      senddata(sockfd);
198   }
199 }
200
201
202
203 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) {
204   int i;
205   
206   uip_len = info->size; 
207   for(i = 0; i < info->size; i++) {
208     uip_buf[i] = *(pkt+i);
209   }
210   Free(pkt);
211   if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
212     uip_arp_arpin();
213     if (uip_len > 0){
214       //ethernet_devicedriver_send();
215       NE2K_Transmit(uip_len);
216     }                                   
217   } else {
218     uip_arp_ipin();
219     uip_input();
220     if(uip_len > 0) {
221       uip_arp_out();
222       //ethernet_devicedriver_send();
223       NE2K_Transmit(uip_len);
224     }
225   }                       
226   return 0;
227 }