socintf.c (2242B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * The part of PCID that interfaces to sockets 8 * 9 * Requires: 10 * Socket library 11 * Verinet functions (write_command, etc) 12 * pli_getreg_service 13 * pli_setreg_service 14 * 15 * 16 * Provides: 17 * pcid_setup_socket 18 * pcid_wait_for_cnxn 19 * pcid_process_request 20 */ 21 22 #include <unistd.h> 23 #include <stdlib.h> 24 #include <errno.h> 25 26 #include <netinet/in.h> 27 #include <arpa/inet.h> 28 #include <memory.h> 29 30 #include <sys/types.h> 31 #include <sys/socket.h> 32 #include <sys/time.h> 33 34 #include "pcid.h" 35 #include "mem.h" 36 #include "cmicsim.h" 37 #include "dma.h" 38 #include "pli.h" 39 40 int 41 pcid_setup_socket(int port) 42 { 43 struct sockaddr_in serv_addr; 44 int i; 45 int sockfd; 46 47 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 48 49 perror("server: can't open stream socket"); 50 exit(1); 51 } 52 53 /* 54 * Set socket option to reuse local address. This is supposed 55 * to have the effect of freeing up the local address. 56 */ 57 58 i = 1; 59 if (setsockopt(sockfd, SOL_SOCKET, 60 SO_REUSEADDR, (char *) &i, 4) < 0) { 61 perror("setsockopt"); 62 } 63 64 /* 65 * Set up server address... 66 */ 67 68 memset((void *) &serv_addr,0x0, sizeof(serv_addr)); 69 serv_addr.sin_family = AF_INET; 70 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 71 serv_addr.sin_port = htons(port); 72 73 /* 74 * Bind our local address & port 75 */ 76 77 if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 78 perror("server: can't bind local address"); 79 exit(1); 80 } 81 82 /* 83 * Only process one connection at a time. 84 */ 85 86 listen(sockfd, 1); 87 88 return sockfd; 89 } 90 91 int pcid_wait_for_cnxn(int sockfd) 92 { 93 struct sockaddr_in cli_addr; 94 socklen_t clilen; 95 int newsockfd; 96 97 for (;;) { 98 clilen = sizeof(cli_addr); 99 newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 100 101 if (newsockfd >= 0) { 102 break; 103 } 104 105 if (errno != EINTR) { 106 perror("accept"); 107 exit(1); 108 } 109 } 110 111 return newsockfd; 112 } 113 114 void pcid_close_cnxn(int sockfd) 115 { 116 close(sockfd); 117 } 118