diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-16 21:50:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-16 21:50:49 -0400 |
commit | ccc580571cf0799d0460a085a7632b77753f083e (patch) | |
tree | 018e0f83776b089b1f272694132688ac93be25b4 /include | |
parent | 0f5cabba49021d36e9f76bd97d7fa0f4a408063f (diff) |
wext: Emit event stream entries correctly when compat.
Three major portions to this change:
1) Add IW_EV_COMPAT_LCP_LEN, IW_EV_COMPAT_POINT_OFF,
and IW_EV_COMPAT_POINT_LEN helper defines.
2) Delete iw_stream_check_add_*(), they are unused.
3) Add iw_request_info argument to iwe_stream_add_*(), and use it to
size the event and pointer lengths correctly depending upon whether
IW_REQUEST_FLAG_COMPAT is set or not.
4) The mechanical transformations to the drivers and wireless stack
bits to get the iw_request_info passed down into the routines
modified in #3. Also, explicit references to IW_EV_LCP_LEN are
replaced with iwe_stream_lcp_len(info).
With a lot of help and bug fixes from Masakazu Mokuno.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/wireless.h | 15 | ||||
-rw-r--r-- | include/net/iw_handler.h | 149 |
2 files changed, 63 insertions, 101 deletions
diff --git a/include/linux/wireless.h b/include/linux/wireless.h index 79d846875825..d7958f9b52cb 100644 --- a/include/linux/wireless.h +++ b/include/linux/wireless.h | |||
@@ -1113,6 +1113,21 @@ struct iw_event | |||
1113 | #define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ | 1113 | #define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ |
1114 | IW_EV_POINT_OFF) | 1114 | IW_EV_POINT_OFF) |
1115 | 1115 | ||
1116 | #ifdef __KERNEL__ | ||
1117 | #ifdef CONFIG_COMPAT | ||
1118 | struct __compat_iw_event { | ||
1119 | __u16 len; /* Real length of this stuff */ | ||
1120 | __u16 cmd; /* Wireless IOCTL */ | ||
1121 | compat_caddr_t pointer; | ||
1122 | }; | ||
1123 | #define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer) | ||
1124 | #define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length) | ||
1125 | #define IW_EV_COMPAT_POINT_LEN \ | ||
1126 | (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \ | ||
1127 | IW_EV_COMPAT_POINT_OFF) | ||
1128 | #endif | ||
1129 | #endif | ||
1130 | |||
1116 | /* Size of the Event prefix when packed in stream */ | 1131 | /* Size of the Event prefix when packed in stream */ |
1117 | #define IW_EV_LCP_PK_LEN (4) | 1132 | #define IW_EV_LCP_PK_LEN (4) |
1118 | /* Size of the various events when packed in stream */ | 1133 | /* Size of the various events when packed in stream */ |
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index c99a8eec84e7..51b9a37de991 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h | |||
@@ -478,105 +478,58 @@ extern void wireless_spy_update(struct net_device * dev, | |||
478 | * Function that are so simple that it's more efficient inlining them | 478 | * Function that are so simple that it's more efficient inlining them |
479 | */ | 479 | */ |
480 | 480 | ||
481 | /*------------------------------------------------------------------*/ | 481 | static inline int iwe_stream_lcp_len(struct iw_request_info *info) |
482 | /* | ||
483 | * Wrapper to add an Wireless Event to a stream of events. | ||
484 | */ | ||
485 | static inline char * | ||
486 | iwe_stream_add_event(char * stream, /* Stream of events */ | ||
487 | char * ends, /* End of stream */ | ||
488 | struct iw_event *iwe, /* Payload */ | ||
489 | int event_len) /* Real size of payload */ | ||
490 | { | 482 | { |
491 | /* Check if it's possible */ | 483 | #ifdef CONFIG_COMPAT |
492 | if(likely((stream + event_len) < ends)) { | 484 | if (info->flags & IW_REQUEST_FLAG_COMPAT) |
493 | iwe->len = event_len; | 485 | return IW_EV_COMPAT_LCP_LEN; |
494 | /* Beware of alignement issues on 64 bits */ | 486 | #endif |
495 | memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); | 487 | return IW_EV_LCP_LEN; |
496 | memcpy(stream + IW_EV_LCP_LEN, | ||
497 | ((char *) iwe) + IW_EV_LCP_LEN, | ||
498 | event_len - IW_EV_LCP_LEN); | ||
499 | stream += event_len; | ||
500 | } | ||
501 | return stream; | ||
502 | } | 488 | } |
503 | 489 | ||
504 | /*------------------------------------------------------------------*/ | 490 | static inline int iwe_stream_point_len(struct iw_request_info *info) |
505 | /* | ||
506 | * Wrapper to add an short Wireless Event containing a pointer to a | ||
507 | * stream of events. | ||
508 | */ | ||
509 | static inline char * | ||
510 | iwe_stream_add_point(char * stream, /* Stream of events */ | ||
511 | char * ends, /* End of stream */ | ||
512 | struct iw_event *iwe, /* Payload length + flags */ | ||
513 | char * extra) /* More payload */ | ||
514 | { | 491 | { |
515 | int event_len = IW_EV_POINT_LEN + iwe->u.data.length; | 492 | #ifdef CONFIG_COMPAT |
516 | /* Check if it's possible */ | 493 | if (info->flags & IW_REQUEST_FLAG_COMPAT) |
517 | if(likely((stream + event_len) < ends)) { | 494 | return IW_EV_COMPAT_POINT_LEN; |
518 | iwe->len = event_len; | 495 | #endif |
519 | memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); | 496 | return IW_EV_POINT_LEN; |
520 | memcpy(stream + IW_EV_LCP_LEN, | ||
521 | ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF, | ||
522 | IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN); | ||
523 | memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); | ||
524 | stream += event_len; | ||
525 | } | ||
526 | return stream; | ||
527 | } | 497 | } |
528 | 498 | ||
529 | /*------------------------------------------------------------------*/ | 499 | static inline int iwe_stream_event_len_adjust(struct iw_request_info *info, |
530 | /* | 500 | int event_len) |
531 | * Wrapper to add a value to a Wireless Event in a stream of events. | ||
532 | * Be careful, this one is tricky to use properly : | ||
533 | * At the first run, you need to have (value = event + IW_EV_LCP_LEN). | ||
534 | */ | ||
535 | static inline char * | ||
536 | iwe_stream_add_value(char * event, /* Event in the stream */ | ||
537 | char * value, /* Value in event */ | ||
538 | char * ends, /* End of stream */ | ||
539 | struct iw_event *iwe, /* Payload */ | ||
540 | int event_len) /* Real size of payload */ | ||
541 | { | 501 | { |
542 | /* Don't duplicate LCP */ | 502 | #ifdef CONFIG_COMPAT |
543 | event_len -= IW_EV_LCP_LEN; | 503 | if (info->flags & IW_REQUEST_FLAG_COMPAT) { |
544 | 504 | event_len -= IW_EV_LCP_LEN; | |
545 | /* Check if it's possible */ | 505 | event_len += IW_EV_COMPAT_LCP_LEN; |
546 | if(likely((value + event_len) < ends)) { | ||
547 | /* Add new value */ | ||
548 | memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len); | ||
549 | value += event_len; | ||
550 | /* Patch LCP */ | ||
551 | iwe->len = value - event; | ||
552 | memcpy(event, (char *) iwe, IW_EV_LCP_LEN); | ||
553 | } | 506 | } |
554 | return value; | 507 | #endif |
508 | |||
509 | return event_len; | ||
555 | } | 510 | } |
556 | 511 | ||
557 | /*------------------------------------------------------------------*/ | 512 | /*------------------------------------------------------------------*/ |
558 | /* | 513 | /* |
559 | * Wrapper to add an Wireless Event to a stream of events. | 514 | * Wrapper to add an Wireless Event to a stream of events. |
560 | * Same as above, with explicit error check... | ||
561 | */ | 515 | */ |
562 | static inline char * | 516 | static inline char * |
563 | iwe_stream_check_add_event(char * stream, /* Stream of events */ | 517 | iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends, |
564 | char * ends, /* End of stream */ | 518 | struct iw_event *iwe, int event_len) |
565 | struct iw_event *iwe, /* Payload */ | ||
566 | int event_len, /* Size of payload */ | ||
567 | int * perr) /* Error report */ | ||
568 | { | 519 | { |
569 | /* Check if it's possible, set error if not */ | 520 | int lcp_len = iwe_stream_lcp_len(info); |
521 | |||
522 | event_len = iwe_stream_event_len_adjust(info, event_len); | ||
523 | |||
524 | /* Check if it's possible */ | ||
570 | if(likely((stream + event_len) < ends)) { | 525 | if(likely((stream + event_len) < ends)) { |
571 | iwe->len = event_len; | 526 | iwe->len = event_len; |
572 | /* Beware of alignement issues on 64 bits */ | 527 | /* Beware of alignement issues on 64 bits */ |
573 | memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); | 528 | memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); |
574 | memcpy(stream + IW_EV_LCP_LEN, | 529 | memcpy(stream + lcp_len, &iwe->u, |
575 | ((char *) iwe) + IW_EV_LCP_LEN, | 530 | event_len - lcp_len); |
576 | event_len - IW_EV_LCP_LEN); | ||
577 | stream += event_len; | 531 | stream += event_len; |
578 | } else | 532 | } |
579 | *perr = -E2BIG; | ||
580 | return stream; | 533 | return stream; |
581 | } | 534 | } |
582 | 535 | ||
@@ -584,27 +537,25 @@ iwe_stream_check_add_event(char * stream, /* Stream of events */ | |||
584 | /* | 537 | /* |
585 | * Wrapper to add an short Wireless Event containing a pointer to a | 538 | * Wrapper to add an short Wireless Event containing a pointer to a |
586 | * stream of events. | 539 | * stream of events. |
587 | * Same as above, with explicit error check... | ||
588 | */ | 540 | */ |
589 | static inline char * | 541 | static inline char * |
590 | iwe_stream_check_add_point(char * stream, /* Stream of events */ | 542 | iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends, |
591 | char * ends, /* End of stream */ | 543 | struct iw_event *iwe, char *extra) |
592 | struct iw_event *iwe, /* Payload length + flags */ | ||
593 | char * extra, /* More payload */ | ||
594 | int * perr) /* Error report */ | ||
595 | { | 544 | { |
596 | int event_len = IW_EV_POINT_LEN + iwe->u.data.length; | 545 | int event_len = iwe_stream_point_len(info) + iwe->u.data.length; |
546 | int point_len = iwe_stream_point_len(info); | ||
547 | int lcp_len = iwe_stream_lcp_len(info); | ||
548 | |||
597 | /* Check if it's possible */ | 549 | /* Check if it's possible */ |
598 | if(likely((stream + event_len) < ends)) { | 550 | if(likely((stream + event_len) < ends)) { |
599 | iwe->len = event_len; | 551 | iwe->len = event_len; |
600 | memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); | 552 | memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); |
601 | memcpy(stream + IW_EV_LCP_LEN, | 553 | memcpy(stream + lcp_len, |
602 | ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF, | 554 | ((char *) &iwe->u) + IW_EV_POINT_OFF, |
603 | IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN); | 555 | IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN); |
604 | memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); | 556 | memcpy(stream + point_len, extra, iwe->u.data.length); |
605 | stream += event_len; | 557 | stream += event_len; |
606 | } else | 558 | } |
607 | *perr = -E2BIG; | ||
608 | return stream; | 559 | return stream; |
609 | } | 560 | } |
610 | 561 | ||
@@ -613,29 +564,25 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */ | |||
613 | * Wrapper to add a value to a Wireless Event in a stream of events. | 564 | * Wrapper to add a value to a Wireless Event in a stream of events. |
614 | * Be careful, this one is tricky to use properly : | 565 | * Be careful, this one is tricky to use properly : |
615 | * At the first run, you need to have (value = event + IW_EV_LCP_LEN). | 566 | * At the first run, you need to have (value = event + IW_EV_LCP_LEN). |
616 | * Same as above, with explicit error check... | ||
617 | */ | 567 | */ |
618 | static inline char * | 568 | static inline char * |
619 | iwe_stream_check_add_value(char * event, /* Event in the stream */ | 569 | iwe_stream_add_value(struct iw_request_info *info, char *event, char *value, |
620 | char * value, /* Value in event */ | 570 | char *ends, struct iw_event *iwe, int event_len) |
621 | char * ends, /* End of stream */ | ||
622 | struct iw_event *iwe, /* Payload */ | ||
623 | int event_len, /* Size of payload */ | ||
624 | int * perr) /* Error report */ | ||
625 | { | 571 | { |
572 | int lcp_len = iwe_stream_lcp_len(info); | ||
573 | |||
626 | /* Don't duplicate LCP */ | 574 | /* Don't duplicate LCP */ |
627 | event_len -= IW_EV_LCP_LEN; | 575 | event_len -= IW_EV_LCP_LEN; |
628 | 576 | ||
629 | /* Check if it's possible */ | 577 | /* Check if it's possible */ |
630 | if(likely((value + event_len) < ends)) { | 578 | if(likely((value + event_len) < ends)) { |
631 | /* Add new value */ | 579 | /* Add new value */ |
632 | memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len); | 580 | memcpy(value, &iwe->u, event_len); |
633 | value += event_len; | 581 | value += event_len; |
634 | /* Patch LCP */ | 582 | /* Patch LCP */ |
635 | iwe->len = value - event; | 583 | iwe->len = value - event; |
636 | memcpy(event, (char *) iwe, IW_EV_LCP_LEN); | 584 | memcpy(event, (char *) iwe, lcp_len); |
637 | } else | 585 | } |
638 | *perr = -E2BIG; | ||
639 | return value; | 586 | return value; |
640 | } | 587 | } |
641 | 588 | ||