📄 xilsock.c
字号:
/* * Xilinx internal socket related functions */#include <net/xilsock.h>/* buffers for sending and receiving packets */unsigned char recvbuf[LINK_FRAME_LEN];unsigned char sendbuf[LINK_FRAME_LEN];unsigned char mb_ip_addr[IP_VERSION] = {0,0,0,0}; /* microblaze ip address , currently set to 127.0.0.0 */unsigned char mb_hw_addr[ETH_ADDR_LEN] = {0x00,0x60,0x08,0x11,0x27,0x7b}; /* microblaze hardware address */struct xilsock_socket xilsock_sockets[NO_OF_XILSOCKS];/* gives the status of the received packet */int xilsock_status_flag = 0;/* * Initialisation of xilsock_sockets */unsigned char is_xilsock_init = 0;int xilsock_init (void) { int i; if (!is_xilsock_init) { for (i = 0; i < NO_OF_XILSOCKS; i++) { xilsock_sockets[i].type = 0; xilsock_sockets[i].domain = 0; xilsock_sockets[i].proto = 0; xilsock_sockets[i].listen = 0; xilsock_sockets[i].bound = 0; xilsock_sockets[i].accept = 0; xilsock_sockets[i].connect = 0; xilsock_sockets[i].closing = 0; xilsock_sockets[i].closed = 0; xilsock_sockets[i].closed = 0; xilsock_sockets[i].free = 1; xilsock_sockets[i].conn.tcp_conn = NULL; xilsock_sockets[i].recvbuf.buf = NULL; xilsock_sockets[i].recvbuf.size = 0; } is_xilsock_init = 1; } return is_xilsock_init;}/* * Release a socket */void xilsock_rel_socket (int sd) { if (xilsock_sockets[sd].type == SOCK_STREAM) { xilsock_sockets[sd].conn.tcp_conn = NULL; } else { xilsock_sockets[sd].conn.udp_conn = NULL; } xilsock_sockets[sd].type = 0; xilsock_sockets[sd].domain = 0; xilsock_sockets[sd].proto = 0; xilsock_sockets[sd].listen = 0; xilsock_sockets[sd].bound = 0; xilsock_sockets[sd].accept = 0; xilsock_sockets[sd].connect = 0; xilsock_sockets[sd].closing = 0; xilsock_sockets[sd].closed = 0; xilsock_sockets[sd].free = 1; xilsock_sockets[sd].recvbuf.buf = NULL; xilsock_sockets[sd].recvbuf.size = 0; }/* * Allocate a xilsock_socket and return socket descriptor * if not able to alloc socket, return -1 */int xilsock_socket(int domain, int type, int proto) { int sd; // find a free xilsock_socket if (!xilsock_init()) return (-1); for (sd = 0; sd < NO_OF_XILSOCKS; sd++) { if (xilsock_sockets[sd].free) { // initialise the socket & make it unavailable xilsock_sockets[sd].domain = domain; xilsock_sockets[sd].type = type; xilsock_sockets[sd].proto = proto; xilsock_sockets[sd].free = 0; return sd; } } // return as no sockets available return -1;}/* * bind a socket to the specified address. * binds addr to socket sd. returns 1 if bound * returns -1 if not able to bind */int xilsock_bind(int sd, struct sockaddr* addr, int addrlen) { int connd; // open a tcp conn/udp conn if (xilsock_sockets[sd].type == SOCK_STREAM) { if ( (connd = xilnet_tcp_open_conn (((struct sockaddr_in*)addr)->sin_port)) == -1) { print("bind: tcp sockets not available \n"); xilsock_rel_socket(sd); return -1; } xilsock_sockets[sd].conn.tcp_conn = (xilnet_tcp_conns + connd); // update fd of tcp conn xilnet_tcp_conns[connd].fd = sd; } else if (xilsock_sockets[sd].type == SOCK_DGRAM) { if ( (connd = xilnet_udp_open_conn (((struct sockaddr_in*)addr)->sin_port)) == -1) { print("bind: udp sockets not available \n"); xilsock_rel_socket(sd); return -1; } xilsock_sockets[sd].conn.udp_conn = (xilnet_udp_conns + connd); // update fd of udp conn xilnet_udp_conns[connd].fd = sd; } return 1;}/* * listen on a socket * called from listen() */int xilsock_listen(int s, int backlog) { xilsock_sockets[s].listen = 1; return 1; }/* * accept a conn on the socket * if pkt for new conn, open new xilsock_socket, return 0 * if pkt for exisiting conn, return 0 */int xilsock_accept(int sd, struct sockaddr* addr, int *addrlen) { int n = 0; int nsd; int ns; struct xilnet_tcp_conn* new_conn; struct xilnet_tcp_conn* curr_conn; int connd; unsigned char *buf = recvbuf; // recvbuf is the array to recv messages int len = LINK_FRAME_LEN; // reset status flag xilsock_status_flag = 0; // check for tcp conn to execute this call if (xilsock_sockets[sd].type != SOCK_STREAM) { print("accept: not a tcp socket \n"); return -1; } // call eth recv. if return val is 1, new conn // create new file, socket with same properties // else no new conn., return -1 n = xilnet_eth_recv_frame(buf, len); if (n < 0) // not for any of the supported conns return -1; if ( n == XILSOCK_NEW_CONN) { // create a new socket nsd = xilsock_socket(xilsock_sockets[sd].domain, xilsock_sockets[sd].type, xilsock_sockets[sd].proto); if (nsd < 0) { print("xilsock sockets not available \n"); return (-1); } if ( (connd = xilnet_tcp_open_conn (xilsock_sockets[sd].conn.tcp_conn->src_port)) == -1) { print("accept: tcp sockets not available \n"); xilsock_rel_socket(nsd); return -1; } // copy the orig socket characteristics to new socket xilsock_sockets[nsd].type = xilsock_sockets[sd].type; xilsock_sockets[nsd].domain = xilsock_sockets[sd].domain; xilsock_sockets[nsd].proto = xilsock_sockets[sd].proto; xilsock_sockets[nsd].connect = 1; new_conn = xilsock_sockets[nsd].conn.tcp_conn = (xilnet_tcp_conns + connd); curr_conn = xilsock_sockets[sd].conn.tcp_conn; // update new tcp conn which starts listening new_conn->fd = nsd; new_conn->dst_ip[0] = xilsock_sockets[sd].conn.tcp_conn->dst_ip[0]; new_conn->dst_ip[1] = xilsock_sockets[sd].conn.tcp_conn->dst_ip[1]; new_conn->dst_ip[2] = xilsock_sockets[sd].conn.tcp_conn->dst_ip[2]; new_conn->dst_ip[3] = xilsock_sockets[sd].conn.tcp_conn->dst_ip[3]; new_conn->dst_port = xilsock_sockets[sd].conn.tcp_conn->dst_port; new_conn->seqno = curr_conn->seqno; new_conn->ack_seqno = curr_conn->ack_seqno; new_conn->exp_acknum = curr_conn->exp_acknum; new_conn->state = curr_conn->state; // reset the listening connection curr_conn->state = TCP_LISTEN; curr_conn->dst_ip[0] = 0; curr_conn->dst_ip[1] = 0; curr_conn->dst_ip[2] = 0; curr_conn->dst_ip[3] = 0; curr_conn->dst_port = 0; curr_conn->seqno = 0; curr_conn->ack_seqno = 0; curr_conn->exp_acknum = 0; xilsock_sockets[sd].listen = 1; // send a reply using new socket memset(sendbuf, 0, LINK_FRAME_LEN); xilnet_tcp_send_pkt(new_conn, (sendbuf + LINK_HDR_LEN + (IP_HDR_LEN*4)), 0, (TCP_SYN|TCP_ACK)); xilnet_ip_header(sendbuf+LINK_HDR_LEN,(IP_HDR_LEN*4)+(TCP_HDR_LEN*4), IP_PROTO_TCP, new_conn->dst_ip); xilnet_eth_send_frame(sendbuf,LINK_HDR_LEN+(IP_HDR_LEN*4)+(TCP_HDR_LEN*4), new_conn->dst_ip, 0, ETH_PROTO_IP); new_conn->exp_acknum += 1; // set status flag xilsock_status_flag |= XILSOCK_NEW_CONN; return nsd; } else if (n == XILSOCK_CLOSE_CONN) { int i; for ( i = 0; i < NO_OF_XILSOCKS; i++) { if (xilsock_sockets[i].closed) { // close conn if (xilsock_sockets[i].type == SOCK_STREAM) xilnet_tcp_close_conn(xilsock_sockets[i].conn.tcp_conn); else if (xilsock_sockets[i].type == SOCK_DGRAM) xilnet_udp_close_conn(xilsock_sockets[i].conn.udp_conn); // close the socket xilsock_rel_socket(i); // set status flag xilsock_status_flag |= XILSOCK_CLOSE_CONN; return -1; } } } // set status flag xilsock_status_flag |= n; return n; }/* * recv data on socket * called from recv() */int xilsock_recv(int s, unsigned char *buf, unsigned int len) { int n; int i; if (s > NO_OF_XILSOCKS) { print("recv: invalid socket descriptor \n"); exit(-1); } n = xilnet_eth_recv_frame(buf, len); for (i = 0; i < NO_OF_XILSOCKS; i++) { if (i == s) { break; } } if ( i >= NO_OF_XILSOCKS) { print("recv: no data \n"); return -1; } // return no of bytes recvd for this conn return xilsock_sockets[s].recvbuf.size; }/* * send data on socket * called from send() */int xilsock_send(int s, unsigned char* buf, unsigned int len) { struct xilnet_tcp_conn *conn; conn = xilsock_sockets[s].conn.tcp_conn; if (!conn) { print("send: no such socket \n"); return -1; }// memset(sendbuf, 0, LINK_FRAME_LEN);// memcpy(sendbuf+LINK_HDR_LEN+IP_HDR_LEN*4+(TCP_HDR_LEN*4), buf, len); xilnet_tcp_send_pkt(conn, buf+LINK_HDR_LEN+IP_HDR_LEN*4, len, TCP_ACK); xilnet_ip_header(buf+LINK_HDR_LEN, len+(TCP_HDR_LEN*4)+IP_HDR_LEN*4, IP_PROTO_TCP, conn->dst_ip);#if defined(_CONFIG_ETH_) xilnet_eth_send_frame(buf, len+(TCP_HDR_LEN*4)+IP_HDR_LEN*4+ETH_HDR_LEN, conn->dst_ip, NULL, ETH_PROTO_IP);#elif defined(_CONFIG_PPP_) // Call to PPP send packet function #elif defined(_CONFIG_HOST_APP_) send_to_jtag_uart(buf, len+(TCP_HDR_LEN*4)+IP_HDR_LEN*4);#endif return len; }/* * recvfrom socket * currently this is same as xilsock_recv * hence recvfrom is mapped to recv for now *//* * sendto socket * called from sendto() */int xilsock_sendto(int s, unsigned char* buf, unsigned int len) { struct xilnet_udp_conn *conn; conn = xilsock_sockets[s].conn.udp_conn; if (!conn) { print("sendto: no such socket \n"); return -1; } memset(sendbuf, 0, LINK_FRAME_LEN); memcpy(sendbuf+LINK_HDR_LEN+IP_HDR_LEN*4+UDP_HDR_LEN, buf, len); // calls to udp stack xilnet_udp_header(conn, sendbuf+LINK_HDR_LEN+IP_HDR_LEN*4, len+UDP_HDR_LEN); xilnet_ip_header(sendbuf+LINK_HDR_LEN, len+UDP_HDR_LEN+IP_HDR_LEN*4, IP_PROTO_UDP, conn->dst_ip);#if defined(_CONFIG_ETH_) xilnet_eth_send_frame(sendbuf, len+UDP_HDR_LEN+IP_HDR_LEN*4+ETH_HDR_LEN, conn->dst_ip, NULL, ETH_PROTO_IP);#elif defined(_CONFIG_PPP_) // Call to PPP send packet function #elif defined(_CONFIG_HOST_APP_) send_to_jtag_uart(sendbuf, len+UDP_HDR_LEN+IP_HDR_LEN*4);#endif return len;}/* * close socket */void xilsock_close(int s) { unsigned char flags = 0; unsigned short check = 0; unsigned char *tcp_reply; if (xilsock_sockets[s].type == SOCK_STREAM) { struct xilnet_tcp_conn *conn = xilsock_sockets[s].conn.tcp_conn; // construct the FIN and wait for ack & FIN from client flags = (TCP_FIN | TCP_ACK); ((struct xilnet_tcp_conn*)conn)->state = TCP_FIN_WAIT1; memset(sendbuf, 0, LINK_FRAME_LEN); tcp_reply = sendbuf+ETH_HDR_LEN+(IP_HDR_LEN*4); xilnet_tcp_header(((struct xilnet_tcp_conn*)conn), tcp_reply, 1, flags); // calculate tcp checksum check = xilnet_udp_tcp_calc_chksum(tcp_reply, (TCP_HDR_LEN*4), mb_ip_addr, ((struct xilnet_tcp_conn*)conn)->dst_ip, IP_PROTO_TCP); tcp_reply[TCP_CHECK_OFF] = (check & 0xff00) >> 8; tcp_reply[TCP_CHECK_OFF+1] = (check & 0x00ff); xilnet_ip_header(sendbuf+ETH_HDR_LEN,(IP_HDR_LEN*4)+(TCP_HDR_LEN*4), IP_PROTO_TCP, ((struct xilnet_tcp_conn*)conn)->dst_ip); xilnet_eth_send_frame(sendbuf, (TCP_HDR_LEN*4)+(IP_HDR_LEN*4)+ETH_HDR_LEN, ((struct xilnet_tcp_conn*)conn)->dst_ip, NULL, ETH_PROTO_IP); } else if (xilsock_sockets[s].type == SOCK_DGRAM) { xilnet_udp_close_conn(xilsock_sockets[s].conn.udp_conn); // close the socket xilsock_rel_socket(s); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -