Revision 5fafdf24 slirp/udp.c

b/slirp/udp.c
37 37
/*
38 38
 * Changes and additions relating to SLiRP
39 39
 * Copyright (c) 1995 Danny Gasparovski.
40
 * 
41
 * Please read the file COPYRIGHT for the 
40
 *
41
 * Please read the file COPYRIGHT for the
42 42
 * terms and conditions of the copyright.
43 43
 */
44 44

  
......
66 66
{
67 67
	udb.so_next = udb.so_prev = &udb;
68 68
}
69
/* m->m_data  points at ip packet header 
70
 * m->m_len   length ip packet 
69
/* m->m_data  points at ip packet header
70
 * m->m_len   length ip packet
71 71
 * ip->ip_len length data (IPDU)
72 72
 */
73 73
void
......
79 79
	register struct udphdr *uh;
80 80
/*	struct mbuf *opts = 0;*/
81 81
	int len;
82
	struct ip save_ip; 
82
	struct ip save_ip;
83 83
	struct socket *so;
84
	
84

  
85 85
	DEBUG_CALL("udp_input");
86 86
	DEBUG_ARG("m = %lx", (long)m);
87 87
	DEBUG_ARG("iphlen = %d", iphlen);
88
	
88

  
89 89
	udpstat.udps_ipackets++;
90 90

  
91 91
	/*
......
119 119
		m_adj(m, len - ip->ip_len);
120 120
		ip->ip_len = len;
121 121
	}
122
	
122

  
123 123
	/*
124 124
	 * Save a copy of the IP header in case we want restore it
125 125
	 * for sending an ICMP error message in response.
126 126
	 */
127
	save_ip = *ip; 
127
	save_ip = *ip;
128 128
	save_ip.ip_len+= iphlen;         /* tcp_input subtracts this */
129 129

  
130 130
	/*
......
136 136
	  ((struct ipovly *)ip)->ih_x1 = 0;
137 137
	  ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
138 138
	  /* keep uh_sum for ICMP reply
139
	   * uh->uh_sum = cksum(m, len + sizeof (struct ip)); 
140
	   * if (uh->uh_sum) { 
139
	   * uh->uh_sum = cksum(m, len + sizeof (struct ip));
140
	   * if (uh->uh_sum) {
141 141
	   */
142 142
	  if(cksum(m, len + sizeof(struct ip))) {
143 143
	    udpstat.udps_badsum++;
......
168 168
	if (so->so_lport != uh->uh_sport ||
169 169
	    so->so_laddr.s_addr != ip->ip_src.s_addr) {
170 170
		struct socket *tmp;
171
		
171
	
172 172
		for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) {
173 173
			if (tmp->so_lport == uh->uh_sport &&
174 174
			    tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
......
185 185
		  udp_last_so = so;
186 186
		}
187 187
	}
188
	
188

  
189 189
	if (so == NULL) {
190 190
	  /*
191 191
	   * If there's no socket for this packet,
......
193 193
	   */
194 194
	  if ((so = socreate()) == NULL) goto bad;
195 195
	  if(udp_attach(so) == -1) {
196
	    DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", 
196
	    DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
197 197
			errno,strerror(errno)));
198 198
	    sofree(so);
199 199
	    goto bad;
200 200
	  }
201
	  
201
	 
202 202
	  /*
203 203
	   * Setup fields
204 204
	   */
205 205
	  /* udp_last_so = so; */
206 206
	  so->so_laddr = ip->ip_src;
207 207
	  so->so_lport = uh->uh_sport;
208
	  
208
	 
209 209
	  if ((so->so_iptos = udp_tos(so)) == 0)
210 210
	    so->so_iptos = ip->ip_tos;
211
	  
211
	 
212 212
	  /*
213 213
	   * XXXXX Here, check if it's in udpexec_list,
214 214
	   * and if it is, do the fork_exec() etc.
......
233 233
	  m->m_data -= iphlen;
234 234
	  *ip=save_ip;
235 235
	  DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno)));
236
	  icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));  
236
	  icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); 
237 237
	}
238 238

  
239 239
	m_free(so->so_m);   /* used for ICMP if error on sorecvfrom */
......
251 251
	return;
