plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

udp.c (1205B)


      1 #include <u.h>
      2 #define NOPLAN9DEFINES
      3 #include <libc.h>
      4 #include <ip.h>
      5 
      6 #include <sys/socket.h>
      7 #include <netinet/in.h>
      8 
      9 long
     10 udpread(int fd, Udphdr *hdr, void *buf, long n)
     11 {
     12 	struct sockaddr_in sin;
     13 	socklen_t len;
     14 
     15 	len = sizeof sin;
     16 	if(getsockname(fd, (struct sockaddr*)&sin, &len) < 0)
     17 		return -1;
     18 	if(len != sizeof sin){
     19 		werrstr("getsockname acting weird");
     20 		return -1;
     21 	}
     22 	memset(hdr, 0, sizeof *hdr);
     23 	memmove(hdr->laddr, v4prefix, IPaddrlen);
     24 	memmove(hdr->laddr+12, &sin.sin_addr, sizeof(u32int));
     25 	memmove(hdr->lport, &sin.sin_port, sizeof(u16int));
     26 
     27 	len = sizeof sin;
     28 	n = recvfrom(fd, buf, n, 0, (struct sockaddr*)&sin, &len);
     29 	if(n < 0)
     30 		return -1;
     31 	if(len != sizeof sin){
     32 		werrstr("recvfrom acting weird");
     33 		return -1;
     34 	}
     35 	memmove(hdr->raddr, v4prefix, IPaddrlen);
     36 	memmove(hdr->raddr+12, &sin.sin_addr, sizeof(u32int));
     37 	memmove(hdr->rport, &sin.sin_port, sizeof(u16int));
     38 
     39 	return n;
     40 }
     41 
     42 long
     43 udpwrite(int fd, Udphdr *hdr, void *buf, long n)
     44 {
     45 	struct sockaddr_in sin;
     46 
     47 	memset(&sin, 0, sizeof sin);
     48 	sin.sin_family = AF_INET;
     49 	memmove(&sin.sin_addr, hdr->raddr+12, 4);
     50 	memmove(&sin.sin_port, hdr->rport, 2);
     51 	return sendto(fd, buf, n, 0, (struct sockaddr*)&sin, sizeof sin);
     52 }