Changeset 15293 in vbox for trunk/src/VBox/Devices/Network/slirp
- Timestamp:
- Dec 11, 2008 9:14:05 AM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/bootp.c
r15207 r15293 307 307 *q++ = RFC1533_END; 308 308 309 m->m_len = sizeof(struct bootp_t) - 310 sizeof(struct ip) - sizeof(struct udphdr); 309 m->m_len = sizeof(struct bootp_t) 310 - sizeof(struct ip) 311 - sizeof(struct udphdr); 311 312 /* Reply to the broadcast address, as some clients perform paranoid checks. */ 312 313 daddr.sin_addr.s_addr = INADDR_BROADCAST; -
trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
r15241 r15293 176 176 } 177 177 } 178 /* fall through */ 179 178 180 /* 179 181 * for TCP and UDP logic little bit reverted, we try to find the HOST socket … … 187 189 laddr.s_addr = ip->ip_src.s_addr; 188 190 lport = udp->uh_sport; 191 /* fall through */ 192 189 193 case IPPROTO_TCP: 190 194 if (head_socket == NULL) … … 199 203 for (so = head_socket; so != head_socket; so = so->so_next) 200 204 { 201 /* Should be reaplaced by hash here */ 202 if (so->so_faddr.s_addr == faddr.s_addr 203 && so->so_fport == fport 204 && so->so_hladdr.s_addr == laddr.s_addr 205 && so->so_hlport == lport) { 206 icm = malloc(sizeof(struct icmp_msg)); 207 icm->im_m = so->so_m; 208 found = 1; 209 } 205 /* Should be reaplaced by hash here */ 206 if ( so->so_faddr.s_addr == faddr.s_addr 207 && so->so_fport == fport 208 && so->so_hladdr.s_addr == laddr.s_addr 209 && so->so_hlport == lport) 210 { 211 icm = malloc(sizeof(struct icmp_msg)); 212 icm->im_m = so->so_m; 213 found = 1; 214 } 210 215 } 211 216 break; 217 212 218 default: 213 219 LogRel(("%s:ICMP: unsupported protocol(%d)\n", __FUNCTION__, ip->ip_p)); … … 229 235 icm->im_m = m; 230 236 LIST_INSERT_HEAD(&pData->icmp_msg_head, icm, im_list); 231 return (0);237 return 0; 232 238 } 233 239 #endif /* VBOX_WITH_SLIRP_ICMP */ … … 240 246 { 241 247 register struct icmp *icp; 242 register struct ip *ip =mtod(m, struct ip *);243 int icmplen =ip->ip_len;248 register struct ip *ip = mtod(m, struct ip *); 249 int icmplen = ip->ip_len; 244 250 int status; 245 251 uint32_t dst; … … 466 472 467 473 #define ICMP_MAXDATALEN (IP_MSS-28) 468 void icmp_error(PNATState pData, struct mbuf *msrc, u_char type, u_char code, int minsize, c har *message)474 void icmp_error(PNATState pData, struct mbuf *msrc, u_char type, u_char code, int minsize, const char *message) 469 475 { 470 476 unsigned hlen, shlen, s_ip_len; … … 496 502 goto end_error; /* Only reply to fragment 0 */ 497 503 498 shlen =ip->ip_hl << 2;499 s_ip_len =ip->ip_len;504 shlen = ip->ip_hl << 2; 505 s_ip_len = ip->ip_len; 500 506 if (ip->ip_p == IPPROTO_ICMP) 501 507 { … … 510 516 511 517 /* make a copy */ 512 if (!(m =m_get(pData)))513 goto end_error; /* get mbuf */518 if (!(m = m_get(pData))) 519 goto end_error; /* get mbuf */ 514 520 { 515 521 int new_m_size; … … 519 525 } 520 526 memcpy(m->m_data, msrc->m_data, msrc->m_len); 521 m->m_len = msrc->m_len; 527 m->m_len = msrc->m_len; /* copy msrc to m */ 522 528 523 529 /* make the header of the reply packet */ 524 530 ip = mtod(m, struct ip *); 525 hlen = sizeof(struct ip ); /* no options in reply */531 hlen = sizeof(struct ip ); /* no options in reply */ 526 532 527 533 /* fill in icmp */ … … 532 538 533 539 if (minsize) 534 s_ip_len =shlen+ICMP_MINLEN;/* return header+8b only */535 else if (s_ip_len >ICMP_MAXDATALEN)/* maximum size */536 s_ip_len =ICMP_MAXDATALEN;537 538 m->m_len =ICMP_MINLEN+s_ip_len;/* 8 bytes ICMP header */540 s_ip_len = shlen+ICMP_MINLEN; /* return header+8b only */ 541 else if (s_ip_len > ICMP_MAXDATALEN) /* maximum size */ 542 s_ip_len = ICMP_MAXDATALEN; 543 544 m->m_len = ICMP_MINLEN + s_ip_len; /* 8 bytes ICMP header */ 539 545 540 546 /* min. size = 8+sizeof(struct ip)+8 */ … … 556 562 int message_len; 557 563 char *cpnt; 558 message_len=strlen(message); 559 if (message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN; 560 cpnt=(char *)m->m_data+m->m_len; 564 message_len = strlen(message); 565 if (message_len > ICMP_MAXDATALEN) 566 message_len = ICMP_MAXDATALEN; 567 cpnt = (char *)m->m_data+m->m_len; 561 568 memcpy(cpnt, message, message_len); 562 m->m_len +=message_len;569 m->m_len += message_len; 563 570 } 564 571 #endif … … 574 581 ip->ip_len = m->m_len; 575 582 576 ip->ip_tos =((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */583 ip->ip_tos = ((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ 577 584 578 585 ip->ip_ttl = MAXTTL; -
trunk/src/VBox/Devices/Network/slirp/ip_icmp.h
r15054 r15293 170 170 171 171 void icmp_input _P((PNATState, struct mbuf *, int)); 172 void icmp_error _P((PNATState, struct mbuf *, u_char, u_char, int, c har *));172 void icmp_error _P((PNATState, struct mbuf *, u_char, u_char, int, const char *)); 173 173 void icmp_reflect _P((PNATState, struct mbuf *)); 174 174 -
trunk/src/VBox/Devices/Network/slirp/sbuf.c
r14964 r15293 146 146 { 147 147 n = sb->sb_rptr - sb->sb_wptr; 148 if (n > len) n = len; 148 if (n > len) 149 n = len; 149 150 memcpy(sb->sb_wptr, m->m_data, n); 150 151 } … … 153 154 /* Do the right edge first */ 154 155 n = sb->sb_data + sb->sb_datalen - sb->sb_wptr; 155 if (n > len) n = len; 156 if (n > len) 157 n = len; 156 158 memcpy(sb->sb_wptr, m->m_data, n); 157 159 len -= n; … … 189 191 if (from < sb->sb_wptr) 190 192 { 191 if (len > sb->sb_cc) len = sb->sb_cc; 193 if (len > sb->sb_cc) 194 len = sb->sb_cc; 192 195 memcpy(to,from,len); 193 196 } … … 196 199 /* re-use off */ 197 200 off = (sb->sb_data + sb->sb_datalen) - from; 198 if (off > len) off = len; 201 if (off > len) 202 off = len; 199 203 memcpy(to,from,off); 200 204 len -= off; -
trunk/src/VBox/Devices/Network/slirp/socket.c
r15261 r15293 291 291 */ 292 292 len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; 293 if (len > so->so_urgc) len = so->so_urgc; 293 if (len > so->so_urgc) 294 len = so->so_urgc; 294 295 memcpy(buff, sb->sb_rptr, len); 295 296 so->so_urgc -= len; … … 481 482 if(m->m_len < 0) 482 483 { 483 u_char code =ICMP_UNREACH_PORT;484 u_char code = ICMP_UNREACH_PORT; 484 485 485 486 if (errno == EHOSTUNREACH) 486 code =ICMP_UNREACH_HOST;487 code = ICMP_UNREACH_HOST; 487 488 else if(errno == ENETUNREACH) 488 code =ICMP_UNREACH_NET;489 code = ICMP_UNREACH_NET; 489 490 490 491 DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); … … 837 838 /* according RFC 793 error messages required copy of initial IP header + 64 bit */ 838 839 memcpy(&icp->icmp_ip, ip_copy, old_ip_len); 839 ip->ip_tos =((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */840 ip->ip_tos = ((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ 840 841 } 841 842 … … 954 955 955 956 if (errno == EHOSTUNREACH) 956 code =ICMP_UNREACH_HOST;957 code = ICMP_UNREACH_HOST; 957 958 else if(errno == ENETUNREACH) 958 code =ICMP_UNREACH_NET;959 code = ICMP_UNREACH_NET; 959 960 960 961 DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", -
trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
r15074 r15293 151 151 m->m_len = sizeof (struct tcpiphdr); 152 152 tlen = 0; 153 #define xchg(a,b,type) { type t; t =a; a=b; b=t; }153 #define xchg(a,b,type) { type t; t = a; a = b; b = t; } 154 154 xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t); 155 155 xchg(ti->ti_dport, ti->ti_sport, u_int16_t); … … 409 409 int tcp_fconnect(PNATState pData, struct socket *so) 410 410 { 411 int ret =0;411 int ret = 0; 412 412 413 413 DEBUG_CALL("tcp_fconnect"); 414 414 DEBUG_ARG("so = %lx", (long )so); 415 415 416 if ((ret = so->s =socket(AF_INET,SOCK_STREAM,0)) >= 0)417 { 418 int opt, s =so->s;416 if ((ret = so->s = socket(AF_INET,SOCK_STREAM,0)) >= 0) 417 { 418 int opt, s = so->s; 419 419 struct sockaddr_in addr; 420 420 -
trunk/src/VBox/Devices/Network/slirp/udp.c
r15234 r15293 56 56 udp_init(PNATState pData) 57 57 { 58 59 58 udp_last_so = &udb; 59 udb.so_next = udb.so_prev = &udb; 60 60 } 61 61 … … 67 67 udp_input(PNATState pData, register struct mbuf *m, int iphlen) 68 68 { 69 register struct ip *ip; 70 register struct udphdr *uh; 71 /* struct mbuf *opts = 0;*/ 72 int len; 73 struct ip save_ip; 74 struct socket *so; 75 76 DEBUG_CALL("udp_input"); 77 DEBUG_ARG("m = %lx", (long)m); 78 DEBUG_ARG("iphlen = %d", iphlen); 79 80 udpstat.udps_ipackets++; 81 82 /* 83 * Strip IP options, if any; should skip this, 84 * make available to user, and use on returned packets, 85 * but we don't yet have a way to check the checksum 86 * with options still present. 87 */ 88 if(iphlen > sizeof(struct ip)) { 89 ip_stripoptions(m, (struct mbuf *)0); 90 iphlen = sizeof(struct ip); 91 } 92 93 /* 94 * Get IP and UDP header together in first mbuf. 95 */ 96 ip = mtod(m, struct ip *); 97 uh = (struct udphdr *)((caddr_t)ip + iphlen); 98 99 /* 100 * Make mbuf data length reflect UDP length. 101 * If not enough data to reflect UDP length, drop. 102 */ 103 len = ntohs((u_int16_t)uh->uh_ulen); 104 105 if (ip->ip_len != len) { 106 if (len > ip->ip_len) { 107 udpstat.udps_badlen++; 108 goto bad; 109 } 110 m_adj(m, len - ip->ip_len); 111 ip->ip_len = len; 112 } 113 114 /* 115 * Save a copy of the IP header in case we want restore it 116 * for sending an ICMP error message in response. 117 */ 118 save_ip = *ip; 119 save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ 120 121 /* 122 * Checksum extended UDP header and data. 123 */ 124 if (udpcksum && uh->uh_sum) { 125 #if !defined(VBOX_WITH_BSD_REASS) 126 ((struct ipovly *)ip)->ih_next = 0; 127 ((struct ipovly *)ip)->ih_prev = 0; 128 ((struct ipovly *)ip)->ih_x1 = 0; 129 #else 130 memset(((struct ipovly *)ip)->ih_x1, 0, 9); 131 #endif 132 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 133 /* keep uh_sum for ICMP reply 134 * uh->uh_sum = cksum(m, len + sizeof (struct ip)); 135 * if (uh->uh_sum) { 136 */ 137 if(cksum(m, len + sizeof(struct ip))) { 138 udpstat.udps_badsum++; 139 goto bad; 140 } 141 } 142 143 /* 144 * handle DHCP/BOOTP 145 */ 146 if (ntohs(uh->uh_dport) == BOOTP_SERVER) { 147 bootp_input(pData, m); 69 register struct ip *ip; 70 register struct udphdr *uh; 71 int len; 72 struct ip save_ip; 73 struct socket *so; 74 75 DEBUG_CALL("udp_input"); 76 DEBUG_ARG("m = %lx", (long)m); 77 DEBUG_ARG("iphlen = %d", iphlen); 78 79 udpstat.udps_ipackets++; 80 81 /* 82 * Strip IP options, if any; should skip this, 83 * make available to user, and use on returned packets, 84 * but we don't yet have a way to check the checksum 85 * with options still present. 86 */ 87 if (iphlen > sizeof(struct ip)) 88 { 89 ip_stripoptions(m, (struct mbuf *)0); 90 iphlen = sizeof(struct ip); 91 } 92 93 /* 94 * Get IP and UDP header together in first mbuf. 95 */ 96 ip = mtod(m, struct ip *); 97 uh = (struct udphdr *)((caddr_t)ip + iphlen); 98 99 /* 100 * Make mbuf data length reflect UDP length. 101 * If not enough data to reflect UDP length, drop. 102 */ 103 len = ntohs((u_int16_t)uh->uh_ulen); 104 105 if (ip->ip_len != len) 106 { 107 if (len > ip->ip_len) 108 { 109 udpstat.udps_badlen++; 148 110 goto bad; 149 111 } 150 112 m_adj(m, len - ip->ip_len); 113 ip->ip_len = len; 114 } 115 116 /* 117 * Save a copy of the IP header in case we want restore it 118 * for sending an ICMP error message in response. 119 */ 120 save_ip = *ip; 121 save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ 122 123 /* 124 * Checksum extended UDP header and data. 125 */ 126 if (udpcksum && uh->uh_sum) 127 { 128 #if !defined(VBOX_WITH_BSD_REASS) 129 ((struct ipovly *)ip)->ih_next = 0; 130 ((struct ipovly *)ip)->ih_prev = 0; 131 ((struct ipovly *)ip)->ih_x1 = 0; 132 #else 133 memset(((struct ipovly *)ip)->ih_x1, 0, 9); 134 #endif 135 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 136 #if 0 137 /* keep uh_sum for ICMP reply */ 138 uh->uh_sum = cksum(m, len + sizeof (struct ip)); 139 if (uh->uh_sum) 140 { 141 142 #endif 143 if(cksum(m, len + sizeof(struct ip))) 144 { 145 udpstat.udps_badsum++; 146 goto bad; 147 } 148 } 149 #if 0 150 } 151 #endif 152 153 /* 154 * handle DHCP/BOOTP 155 */ 156 if (ntohs(uh->uh_dport) == BOOTP_SERVER) 157 { 158 bootp_input(pData, m); 159 goto bad; 160 } 161 162 /* 163 * handle TFTP 164 */ 165 if (ntohs(uh->uh_dport) == TFTP_SERVER) 166 { 167 tftp_input(pData, m); 168 goto bad; 169 } 170 171 /* 172 * Locate pcb for datagram. 173 */ 174 so = udp_last_so; 175 if ( so->so_lport != uh->uh_sport 176 || so->so_laddr.s_addr != ip->ip_src.s_addr) 177 { 178 struct socket *tmp; 179 180 for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) 181 { 182 if ( tmp->so_lport == uh->uh_sport 183 && tmp->so_laddr.s_addr == ip->ip_src.s_addr) 184 { 185 so = tmp; 186 break; 187 } 188 } 189 if (tmp == &udb) 190 so = NULL; 191 else 192 { 193 udpstat.udpps_pcbcachemiss++; 194 udp_last_so = so; 195 } 196 } 197 198 if (so == NULL) 199 { 151 200 /* 152 * handle TFTP 201 * If there's no socket for this packet, 202 * create one 153 203 */ 154 if (ntohs(uh->uh_dport) == TFTP_SERVER) { 155 tftp_input(pData, m); 204 if ((so = socreate()) == NULL) 156 205 goto bad; 157 } 158 159 /* 160 * Locate pcb for datagram. 161 */ 162 so = udp_last_so; 163 if (so->so_lport != uh->uh_sport || 164 so->so_laddr.s_addr != ip->ip_src.s_addr) { 165 struct socket *tmp; 166 167 for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { 168 if (tmp->so_lport == uh->uh_sport && 169 tmp->so_laddr.s_addr == ip->ip_src.s_addr) { 170 so = tmp; 171 break; 172 } 173 } 174 if (tmp == &udb) { 175 so = NULL; 176 } else { 177 udpstat.udpps_pcbcachemiss++; 178 udp_last_so = so; 179 } 180 } 181 182 if (so == NULL) { 183 /* 184 * If there's no socket for this packet, 185 * create one 186 */ 187 if ((so = socreate()) == NULL) goto bad; 188 if(udp_attach(pData, so) == -1) { 206 if (udp_attach(pData, so) == -1) 207 { 189 208 DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", 190 209 errno,strerror(errno))); 191 210 sofree(pData, so); 192 211 goto bad; 193 194 195 196 197 198 199 200 201 202 212 } 213 214 /* 215 * Setup fields 216 */ 217 /* udp_last_so = so; */ 218 so->so_laddr = ip->ip_src; 219 so->so_lport = uh->uh_sport; 220 221 if ((so->so_iptos = udp_tos(so)) == 0) 203 222 so->so_iptos = ip->ip_tos; 204 223 205 /*206 * XXXXX Here, check if it's in udpexec_list,207 * and if it is, do the fork_exec() etc.208 */209 }210 211 so->so_faddr = ip->ip_dst; /* XXX */212 so->so_fport = uh->uh_dport; /* XXX */213 214 iphlen += sizeof(struct udphdr);215 m->m_len -= iphlen;216 m->m_data += iphlen;217 218 224 /* 219 * Now we sendto() the packet. 225 * XXXXX Here, check if it's in udpexec_list, 226 * and if it is, do the fork_exec() etc. 220 227 */ 221 if (so->so_emu) 222 udp_emu(pData, so, m); 223 224 if(sosendto(pData, so,m) == -1) { 225 m->m_len += iphlen; 226 m->m_data -= iphlen; 227 *ip=save_ip; 228 DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno))); 229 icmp_error(pData, m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); 230 } 231 232 m_free(pData, so->so_m); /* used for ICMP if error on sorecvfrom */ 233 234 /* restore the orig mbuf packet */ 228 } 229 230 so->so_faddr = ip->ip_dst; /* XXX */ 231 so->so_fport = uh->uh_dport; /* XXX */ 232 233 iphlen += sizeof(struct udphdr); 234 m->m_len -= iphlen; 235 m->m_data += iphlen; 236 237 /* 238 * Now we sendto() the packet. 239 */ 240 if (so->so_emu) 241 udp_emu(pData, so, m); 242 243 if(sosendto(pData, so,m) == -1) 244 { 235 245 m->m_len += iphlen; 236 246 m->m_data -= iphlen; 237 *ip=save_ip; 238 so->so_m=m; /* ICMP backup */ 239 240 return; 247 *ip = save_ip; 248 DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno))); 249 icmp_error(pData, m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); 250 } 251 252 m_free(pData, so->so_m); /* used for ICMP if error on sorecvfrom */ 253 254 /* restore the orig mbuf packet */ 255 m->m_len += iphlen; 256 m->m_data -= iphlen; 257 *ip = save_ip; 258 so->so_m = m; /* ICMP backup */ 259 260 return; 261 241 262 bad: 242 m_freem(pData, m); 243 /* if (opts) m_freem(opts); */ 244 return; 263 m_freem(pData, m); 264 return; 245 265 } 246 266 … … 249 269 int iptos) 250 270 { 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 register struct udpiphdr *ui; 272 int error = 0; 273 274 DEBUG_CALL("udp_output"); 275 DEBUG_ARG("so = %lx", (long)so); 276 DEBUG_ARG("m = %lx", (long)m); 277 DEBUG_ARG("saddr = %lx", (long)saddr->sin_addr.s_addr); 278 DEBUG_ARG("daddr = %lx", (long)daddr->sin_addr.s_addr); 279 280 /* 281 * Adjust for header 282 */ 283 m->m_data -= sizeof(struct udpiphdr); 284 m->m_len += sizeof(struct udpiphdr); 285 286 /* 287 * Fill in mbuf with extended UDP header 288 * and addresses and length put into network format. 289 */ 290 ui = mtod(m, struct udpiphdr *); 271 291 #if !defined(VBOX_WITH_BSD_REASS) 272 273 292 ui->ui_next = ui->ui_prev = 0; 293 ui->ui_x1 = 0; 274 294 #else 275 276 #endif 277 278 279 280 281 282 283 284 285 286 287 288 289 290 if (udpcksum) {291 if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0)292 ui->ui_sum = 0xffff;293 }294 ((struct ip *)ui)->ip_len = m->m_len;295 296 297 298 299 300 301 302 303 return (error);295 memset(ui->ui_x1, 0, 9); 296 #endif 297 ui->ui_pr = IPPROTO_UDP; 298 ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ 299 /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ 300 ui->ui_src = saddr->sin_addr; 301 ui->ui_dst = daddr->sin_addr; 302 ui->ui_sport = saddr->sin_port; 303 ui->ui_dport = daddr->sin_port; 304 ui->ui_ulen = ui->ui_len; 305 306 /* 307 * Stuff checksum and output datagram. 308 */ 309 ui->ui_sum = 0; 310 if (udpcksum) 311 { 312 if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) 313 ui->ui_sum = 0xffff; 314 } 315 ((struct ip *)ui)->ip_len = m->m_len; 316 ((struct ip *)ui)->ip_ttl = ip_defttl; 317 ((struct ip *)ui)->ip_tos = iptos; 318 319 udpstat.udps_opackets++; 320 321 error = ip_output(pData, so, m); 322 323 return error; 304 324 } 305 325 … … 310 330 311 331 saddr = *addr; 312 if ((so->so_faddr.s_addr & htonl(pData->netmask)) == special_addr.s_addr) { 332 if ((so->so_faddr.s_addr & htonl(pData->netmask)) == special_addr.s_addr) 333 { 313 334 saddr.sin_addr.s_addr = so->so_faddr.s_addr; 314 335 if ((so->so_faddr.s_addr & htonl(~pData->netmask)) == htonl(~pData->netmask)) 315 336 saddr.sin_addr.s_addr = alias_addr.s_addr; 316 337 } 338 317 339 /* Any UDP packet to the loopback address must be translated to be from 318 340 * the forwarding address, i.e. 10.0.2.2. */ … … 330 352 udp_attach(PNATState pData, struct socket *so) 331 353 { 332 struct sockaddr_in addr; 333 334 if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) { 335 /* 336 * Here, we bind() the socket. Although not really needed 337 * (sendto() on an unbound socket will bind it), it's done 338 * here so that emulation of ytalk etc. don't have to do it 339 */ 340 addr.sin_family = AF_INET; 341 addr.sin_port = 0; 342 addr.sin_addr.s_addr = INADDR_ANY; 343 if(bind(so->s, (struct sockaddr *)&addr, sizeof(addr))<0) { 344 int lasterrno=errno; 345 closesocket(so->s); 346 so->s=-1; 354 struct sockaddr_in addr; 355 356 if ((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) 357 { 358 /* 359 * Here, we bind() the socket. Although not really needed 360 * (sendto() on an unbound socket will bind it), it's done 361 * here so that emulation of ytalk etc. don't have to do it 362 */ 363 addr.sin_family = AF_INET; 364 addr.sin_port = 0; 365 addr.sin_addr.s_addr = INADDR_ANY; 366 if (bind(so->s, (struct sockaddr *)&addr, sizeof(addr)) < 0) 367 { 368 int lasterrno = errno; 369 closesocket(so->s); 370 so->s = -1; 347 371 #ifdef RT_OS_WINDOWS 348 WSASetLastError(lasterrno);372 WSASetLastError(lasterrno); 349 373 #else 350 errno=lasterrno; 351 #endif 352 } else { 353 int opt = 1; 354 /* success, insert in queue */ 355 so->so_expire = curtime + SO_EXPIRE; 356 /* enable broadcast for later use */ 357 setsockopt(so->s, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)); 358 insque(pData, so,&udb); 374 errno = lasterrno; 375 #endif 376 } 377 else 378 { 379 int opt = 1; 380 /* success, insert in queue */ 381 so->so_expire = curtime + SO_EXPIRE; 382 /* enable broadcast for later use */ 383 setsockopt(so->s, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)); 384 insque(pData, so,&udb); 359 385 #ifdef VBOX_WITH_SLIRP_ICMP 360 so->so_hlport = addr.sin_port;361 so->so_hladdr.s_addr = addr.sin_addr.s_addr;362 #endif 363 }364 }365 return(so->s);386 so->so_hlport = addr.sin_port; 387 so->so_hladdr.s_addr = addr.sin_addr.s_addr; 388 #endif 389 } 390 } 391 return so->s; 366 392 } 367 393 … … 369 395 udp_detach(PNATState pData, struct socket *so) 370 396 { 371 /* Correctly update list if detaching last socket in list. */372 if (so == udp_last_so) udp_last_so = &udb;373 397 #ifndef VBOX_WITH_SLIRP_ICMP 398 closesocket(so->s); 399 sofree(pData, so); 400 #else /*! VBOX_WITH_SLIRP_ICMP */ 401 if (so != &pData->icmp_socket) 402 { 374 403 closesocket(so->s); 375 /* if (so->so_m) m_free(so->so_m); done by sofree */376 377 404 sofree(pData, so); 378 #else /*! VBOX_WITH_SLIRP_ICMP */ 379 if (so != &pData->icmp_socket) { 380 closesocket(so->s); 381 sofree(pData, so); 405 } 406 #endif /* VBOX_WITH_SLIRP_ICMP */ 407 } 408 409 static const struct tos_t udptos[] = 410 { 411 { 0, 53, IPTOS_LOWDELAY, 0 }, /* DNS */ 412 { 517, 517, IPTOS_LOWDELAY, EMU_TALK }, /* talk */ 413 { 518, 518, IPTOS_LOWDELAY, EMU_NTALK }, /* ntalk */ 414 { 0, 7648, IPTOS_LOWDELAY, EMU_CUSEEME }, /* Cu-Seeme */ 415 { 0, 0, 0, 0 } 416 }; 417 418 u_int8_t 419 udp_tos(struct socket *so) 420 { 421 int i = 0; 422 423 while(udptos[i].tos) 424 { 425 if ( (udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) 426 || (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) 427 { 428 so->so_emu = udptos[i].emu; 429 return udptos[i].tos; 382 430 } 383 #endif /* VBOX_WITH_SLIRP_ICMP */ 384 } 385 386 static const struct tos_t udptos[] = { 387 {0, 53, IPTOS_LOWDELAY, 0}, /* DNS */ 388 {517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */ 389 {518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */ 390 {0, 7648, IPTOS_LOWDELAY, EMU_CUSEEME}, /* Cu-Seeme */ 391 {0, 0, 0, 0} 392 }; 393 394 u_int8_t 395 udp_tos(so) 396 struct socket *so; 397 { 398 int i = 0; 399 400 while(udptos[i].tos) { 401 if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) || 402 (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) { 403 so->so_emu = udptos[i].emu; 404 return udptos[i].tos; 405 } 406 i++; 407 } 408 409 return 0; 431 i++; 432 } 433 434 return 0; 410 435 } 411 436 … … 420 445 udp_emu(PNATState pData, struct socket *so, struct mbuf *m) 421 446 { 422 423 447 struct sockaddr_in addr; 448 socklen_t addrlen = sizeof(addr); 424 449 #ifdef EMULATE_TALK 425 CTL_MSG_OLD *omsg; 426 CTL_MSG *nmsg; 427 char buff[sizeof(CTL_MSG)]; 428 u_char type; 429 430 struct talk_request { 450 CTL_MSG_OLD *omsg; 451 CTL_MSG *nmsg; 452 char buff[sizeof(CTL_MSG)]; 453 u_char type; 454 455 struct talk_request 456 { 431 457 struct talk_request *next; 432 458 struct socket *udp_so; 433 459 struct socket *tcp_so; 434 } *req; 435 436 static struct talk_request *req_tbl = 0; 437 438 #endif 439 440 struct cu_header { 441 uint16_t d_family; /* destination family */ 442 uint16_t d_port; /* destination port */ 443 uint32_t d_addr; /* destination address */ 444 uint16_t s_family; /* source family */ 445 uint16_t s_port; /* source port */ 446 uint32_t so_addr; /* source address */ 447 uint32_t seqn; /* sequence number */ 448 uint16_t message; /* message */ 449 uint16_t data_type; /* data type */ 450 uint16_t pkt_len; /* packet length */ 451 } *cu_head; 452 453 switch(so->so_emu) { 454 460 } *req; 461 462 static struct talk_request *req_tbl = 0; 463 464 #endif 465 466 struct cu_header 467 { 468 uint16_t d_family; /* destination family */ 469 uint16_t d_port; /* destination port */ 470 uint32_t d_addr; /* destination address */ 471 uint16_t s_family; /* source family */ 472 uint16_t s_port; /* source port */ 473 uint32_t so_addr; /* source address */ 474 uint32_t seqn; /* sequence number */ 475 uint16_t message; /* message */ 476 uint16_t data_type; /* data type */ 477 uint16_t pkt_len; /* packet length */ 478 } *cu_head; 479 480 switch(so->so_emu) 481 { 455 482 #ifdef EMULATE_TALK 456 457 458 459 460 461 462 463 464 465 483 case EMU_TALK: 484 case EMU_NTALK: 485 /* 486 * Talk emulation. We always change the ctl_addr to get 487 * some answers from the daemon. When an ANNOUNCE comes, 488 * we send LEAVE_INVITE to the local daemons. Also when a 489 * DELETE comes, we send copies to the local daemons. 490 */ 491 if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) 492 return; 466 493 467 494 #define IS_OLD (so->so_emu == EMU_TALK) 468 495 469 #define COPY_MSG(dest, src) { dest->type = src->type; \ 470 dest->id_num = src->id_num; \ 471 dest->pid = src->pid; \ 472 dest->addr = src->addr; \ 473 dest->ctl_addr = src->ctl_addr; \ 474 memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \ 475 memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \ 476 memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); } 496 #define COPY_MSG(dest, src) \ 497 do { \ 498 dest->type = src->type; \ 499 dest->id_num = src->id_num; \ 500 dest->pid = src->pid; \ 501 dest->addr = src->addr; \ 502 dest->ctl_addr = src->ctl_addr; \ 503 memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \ 504 memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \ 505 memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); 506 } while (0) 477 507 478 508 #define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field) … … 480 510 481 511 482 if (IS_OLD) { /* old talk */ 483 omsg = mtod(m, CTL_MSG_OLD*); 484 nmsg = (CTL_MSG *) buff; 485 type = omsg->type; 486 OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; 487 OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; 488 strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD); 489 } else { /* new talk */ 490 omsg = (CTL_MSG_OLD *) buff; 491 nmsg = mtod(m, CTL_MSG *); 492 type = nmsg->type; 493 OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port; 494 OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; 495 strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD); 512 if (IS_OLD) 513 { 514 /* old talk */ 515 omsg = mtod(m, CTL_MSG_OLD*); 516 nmsg = (CTL_MSG *) buff; 517 type = omsg->type; 518 OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; 519 OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; 520 strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD); 521 } 522 else 523 { 524 /* new talk */ 525 omsg = (CTL_MSG_OLD *) buff; 526 nmsg = mtod(m, CTL_MSG *); 527 type = nmsg->type; 528 OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port; 529 OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; 530 strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD); 531 } 532 533 if (type == LOOK_UP) 534 return; /* for LOOK_UP this is enough */ 535 536 if (IS_OLD) 537 { 538 /* make a copy of the message */ 539 COPY_MSG(nmsg, omsg); 540 nmsg->vers = 1; 541 nmsg->answer = 0; 542 } 543 else 544 COPY_MSG(omsg, nmsg); 545 546 /* 547 * If if is an ANNOUNCE message, we go through the 548 * request table to see if a tcp port has already 549 * been redirected for this socket. If not, we solisten() 550 * a new socket and add this entry to the table. 551 * The port number of the tcp socket and our IP 552 * are put to the addr field of the message structures. 553 * Then a LEAVE_INVITE is sent to both local daemon 554 * ports, 517 and 518. This is why we have two copies 555 * of the message, one in old talk and one in new talk 556 * format. 557 */ 558 559 if (type == ANNOUNCE) 560 { 561 int s; 562 u_short temp_port; 563 564 for(req = req_tbl; req; req = req->next) 565 if (so == req->udp_so) 566 break; /* found it */ 567 568 if (!req) 569 { 570 /* no entry for so, create new */ 571 req = (struct talk_request *)malloc(sizeof(struct talk_request)); 572 req->udp_so = so; 573 req->tcp_so = solisten(0, 574 OTOSIN(omsg, addr)->sin_addr.s_addr, 575 OTOSIN(omsg, addr)->sin_port, 576 SS_FACCEPTONCE); 577 req->next = req_tbl; 578 req_tbl = req; 496 579 } 497 580 498 if (type == LOOK_UP) 499 return; /* for LOOK_UP this is enough */ 500 501 if (IS_OLD) { /* make a copy of the message */ 502 COPY_MSG(nmsg, omsg); 503 nmsg->vers = 1; 504 nmsg->answer = 0; 505 } else 506 COPY_MSG(omsg, nmsg); 507 508 /* 509 * If if is an ANNOUNCE message, we go through the 510 * request table to see if a tcp port has already 511 * been redirected for this socket. If not, we solisten() 512 * a new socket and add this entry to the table. 513 * The port number of the tcp socket and our IP 514 * are put to the addr field of the message structures. 515 * Then a LEAVE_INVITE is sent to both local daemon 516 * ports, 517 and 518. This is why we have two copies 517 * of the message, one in old talk and one in new talk 518 * format. 519 */ 520 521 if (type == ANNOUNCE) { 522 int s; 523 u_short temp_port; 524 525 for(req = req_tbl; req; req = req->next) 526 if (so == req->udp_so) 527 break; /* found it */ 528 529 if (!req) { /* no entry for so, create new */ 530 req = (struct talk_request *) 531 malloc(sizeof(struct talk_request)); 532 req->udp_so = so; 533 req->tcp_so = solisten(0, 534 OTOSIN(omsg, addr)->sin_addr.s_addr, 535 OTOSIN(omsg, addr)->sin_port, 536 SS_FACCEPTONCE); 537 req->next = req_tbl; 538 req_tbl = req; 581 /* replace port number in addr field */ 582 addrlen = sizeof(addr); 583 getsockname(req->tcp_so->s, (struct sockaddr *) &addr, &addrlen); 584 OTOSIN(omsg, addr)->sin_port = addr.sin_port; 585 OTOSIN(omsg, addr)->sin_addr = our_addr; 586 OTOSIN(nmsg, addr)->sin_port = addr.sin_port; 587 OTOSIN(nmsg, addr)->sin_addr = our_addr; 588 589 /* send LEAVE_INVITEs */ 590 temp_port = OTOSIN(omsg, ctl_addr)->sin_port; 591 OTOSIN(omsg, ctl_addr)->sin_port = 0; 592 OTOSIN(nmsg, ctl_addr)->sin_port = 0; 593 omsg->type = nmsg->type = LEAVE_INVITE; 594 595 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 596 addr.sin_addr = our_addr; 597 addr.sin_family = AF_INET; 598 addr.sin_port = htons(517); 599 sendto(s, (char *)omsg, sizeof(*omsg), 0, 600 (struct sockaddr *)&addr, sizeof(addr)); 601 addr.sin_port = htons(518); 602 sendto(s, (char *)nmsg, sizeof(*nmsg), 0, 603 (struct sockaddr *) &addr, sizeof(addr)); 604 closesocket(s) ; 605 606 omsg->type = nmsg->type = ANNOUNCE; 607 OTOSIN(omsg, ctl_addr)->sin_port = temp_port; 608 OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; 609 } 610 611 /* 612 * If it is a DELETE message, we send a copy to the 613 * local daemons. Then we delete the entry corresponding 614 * to our socket from the request table. 615 */ 616 617 if (type == DELETE) 618 { 619 struct talk_request *temp_req, *req_next; 620 int s; 621 u_short temp_port; 622 623 temp_port = OTOSIN(omsg, ctl_addr)->sin_port; 624 OTOSIN(omsg, ctl_addr)->sin_port = 0; 625 OTOSIN(nmsg, ctl_addr)->sin_port = 0; 626 627 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 628 addr.sin_addr = our_addr; 629 addr.sin_family = AF_INET; 630 addr.sin_port = htons(517); 631 sendto(s, (char *)omsg, sizeof(*omsg), 0, 632 (struct sockaddr *)&addr, sizeof(addr)); 633 addr.sin_port = htons(518); 634 sendto(s, (char *)nmsg, sizeof(*nmsg), 0, 635 (struct sockaddr *)&addr, sizeof(addr)); 636 closesocket(s); 637 638 OTOSIN(omsg, ctl_addr)->sin_port = temp_port; 639 OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; 640 641 /* delete table entry */ 642 if (so == req_tbl->udp_so) 643 { 644 temp_req = req_tbl; 645 req_tbl = req_tbl->next; 646 free(temp_req); 647 } 648 else 649 { 650 temp_req = req_tbl; 651 for (req = req_tbl->next; req; req = req_next) 652 { 653 req_next = req->next; 654 if (so == req->udp_so) 655 { 656 temp_req->next = req_next; 657 free(req); 658 break; 539 659 } 540 541 /* replace port number in addr field */ 542 addrlen = sizeof(addr); 543 getsockname(req->tcp_so->s, 544 (struct sockaddr *) &addr, 545 &addrlen); 546 OTOSIN(omsg, addr)->sin_port = addr.sin_port; 547 OTOSIN(omsg, addr)->sin_addr = our_addr; 548 OTOSIN(nmsg, addr)->sin_port = addr.sin_port; 549 OTOSIN(nmsg, addr)->sin_addr = our_addr; 550 551 /* send LEAVE_INVITEs */ 552 temp_port = OTOSIN(omsg, ctl_addr)->sin_port; 553 OTOSIN(omsg, ctl_addr)->sin_port = 0; 554 OTOSIN(nmsg, ctl_addr)->sin_port = 0; 555 omsg->type = nmsg->type = LEAVE_INVITE; 556 557 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 558 addr.sin_addr = our_addr; 559 addr.sin_family = AF_INET; 560 addr.sin_port = htons(517); 561 sendto(s, (char *)omsg, sizeof(*omsg), 0, 562 (struct sockaddr *)&addr, sizeof(addr)); 563 addr.sin_port = htons(518); 564 sendto(s, (char *)nmsg, sizeof(*nmsg), 0, 565 (struct sockaddr *) &addr, sizeof(addr)); 566 closesocket(s) ; 567 568 omsg->type = nmsg->type = ANNOUNCE; 569 OTOSIN(omsg, ctl_addr)->sin_port = temp_port; 570 OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; 660 else 661 temp_req = req; 662 } 571 663 } 572 573 /* 574 * If it is a DELETE message, we send a copy to the 575 * local daemons. Then we delete the entry corresponding 576 * to our socket from the request table. 577 */ 578 579 if (type == DELETE) { 580 struct talk_request *temp_req, *req_next; 581 int s; 582 u_short temp_port; 583 584 temp_port = OTOSIN(omsg, ctl_addr)->sin_port; 585 OTOSIN(omsg, ctl_addr)->sin_port = 0; 586 OTOSIN(nmsg, ctl_addr)->sin_port = 0; 587 588 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 589 addr.sin_addr = our_addr; 590 addr.sin_family = AF_INET; 591 addr.sin_port = htons(517); 592 sendto(s, (char *)omsg, sizeof(*omsg), 0, 593 (struct sockaddr *)&addr, sizeof(addr)); 594 addr.sin_port = htons(518); 595 sendto(s, (char *)nmsg, sizeof(*nmsg), 0, 596 (struct sockaddr *)&addr, sizeof(addr)); 597 closesocket(s); 598 599 OTOSIN(omsg, ctl_addr)->sin_port = temp_port; 600 OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; 601 602 /* delete table entry */ 603 if (so == req_tbl->udp_so) { 604 temp_req = req_tbl; 605 req_tbl = req_tbl->next; 606 free(temp_req); 607 } else { 608 temp_req = req_tbl; 609 for(req = req_tbl->next; req; req = req_next) { 610 req_next = req->next; 611 if (so == req->udp_so) { 612 temp_req->next = req_next; 613 free(req); 614 break; 615 } else { 616 temp_req = req; 617 } 618 } 619 } 620 } 621 622 return; 664 } 665 666 return; 623 667 #endif 624 668 625 669 case EMU_CUSEEME: 626 627 /* 628 * Cu-SeeMe emulation. 629 * Hopefully the packet is more that 16 bytes long. We don't 630 * do any other tests, just replace the address and port 631 * fields. 632 */ 633 if (m->m_len >= sizeof (*cu_head)) { 634 if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) 635 return; 636 cu_head = mtod(m, struct cu_header *); 637 cu_head->s_port = addr.sin_port; 638 cu_head->so_addr = our_addr.s_addr; 639 } 640 641 return; 642 } 670 /* 671 * Cu-SeeMe emulation. 672 * Hopefully the packet is more that 16 bytes long. We don't 673 * do any other tests, just replace the address and port 674 * fields. 675 */ 676 if (m->m_len >= sizeof (*cu_head)) 677 { 678 if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) 679 return; 680 cu_head = mtod(m, struct cu_header *); 681 cu_head->s_port = addr.sin_port; 682 cu_head->so_addr = our_addr.s_addr; 683 } 684 return; 685 } 643 686 } 644 687 … … 646 689 udp_listen(PNATState pData, u_int port, u_int32_t laddr, u_int lport, int flags) 647 690 { 648 struct sockaddr_in addr; 649 struct socket *so; 650 socklen_t addrlen = sizeof(struct sockaddr_in); 651 int opt = 1; 652 653 if ((so = socreate()) == NULL) { 654 free(so); 655 return NULL; 656 } 657 so->s = socket(AF_INET,SOCK_DGRAM,0); 658 so->so_expire = curtime + SO_EXPIRE; 659 insque(pData, so,&udb); 660 661 addr.sin_family = AF_INET; 662 addr.sin_addr.s_addr = INADDR_ANY; 663 addr.sin_port = port; 664 665 if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) { 666 udp_detach(pData, so); 667 return NULL; 668 } 669 setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); 670 /* setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */ 671 672 getsockname(so->s,(struct sockaddr *)&addr,&addrlen); 673 so->so_fport = addr.sin_port; 674 /* The original check was completely broken, as the commented out 675 * if statement was always true (INADDR_ANY=0). */ 676 /* if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) */ 677 if (1 == 0) /* always use the else part */ 678 so->so_faddr = alias_addr; 679 else 680 so->so_faddr = addr.sin_addr; 681 682 so->so_lport = lport; 683 so->so_laddr.s_addr = laddr; 684 if (flags != SS_FACCEPTONCE) 685 so->so_expire = 0; 686 687 so->so_state = SS_ISFCONNECTED; 688 689 return so; 690 } 691 struct sockaddr_in addr; 692 struct socket *so; 693 socklen_t addrlen = sizeof(struct sockaddr_in); 694 int opt = 1; 695 696 if ((so = socreate()) == NULL) 697 { 698 free(so); 699 return NULL; 700 } 701 so->s = socket(AF_INET,SOCK_DGRAM,0); 702 so->so_expire = curtime + SO_EXPIRE; 703 insque(pData, so,&udb); 704 705 addr.sin_family = AF_INET; 706 addr.sin_addr.s_addr = INADDR_ANY; 707 addr.sin_port = port; 708 709 if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) 710 { 711 udp_detach(pData, so); 712 return NULL; 713 } 714 setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); 715 /* setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */ 716 717 getsockname(so->s,(struct sockaddr *)&addr,&addrlen); 718 so->so_fport = addr.sin_port; 719 /* The original check was completely broken, as the commented out 720 * if statement was always true (INADDR_ANY=0). */ 721 /* if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) */ 722 if (1 == 0) /* always use the else part */ 723 so->so_faddr = alias_addr; 724 else 725 so->so_faddr = addr.sin_addr; 726 727 so->so_lport = lport; 728 so->so_laddr.s_addr = laddr; 729 if (flags != SS_FACCEPTONCE) 730 so->so_expire = 0; 731 732 so->so_state = SS_ISFCONNECTED; 733 734 return so; 735 }
Note:
See TracChangeset
for help on using the changeset viewer.