252 252
}
253 253

  
254
int udp_output2(struct socket *so, struct mbuf *m, 
254
int udp_output2(struct socket *so, struct mbuf *m,
255 255
                struct sockaddr_in *saddr, struct sockaddr_in *daddr,
256 256
                int iptos)
257 257
{
......
269 269
	 */
270 270
	m->m_data -= sizeof(struct udpiphdr);
271 271
	m->m_len += sizeof(struct udpiphdr);
272
	
272

  
273 273
	/*
274 274
	 * Fill in mbuf with extended UDP header
275 275
	 * and addresses and length put into network format.
......
298 298

  
299 299
	((struct ip *)ui)->ip_ttl = ip_defttl;
300 300
	((struct ip *)ui)->ip_tos = iptos;
301
	
301

  
302 302
	udpstat.udps_opackets++;
303
	
303

  
304 304
	error = ip_output(so, m);
305
	
305

  
306 306
	return (error);
307 307
}
308 308

  
309
int udp_output(struct socket *so, struct mbuf *m, 
309
int udp_output(struct socket *so, struct mbuf *m,
310 310
               struct sockaddr_in *addr)
311 311

  
312 312
{
......
320 320
    }
321 321
    daddr.sin_addr = so->so_laddr;
322 322
    daddr.sin_port = so->so_lport;
323
    
323
   
324 324
    return udp_output2(so, m, &saddr, &daddr, so->so_iptos);
325 325
}
326 326

  
......
329 329
     struct socket *so;
330 330
{
331 331
  struct sockaddr_in addr;
332
	
332

  
333 333
  if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
334 334
    /*
335 335
     * Here, we bind() the socket.  Although not really needed
......
380 380
	struct socket *so;
381 381
{
382 382
	int i = 0;
383
	
383

  
384 384
	while(udptos[i].tos) {
385 385
		if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) ||
386 386
		    (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) {
......
389 389
		}
390 390
		i++;
391 391
	}
392
	
392

  
393 393
	return 0;
394 394
}
395 395

  
......
412 412
	CTL_MSG *nmsg;
413 413
	char buff[sizeof(CTL_MSG)];
414 414
	u_char type;
415
	
415

  
416 416
struct talk_request {
417 417
	struct talk_request *next;
418 418
	struct socket *udp_so;
419 419
	struct socket *tcp_so;
420 420
} *req;
421
	
422
	static struct talk_request *req_tbl = 0;	
423
	
421

  
422
	static struct talk_request *req_tbl = 0;
423

  
424 424
#endif
425
	
425

  
426 426
struct cu_header {
427 427
	uint16_t	d_family;		// destination family
428 428
	uint16_t	d_port;			// destination port
......
449 449
		 */
450 450
		if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)
451 451
			return;
452
		
452
	
453 453
#define	IS_OLD	(so->so_emu == EMU_TALK)
454 454

  
455 455
#define COPY_MSG(dest, src) { dest->type = src->type; \
......
472 472
			OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port;
473 473
			OTOSIN(omsg, ctl_addr)->sin_addr = our_addr;
474 474
			strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD);
475
		} else {		/* new talk */	
475
		} else {		/* new talk */
476 476
			omsg = (CTL_MSG_OLD *) buff;
477 477
			nmsg = mtod(m, CTL_MSG *);
478 478
			type = nmsg->type;
......
480 480
			OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr;
481 481
			strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD);
482 482
		}
483
		
484
		if (type == LOOK_UP) 
483
	
484
		if (type == LOOK_UP)
485 485
			return;		/* for LOOK_UP this is enough */
486
			
486
		
