120 likes | 250 Views
Sys_sendto. Sock_sendmsg. __sock_sendmsg. return sock->ops->sendmsg (). Sys_socket. Sock_create. __Sock_create. Net_families[family ]->create( sock , protocol). Sock_register(ops). Net_families[ops->family]=ops. Inet_init(void). Sock_register(& inet_family_ops ).
E N D
Sys_sendto Sock_sendmsg __sock_sendmsg return sock->ops->sendmsg () Sys_socket Sock_create __Sock_create Net_families[family]->create(sock, protocol) Sock_register(ops) Net_families[ops->family]=ops
Inet_init(void) Sock_register(&inet_family_ops) Struct net_proto_family inet_family_ops ={ .family = PF_INET, .create = inet_create, .owner = THIS_MODULE, }; Inet_create() Struct inet_protosw *answer=NULL; …(A strange loop and other fuctions) sock->ops = answer->ops;
static struct inet_protosw={ .type = SOCK_DGRAM, .protocol = IPPROTO_UDP, .prot = &udp_prot, .ops = &inet_dgram_ops, …} struct proto_ops inet_dgram_ops = { … .sendmsg = inet_sendmsg, … } Inet_dgram_ops udp_prot Inet_sendmsg() struct proto udp_prot = { … .sendmsg = udp_sendmsg,… } return sk->sk_prot->sendmsg() To Be Continued… 經過一連串的尋找及推測…
tcp_sendmsg() tcp_push_one() tcp_transmit_skb() const struct inet_connection_sock *icsk = inet_csk(sk); … err = icsk->icsk_af_ops->queue_xmit(skb, 0)
struct inet_connection_sock_af_ops ipv4_specific={ .queue_xmit = ip_queue_xmit, …. } Ip_queue_xmit() return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); *** #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) *** static inline int dst_output(struct sk_buff *skb) {return skb->dst->output(skb);} ???
Ip_queue_xmit() if (ip_route_output_flow(&rt, &fl, sk, 0)){ ... } int ip_route_output_flow() static inline int ip_mkroute_output_def() int __ip_route_output_key() rth->u.dst.output=ip_output; static int ip_route_output_slow() static inline int ip_mkroute_output()
int ip_output() return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, ip_finish_output, !(IPCB(skb)->flags & IPSKB_REROUTED)); static inline int ip_finish_output() static inline int ip_finish_output2() if (hh) { … return hh->hh_output(skb) }
int __init init_module() int dev_queue_xmit() int dev_hard_start_xmit() static inline struct net_device *alloc_ei_netdev() struct net_device *__alloc_ei_netdev() rc = dev->hard_start_xmit(nskb, dev); static void ethdev_setup() static int ei_start_xmit() dev->hard_start_xmit = &ei_start_xmit; ei_block_output(dev, send_length, data, output_page); * #define ei_block_output (ei_local->block_output)*
static int ei_start_xmit() struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); ei_block_output(dev, send_length, data, output_page); * #define ei_block_output (ei_local->block_output)* static int __init ne2_probe1(){ ei_status.block_output = &ne_block_output; } * #define ei_status (*(struct ei_device *)netdev_priv(dev)) *
static int ei_start_xmit() ei_block_output(dev, send_length, data, output_page); … NS8390_trigger_send(dev, send_length, output_page); enable_irq(dev->irq); Finish(?), 等待interrupt Interrupt發生! irqreturn_t ei_interrupt() if (interrupts & ENISR_TX)ei_tx_intr(dev);
static void ei_tx_intr(struct net_device *dev) Case1: if (ei_local->tx1 < 0){ if (ei_local->tx2 > 0) NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6); } Case2: else if (ei_local->tx2 < 0){ if (ei_local->tx1 > 0) NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page); netif_wake_queue(dev);
2. ne2_block_output 1. dev->hard_start_xmit 3. NS8390_tigger_send ei_start_xmit 5. ei_interrupt NIC Kernel 6. ei_tx_intr 7a. NS8390_trigger_send 7b.netif_wake_queue 4. Interrupt occurs