1 #include "syshdrs.h" 2 3 #ifndef INADDR_ANY 4 # define INADDR_ANY ((unsigned long int) 0x00000000) 5 #endif 6 7 #ifndef INADDR_NONE 8 # define INADDR_NONE ((unsigned long int) 0xffffffff) 9 #endif 10 11 /* Linux libc 5.3.x has a bug that causes isalnum() to not work! */ 12 #define ISALNUM(c) ( (((c) >= 'A') && ((c) <= 'Z')) || (((c) >= 'a') && ((c) <= 'z')) || (((c) >= '0') && ((c) <= '9')) ) 13 14 static unsigned int 15 ServiceNameToPortNumber(const char *const s) 16 { 17 char str[64]; 18 char *cp; 19 struct servent *sp; 20 21 strncpy(str, s, sizeof(str) - 1); 22 str[sizeof(str) - 1] = '\0'; 23 cp = str; 24 if (isdigit(*cp)) { 25 while (isdigit(*cp)) 26 cp++; 27 *cp = '\0'; 28 return (atoi(str)); 29 } 30 for (;; cp++) { 31 if ((*cp == '\0') 32 || ((!ISALNUM(*cp)) && (*cp != '-') && (*cp != '_'))) 33 break; 34 } 35 *cp = '\0'; 36 37 sp = getservbyname(str, "tcp"); 38 if (sp != NULL) { 39 /* endservent(); */ 40 return ((unsigned int) ntohs((unsigned short) sp->s_port)); 41 } 42 sp = getservbyname(str, "udp"); 43 if (sp != NULL) { 44 /* endservent(); */ 45 return ((unsigned int) ntohs((unsigned short) sp->s_port)); 46 } 47 return (0); /* error */ 48 } /* ServiceNameToPortNumber */ 49 50 51 52 53 int 54 AddrStrToAddr(const char * const s, struct sockaddr_in * const sa, const int defaultport) 55 { 56 char portstr[128]; 57 unsigned long ipnum; 58 unsigned int port; 59 struct hostent *hp; 60 char *hostcp, *atsign, *colon, *cp, *p2; 61 62 memset(sa, 0, sizeof(struct sockaddr_in)); 63 strncpy(portstr, s, sizeof(portstr)); 64 portstr[sizeof(portstr) - 1] = '\0'; 65 66 if ((colon = strchr(portstr, ':')) != NULL) { 67 /* Does it look like a URL? http://host ? */ 68 if ((colon[1] == '/') && (colon[2] == '/')) { 69 *colon = '\0'; 70 port = 0; 71 hostcp = colon + 3; 72 for (cp = hostcp; *cp != '\0'; cp++) { 73 if ((!ISALNUM(*cp)) && (*cp != '.')) { 74 /* http://host:port */ 75 if ((*cp == ':') && (isdigit(cp[1]))) { 76 *cp++ = '\0'; 77 p2 = cp; 78 while (isdigit(*cp)) 79 cp++; 80 *cp = '\0'; 81 port = atoi(p2); 82 } 83 *cp = '\0'; 84 break; 85 } 86 } 87 if (port == 0) 88 port = ServiceNameToPortNumber(portstr); 89 } else { 90 /* Look for host.name.domain:port */ 91 *colon = '\0'; 92 hostcp = portstr; 93 port = (unsigned int) atoi(colon + 1); 94 } 95 } else if ((atsign = strchr(portstr, '@')) != NULL) { 96 /* Look for port@host.name.domain */ 97 *atsign = '\0'; 98 hostcp = atsign + 1; 99 port = (unsigned int) atoi(portstr); 100 } else if (defaultport > 0) { 101 /* Have just host.name.domain, use that w/ default port. */ 102 port = (unsigned int) defaultport; 103 hostcp = portstr; 104 } else { 105 /* If defaultport <= 0, they must supply a port number 106 * in the host/port string. 107 */ 108 errno = EADDRNOTAVAIL; 109 return (kAddrStrToAddrMiscErr); 110 } 111 112 sa->sin_port = htons((short) port); 113 114 ipnum = inet_addr(hostcp); 115 if (ipnum != INADDR_NONE) { 116 sa->sin_family = AF_INET; 117 sa->sin_addr.s_addr = ipnum; 118 } else { 119 errno = 0; 120 hp = gethostbyname(hostcp); 121 if (hp == NULL) { 122 if (errno == 0) 123 errno = ENOENT; 124 return (kAddrStrToAddrBadHost); 125 } 126 sa->sin_family = hp->h_addrtype; 127 memcpy(&sa->sin_addr.s_addr, hp->h_addr_list[0], 128 (size_t) hp->h_length); 129 } 130 return (0); 131 } /* AddrStrToAddr */ 132 133 134 135 char * 136 AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr_in * const saddrp, int dns, const char *fmt) 137 { 138 const char *addrNamePtr; 139 struct hostent *hp; 140 char str[128]; 141 char *dlim, *dp; 142 const char *cp; 143 struct servent *pp; 144 145 if (dns == 0) { 146 addrNamePtr = inet_ntoa(saddrp->sin_addr); 147 } else { 148 hp = gethostbyaddr((char *) &saddrp->sin_addr, (int) sizeof(struct in_addr), AF_INET); 149 if ((hp != NULL) && (hp->h_name != NULL) && (hp->h_name[0] != '\0')) { 150 addrNamePtr = hp->h_name; 151 } else { 152 addrNamePtr = inet_ntoa(saddrp->sin_addr); 153 } 154 } 155 if (fmt == NULL) 156 fmt = "%h:%p"; 157 for (dp = dst, dlim = dp + dsize - 1; ; fmt++) { 158 if (*fmt == '\0') { 159 break; /* done */ 160 } else if (*fmt == '%') { 161 fmt++; 162 if (*fmt == '%') { 163 if (dp < dlim) 164 *dp++ = '%'; 165 } else if (*fmt == 'p') { 166 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port)); 167 for (cp = str; *cp != '\0'; cp++) 168 if (dp < dlim) 169 *dp++ = *cp; 170 *dp = '\0'; 171 } else if (*fmt == 'h') { 172 if (addrNamePtr != NULL) { 173 cp = addrNamePtr; 174 } else { 175 cp = "unknown"; 176 } 177 for ( ; *cp != '\0'; cp++) 178 if (dp < dlim) 179 *dp++ = *cp; 180 *dp = '\0'; 181 } else if (*fmt == 's') { 182 pp = getservbyport((int) (saddrp->sin_port), "tcp"); 183 if (pp == NULL) 184 pp = getservbyport((int) (saddrp->sin_port), "udp"); 185 if (pp == NULL) { 186 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port)); 187 cp = str; 188 } else { 189 cp = pp->s_name; 190 } 191 for ( ; *cp != '\0'; cp++) 192 if (dp < dlim) 193 *dp++ = *cp; 194 /* endservent(); */ 195 *dp = '\0'; 196 } else if ((*fmt == 't') || (*fmt == 'u')) { 197 pp = getservbyport((int) (saddrp->sin_port), (*fmt == 'u') ? "udp" : "tcp"); 198 if (pp == NULL) { 199 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port)); 200 cp = str; 201 } else { 202 cp = pp->s_name; 203 } 204 for ( ; *cp != '\0'; cp++) 205 if (dp < dlim) 206 *dp++ = *cp; 207 /* endservent(); */ 208 *dp = '\0'; 209 } else if (*fmt == '\0') { 210 break; 211 } else { 212 if (dp < dlim) 213 *dp++ = *fmt; 214 } 215 } else if (dp < dlim) { 216 *dp++ = *fmt; 217 } 218 } 219 *dp = '\0'; 220 return (dst); 221 } /* AddrToAddrStr */ 222