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   uip_ipaddr_t ipaddr;
71
72   sockfd = allocate_socket_fd();
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
94   for(i = 0; i < UIP_CONNS; ++i) {
95     uip_periodic(i);
96
97     if(uip_len > 0) {
98       NE2K_Transmit(uip_len);
99     }
100   }
101
102
103   for(i = 0; i < UIP_UDP_CONNS; i++) {
104     uip_udp_periodic(i);
105
106     if(uip_len > 0) {
107       NE2K_Transmit(uip_len);
108     }
109   }
110 }
111
112 // a series of utilities to handle conncetion states
113 static void connected(int sockfd){
114
115 }
116
117 static void closed(int sockfd){
118
119 }
120
121 static void acked(int sockfd){
122
123 }
124
125 static void newdata(int sockfd){
126
127 }
128
129 // not finished yet
130 static void
131 senddata(int sockfd){
132   /*uchar_t *bufptr;
133     int len = 0;
134     addr_t pkt;
135     
136     struct sockets *sock = get_socket_from_fd(sockfd);
137     
138     pkt = dequeue(sock->send_queue);
139     if (pkt == 0)  // no packet for send
140     return;
141     
142     bufptr = uip_appdata;
143     
144     if(len < uip_mss()) {
145     // memcpy(bufptr, data, len);
146     } else {
147     
148     }*/
149   //uip_send(uip_appdata,len);
150 }
151
152
153
154 //get the socket id by the local tcp port
155 static int  get_socket_from_port(ushort_t lport) {
156   int i;
157   
158   for (i = 0; i < MAX_SOCKS; i++){
159     if (sockets[i].con->lport == lport) 
160       return i;
161   }
162   
163   return -1;
164 }
165
166
167
168
169 void
170 socket_appcall(void)
171 {
172   int sockfd; 
173
174   sockfd = get_socket_from_port(uip_conn->lport);
175
176   if (sockfd == -1) {
177     return;
178   }
179
180   if(uip_connected()) {
181     connected(sockfd);
182   }
183   
184   if(uip_closed() ||uip_aborted() ||uip_timedout()) {
185      closed(sockfd);
186      return;
187   }
188   
189   if(uip_acked()) {
190      acked(sockfd);
191   }
192   
193   if(uip_newdata()) {
194      newdata(sockfd);
195   }
196   
197   if(uip_rexmit() ||
198      uip_newdata() ||
199      uip_acked() ||
200      uip_connected() ||
201      uip_poll()) {
202      senddata(sockfd);
203   }
204 }
205
206
207
208 int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) {
209   int i;
210   
211   uip_len = info->size; 
212
213   for (i = 0; i < info->size; i++) {
214     uip_buf[i] = *(pkt+i);
215   }
216
217   Free(pkt);
218
219   if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
220     uip_arp_arpin();
221
222     if (uip_len > 0) {
223       NE2K_Transmit(uip_len);
224     }                                   
225
226   } else {
227
228     uip_arp_ipin();
229     uip_input();
230
231     if (uip_len > 0) {
232       uip_arp_out();
233       NE2K_Transmit(uip_len);
234     }
235   }                       
236   return 0;
237 }