487 487
		if (IS_OLD) {		/* make a copy of the message */
488 488
			COPY_MSG(nmsg, omsg);
489 489
			nmsg->vers = 1;
......
502 502
		 * ports, 517 and 518. This is why we have two copies
503 503
		 * of the message, one in old talk and one in new talk
504 504
		 * format.
505
		 */ 
505
		 */
506 506

  
507 507
		if (type == ANNOUNCE) {
508 508
			int s;
509 509
			u_short temp_port;
510
			
510
		
511 511
			for(req = req_tbl; req; req = req->next)
512 512
				if (so == req->udp_so)
513 513
					break;  	/* found it */
514
					
514
				
515 515
			if (!req) {	/* no entry for so, create new */
516 516
				req = (struct talk_request *)
517 517
					malloc(sizeof(struct talk_request));
518 518
				req->udp_so = so;
519
				req->tcp_so = solisten(0,		
520
					OTOSIN(omsg, addr)->sin_addr.s_addr,	
519
				req->tcp_so = solisten(0,	
520
					OTOSIN(omsg, addr)->sin_addr.s_addr,
521 521
					OTOSIN(omsg, addr)->sin_port,
522 522
					SS_FACCEPTONCE);
523 523
				req->next = req_tbl;
524 524
				req_tbl = req;
525
			}			
526
			
525
			}		
526
		
527 527
			/* replace port number in addr field */
528 528
			addrlen = sizeof(addr);
529
			getsockname(req->tcp_so->s, 
529
			getsockname(req->tcp_so->s,
530 530
					(struct sockaddr *) &addr,
531
					&addrlen);		
531
					&addrlen);	
532 532
			OTOSIN(omsg, addr)->sin_port = addr.sin_port;
533 533
			OTOSIN(omsg, addr)->sin_addr = our_addr;
534 534
			OTOSIN(nmsg, addr)->sin_port = addr.sin_port;
535
			OTOSIN(nmsg, addr)->sin_addr = our_addr;		
536
			
535
			OTOSIN(nmsg, addr)->sin_addr = our_addr;	
536
		
537 537
			/* send LEAVE_INVITEs */
538 538
			temp_port = OTOSIN(omsg, ctl_addr)->sin_port;
539 539
			OTOSIN(omsg, ctl_addr)->sin_port = 0;
540 540
			OTOSIN(nmsg, ctl_addr)->sin_port = 0;
541
			omsg->type = nmsg->type = LEAVE_INVITE;			
542
			
541
			omsg->type = nmsg->type = LEAVE_INVITE;		
542
		
543 543
			s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
544 544
			addr.sin_addr = our_addr;
545 545
			addr.sin_family = AF_INET;
546 546
			addr.sin_port = htons(517);
547
			sendto(s, (char *)omsg, sizeof(*omsg), 0, 
547
			sendto(s, (char *)omsg, sizeof(*omsg), 0,
548 548
				(struct sockaddr *)&addr, sizeof(addr));
549 549
			addr.sin_port = htons(518);
550 550
			sendto(s, (char *)nmsg, sizeof(*nmsg), 0,
551 551
				(struct sockaddr *) &addr, sizeof(addr));
552 552
			closesocket(s) ;
553 553

  
554
			omsg->type = nmsg->type = ANNOUNCE; 
554
			omsg->type = nmsg->type = ANNOUNCE;
555 555
			OTOSIN(omsg, ctl_addr)->sin_port = temp_port;
556 556
			OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;
557 557
		}
558
		
559
		/*	
558
	
559
		/*
560 560
		 * If it is a DELETE message, we send a copy to the
561 561
		 * local daemons. Then we delete the entry corresponding
562 562
		 * to our socket from the request table.
563 563
		 */
564
		
564
	
565 565
		if (type == DELETE) {
566 566
			struct talk_request *temp_req, *req_next;
567 567
			int s;
568 568
			u_short temp_port;
569
			
569
		
570 570
			temp_port = OTOSIN(omsg, ctl_addr)->sin_port;
571 571
			OTOSIN(omsg, ctl_addr)->sin_port = 0;
572 572
			OTOSIN(nmsg, ctl_addr)->sin_port = 0;
573
			
573
		
574 574
			s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
575 575
			addr.sin_addr = our_addr;
576 576
			addr.sin_family = AF_INET;
......
581 581
			sendto(s, (char *)nmsg, sizeof(*nmsg), 0,
582 582
				(struct sockaddr *)&addr, sizeof(addr));
583 583
			closesocket(s);
584
			
584
		
585 585
			OTOSIN(omsg, ctl_addr)->sin_port = temp_port;
586 586
			OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;
587 587

  
......
604 604
				}
605 605
			}
606 606
		}
607
		
608
		return;		
607
	
608
		return;	
609 609
#endif
610
		
611
	case EMU_CUSEEME:
612 610
	
611
	case EMU_CUSEEME:
612

  
613 613
		/*
614 614
		 * Cu-SeeMe emulation.
615 615
		 * Hopefully the packet is more that 16 bytes long. We don't
616 616
		 * do any other tests, just replace the address and port
617 617
		 * fields.
618
		 */ 
618
		 */
619 619
		if (m->m_len >= sizeof (*cu_head)) {
620 620
			if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)
621 621
				return;
......
623 623
			cu_head->s_port = addr.sin_port;
624 624
			cu_head->so_addr = our_addr.s_addr;
625 625
		}
626
		
626
	
627 627
		return;
628 628
	}
629 629
}
......
638 638
	struct sockaddr_in addr;
639 639
	struct socket *so;
640 640
	int addrlen = sizeof(struct sockaddr_in), opt = 1;
641
	
641

  
642 642
	if ((so = socreate()) == NULL) {
643 643
		free(so);
644 644
		return NULL;
......
657 657
	}
658 658
	setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
659 659
/*	setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */
660
	
660

  
661 661
	getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
662 662
	so->so_fport = addr.sin_port;
663 663
	if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
664 664
	   so->so_faddr = alias_addr;
665 665
	else
666 666
	   so->so_faddr = addr.sin_addr;
667
	
667

  
668 668
	so->so_lport = lport;
669 669
	so->so_laddr.s_addr = laddr;
670 670
	if (flags != SS_FACCEPTONCE)
671 671
	   so->so_expire = 0;
672
	
672

  
673 673
	so->so_state = SS_ISFCONNECTED;
674
	
674

  
675 675
	return so;
676 676
}

Also available in: Unified diff