| #include <u.h> |
| #define NOPLAN9DEFINES |
| #include <libc.h> |
| #include <ip.h> |
| |
| #include <sys/socket.h> |
| #include <netinet/in.h> |
| |
| /* |
| * prefix of all v4 addresses |
| * copied from libip because libc cannot depend on libip |
| */ |
| static uchar v4prefix[IPaddrlen] = { |
| 0, 0, 0, 0, |
| 0, 0, 0, 0, |
| 0, 0, 0xff, 0xff, |
| 0, 0, 0, 0 |
| }; |
| |
| long |
| udpread(int fd, Udphdr *hdr, void *buf, long n) |
| { |
| struct sockaddr_in sin; |
| socklen_t len; |
| |
| len = sizeof sin; |
| n = recvfrom(fd, buf, n, 0, (struct sockaddr*)&sin, &len); |
| if(len != sizeof sin){ |
| werrstr("recvfrom acting weird"); |
| return -1; |
| } |
| if(n < 0) |
| return -1; |
| memset(hdr, 0, sizeof *hdr); |
| memmove(hdr->raddr, v4prefix, IPaddrlen); |
| *(u32int*)(hdr->raddr+12) = *(u32int*)&sin.sin_addr; |
| *(u16int*)hdr->rport = *(u16int*)&sin.sin_port; |
| return n; |
| } |
| |
| long |
| udpwrite(int fd, Udphdr *hdr, void *buf, long n) |
| { |
| struct sockaddr_in sin; |
| |
| memset(&sin, 0, sizeof sin); |
| sin.sin_family = AF_INET; |
| *(u32int*)&sin.sin_addr = *(u32int*)(hdr->raddr+12); |
| *(u16int*)&sin.sin_port = *(u16int*)hdr->rport; |
| return sendto(fd, buf, n, 0, (struct sockaddr*)&sin, sizeof sin); |
| } |
| |