diff options
| author | Miguel <m.i@gmx.at> | 2018-09-26 10:22:37 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-26 10:22:37 +0200 |
| commit | ae33cc6557790a502a01b380b0926944ca2f3cfa (patch) | |
| tree | e72632052d1c6f6830c40d10d26c04b73aac74c6 /net | |
| parent | daf374435560861681c3e4d14a2d44141aa11abc (diff) | |
ntp and udp
Diffstat (limited to 'net')
| -rw-r--r-- | net/eth.c | 24 | ||||
| -rw-r--r-- | net/eth.h | 4 | ||||
| -rw-r--r-- | net/icmp.c | 33 | ||||
| -rw-r--r-- | net/icmp.h | 1 | ||||
| -rw-r--r-- | net/inet.c | 22 | ||||
| -rw-r--r-- | net/inet.h | 5 | ||||
| -rw-r--r-- | net/ipv4.c | 29 | ||||
| -rw-r--r-- | net/ipv4.h | 12 | ||||
| -rw-r--r-- | net/netdev.c | 4 | ||||
| -rw-r--r-- | net/netdev.h | 2 | ||||
| -rw-r--r-- | net/ntp.c | 36 | ||||
| -rw-r--r-- | net/ntp.h | 34 | ||||
| -rw-r--r-- | net/udp.c | 16 | ||||
| -rw-r--r-- | net/udp.h | 11 |
14 files changed, 225 insertions, 8 deletions
@@ -1 +1,25 @@ +#include "inet.h" +#include "eth.h" +#include "netdev.h" +#include "lib/string/string.h" + +uint32_t eth_generic(struct netdev *dev, uint32_t ip, uint16_t type, uint8_t* pos,uint32_t *end) +{ + pos-=14;// we need 14 bytes for the eth header + struct eth_hdr *eth=pos; + + // TODO: dmac from arp and routing tables. + eth->dmac[0]=0x90; + eth->dmac[1]=0x5c; + eth->dmac[2]=0x44; + eth->dmac[3]=0x2f; + eth->dmac[4]=0x9a; + eth->dmac[5]=0x40; + + memcpy(eth->smac,dev->hwaddr,6); + eth->ethertype=htons(type); + + return pos; +} + @@ -13,4 +13,8 @@ struct eth_hdr unsigned char payload[]; // payload } __attribute__((packed)); +struct netdev; + +uint32_t eth_generic(struct netdev *dev, uint32_t ip, uint16_t type, uint8_t* pos,uint32_t *end); + #endif @@ -2,9 +2,42 @@ #include "icmp.h" #include "ipv4.h" #include "log.h" +#include "kmalloc.h" #include "lib/string/string.h" +uint32_t icmp_generic(struct netdev *dev, uint32_t ip, uint8_t type, uint8_t* pos,uint8_t *end) +{ + pos-=4; //we need 32 bytes + struct icmp_v4 *icmp=pos; + + icmp->type=type; + icmp->code=0; + icmp->csum=0; + icmp->csum=checksum(icmp,end-pos); + + return ipv4_generic(dev,ip,IPV4_P_ICMP,pos,end); +} + +uint32_t icmp_ping(struct netdev *dev, uint32_t ip, uint16_t* pos,uint32_t *end) +{ + // payload + for(int i=0;i<64;i++) + { + pos--; + *pos=0xbeef; + } + + // id and sequence number + pos-=2; // we need 32 bytes + struct icmp_v4_echo *ping=pos; + ping->id=htons(0xabcd); // some random number + ping->seq=htons(0); // we just send one single ping with id 1 for now + + return icmp_generic(dev,ip,ICMP_ECHO_REQUEST,pos,end); +} + + bool icmp_reply(struct netdev *dev,struct eth_hdr *hdr) { unsigned char tmp[6]; @@ -25,4 +25,5 @@ struct icmp_v4_dst_unreachable { uint8_t data[]; } __attribute__((packed)); +uint32_t icmp_ping(struct netdev *dev, uint32_t ip, uint16_t* pos,uint32_t *end); bool icmp_incoming(struct netdev *dev,struct eth_hdr *hdr); @@ -1,4 +1,8 @@ #include "inet.h" +#include "icmp.h" +#include "kmalloc.h" +#include "udp.h" +#include "ntp.h" uint16_t ntohs(uint16_t val) { @@ -36,3 +40,21 @@ uint16_t checksum(void *addr, int count) return ~sum; } + +bool net_packet(struct netdev *dev) +{ + uint32_t packet=kballoc(1)+4096; // we start one byte after the end; + // + uint32_t addr=(144)+(76<<8)+(106<<16)+(46<<24); + uint32_t google_time=216+(239<<8)+(35<<16)+(0<<24); + // this should of course be filled dynamically! + //uint32_t pos=icmp_ping(dev,addr,packet,packet); // create ping packet and get new position; + //uint32_t pos=udp_generic(dev, addr, 666, 123, packet,packet); + uint32_t pos=ntp_generic(dev, google_time, 6666, 123, packet,packet); + + // + dev->transmit(pos,(packet-pos)); + + kbfree(packet-4096); // TODO: take care it is not overwritten before transmitted! + return true; +} @@ -3,6 +3,8 @@ * https://en.wikipedia.org/wiki/OSI_model */ #include <stdint.h> +#include <stdbool.h> +#include <netdev.h> #define ARP_ETHERNET 1 #define ARP_IPV4 0x800 @@ -13,6 +15,8 @@ #define ETH_P_IPV4 0x0800 #define IPV4_P_ICMP 0x1 +#define IPV4_P_TCP 0x6 +#define IPV4_P_UDP 0x11 #define ICMP_ECHO_REPLY 0 #define ICMP_UNREACHABLE 3 @@ -21,3 +25,4 @@ uint16_t checksum(void *addr, int count); uint16_t ntohs(uint16_t val); uint16_t htons(uint16_t val); +bool net_packet(struct netdev *dev); @@ -11,6 +11,7 @@ bool ipv4_incoming(struct netdev *dev,struct eth_hdr *hdr) ipv4->csum=0; klog("expected checksum: 0x%04X",checksum(ipv4,ntohs(ipv4->len))); klog("ipv4 header len=%d",ipv4->ihl); + if(ipv4->proto==IPV4_P_ICMP) { icmp_incoming(dev,hdr); @@ -18,3 +19,31 @@ bool ipv4_incoming(struct netdev *dev,struct eth_hdr *hdr) return true; } + +uint32_t ipv4_generic(struct netdev *dev, uint32_t ip, uint8_t type, uint8_t* pos,uint8_t *end) +{ + + pos-=20; // we need 20 bytes for the ipv4 header. + struct ipv4_hdr *ipv4=pos; + ipv4->ihl=5; // 20 bytes + ipv4->version=4; // ipv 4 + + ipv4->tos=0; // type of service? + ipv4->len=htons(end-pos); // total length of ip datagramm in bytes + ipv4->id=0; // index of datagram for fragmentation + + //ipv4->flags=0x2; // various control flags 0x20 do not fragment + //ipv4->frag_offset=0; // fragment offset 0 - first + ipv4->flags_and_offset=0; // TODO! 0x2? + + ipv4->ttl=64; // time to live - countdown decreased by each receiver + ipv4->proto=type; // payload protocol / 1-icmp, 16 - udp , 6 -tcp + ipv4->csum=0; // header checksum + ipv4->saddr=dev->ip; // source ip address + ipv4->daddr=ip; // destination ip address + + //ipv4->csum=checksum(ipv4,ntohs(ipv4->len)); + ipv4->csum=checksum(ipv4,20); + + return eth_generic(dev,ip,ETH_P_IPV4,pos,end); +} @@ -11,8 +11,11 @@ struct ipv4_hdr { uint8_t tos; // type of service uint16_t len; // total length of ip datagramm uint16_t id; // index of datagram for fragmentation - uint16_t flags : 3; // various control flags - uint16_t frag_offset : 13; // fragment offset 0 - first + + //uint16_t flags : 3; // various control flags + //uint16_t frag_offset : 13; // fragment offset 0 - first + uint16_t flags_and_offset; + uint8_t ttl; // time to live - countdown decreased by each receiver uint8_t proto; // payload protocol / 1-icmp, 16 - udp , 6 -tcp uint16_t csum; // header checksum @@ -20,6 +23,5 @@ struct ipv4_hdr { uint32_t daddr; // destination ip address } __attribute__((packed)); -uint16_t ipv4_checksum(void *addr, int count); -bool ipv4_incoming(struct netdev *,struct eth_hdr *); -uint16_t ipv4_checksum(void *addr, int count); +bool ipv4_incoming(struct netdev *,struct eth_hdr *); +uint32_t ipv4_generic(struct netdev *dev, uint32_t ip, uint8_t type, uint8_t* pos,uint8_t *end); diff --git a/net/netdev.c b/net/netdev.c index 1539bd6..69fd45f 100644 --- a/net/netdev.c +++ b/net/netdev.c @@ -1,10 +1,10 @@ #include <stdint.h> -#include "inet.h" #include "eth.h" +#include "inet.h" #include "arp.h" #include "ipv4.h" -#include "netdev.h" #include "lib/string/string.h" +#include "netdev.h" void net_incoming(struct netdev *netdev, struct eth_hdr *hdr) { diff --git a/net/netdev.h b/net/netdev.h index 73f9783..92ff9f2 100644 --- a/net/netdev.h +++ b/net/netdev.h @@ -10,7 +10,7 @@ struct netdev int (*transmit)(const void *data, uint16_t p_len); }; -void netdev_transmit(struct netdev *dev, struct eth_hdr *hdr, uint16_t ethertype, int len, unsigned char *dst); void net_incoming(struct netdev *netdev, struct eth_hdr *hdr); +void netdev_transmit(struct netdev *dev, struct eth_hdr *hdr, uint16_t ethertype, int len, unsigned char *dst); #endif diff --git a/net/ntp.c b/net/ntp.c new file mode 100644 index 0000000..137d677 --- /dev/null +++ b/net/ntp.c @@ -0,0 +1,36 @@ +#include "udp.h" +#include "ntp.h" + +uint32_t ntp_generic(struct netdev *dev, uint32_t ip, uint16_t src, uint16_t dst, uint8_t* pos,uint8_t *end) +{ + pos-=48; // we need 48 bytes + struct udp_v4_ntp *ntp=pos; + + ntp->li_vn_mode=0x1b; // Eight bits. li, vn, and mode. + // li. Two bits. Leap indicator. + // vn. Three bits. Version number of the protocol. + // mode. Three bits. Client will pick mode 3 for client. + + ntp->stratum=0; // Eight bits. Stratum level of the local clock. + ntp->poll=0; // Eight bits. Maximum interval between successive messages. + ntp->precision=0; // Eight bits. Precision of the local clock. + + ntp->rootDelay=0; // 32 bits. Total round trip delay time. + ntp->rootDispersion=0; // 32 bits. Max error aloud from primary clock source. + ntp->refId=0; // 32 bits. Reference clock identifier. + + ntp->refTm_s=0; // 32 bits. Reference time-stamp seconds. + ntp->refTm_f=0; // 32 bits. Reference time-stamp fraction of a second. + + ntp->origTm_s=0; // 32 bits. Originate time-stamp seconds. + ntp->origTm_f=0; // 32 bits. Originate time-stamp fraction of a second. + + ntp->rxTm_s=0; // 32 bits. Received time-stamp seconds. + ntp->rxTm_f=0; // 32 bits. Received time-stamp fraction of a second. + + ntp->txTm_s=0; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds. + ntp->txTm_f=0; // 32 bits. Transmit time-stamp fraction of a second. + + return udp_generic(dev, ip, src, dst, pos,end); +} + diff --git a/net/ntp.h b/net/ntp.h new file mode 100644 index 0000000..0b7fa00 --- /dev/null +++ b/net/ntp.h @@ -0,0 +1,34 @@ +//https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html + +struct udp_v4_ntp +{ + + uint8_t li_vn_mode; // Eight bits. li, vn, and mode. + // li. Two bits. Leap indicator. + // vn. Three bits. Version number of the protocol. + // mode. Three bits. Client will pick mode 3 for client. + + uint8_t stratum; // Eight bits. Stratum level of the local clock. + uint8_t poll; // Eight bits. Maximum interval between successive messages. + uint8_t precision; // Eight bits. Precision of the local clock. + + uint32_t rootDelay; // 32 bits. Total round trip delay time. + uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source. + uint32_t refId; // 32 bits. Reference clock identifier. + + uint32_t refTm_s; // 32 bits. Reference time-stamp seconds. + uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second. + + uint32_t origTm_s; // 32 bits. Originate time-stamp seconds. + uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second. + + uint32_t rxTm_s; // 32 bits. Received time-stamp seconds. + uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second. + + uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds. + uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second. + + // Total: 384 bits or 48 bytes. +} __attribute__((packed)); + +uint32_t ntp_generic(struct netdev *dev, uint32_t ip, uint16_t src, uint16_t dst, uint8_t* pos,uint8_t *end); diff --git a/net/udp.c b/net/udp.c new file mode 100644 index 0000000..6913256 --- /dev/null +++ b/net/udp.c @@ -0,0 +1,16 @@ +#include "udp.h" +#include "inet.h" +#include "ipv4.h" + +uint32_t udp_generic(struct netdev *dev, uint32_t ip, uint16_t src, uint16_t dst, uint8_t* pos,uint8_t *end) +{ + pos-=8; //we need 64 bytes + struct udp_v4 *udp=pos; + + udp->src_port=htons(src); + udp->dst_port=htons(dst); + udp->len=htons(end-pos); + udp->csum=0; // TODO: optional + + return ipv4_generic(dev,ip,IPV4_P_UDP,pos,end); +} diff --git a/net/udp.h b/net/udp.h new file mode 100644 index 0000000..2c30804 --- /dev/null +++ b/net/udp.h @@ -0,0 +1,11 @@ +#include "netdev.h" +#include <stdint.h> + +struct udp_v4{ + uint16_t src_port; + uint16_t dst_port; + uint16_t len; + uint16_t csum; +} __attribute__((packed)); + +uint32_t udp_generic(struct netdev *dev, uint32_t ip, uint16_t src, uint16_t dst, uint8_t* pos,uint8_t *end); |
