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 }